I need to block the user from inputing the . (period) character from the keyboard on a number EditText, but I need to be able to use it on the same EditText via the setText method.
I've tried using InputFilter but when I call setText the . character don't show. I've also tried setting the digits parameter in the xml but the setText doesn't work either.
Is there a way to do this?
Here's my InputFilter code:
public static InputFilter blockPeriod(){
return new InputFilter() {
#Override
public CharSequence filter(CharSequence charSequence, int i, int i1, Spanned spanned, int i2, int i3) {
for (int j = i; j <i1 ; j++) {
char c = charSequence.charAt(j);
if (!allowed(c)){
return "";
}
}
return null;
}
private boolean allowed(char c){
return c != '.';
}
};
}
You can do it with your InputFilter, but you need to allow it for a while when you calling setText() method.
private static class AllowableInputFilter implements InputFilter {
private boolean mAllowDot;
public void setAllowDot(boolean toAllow) {
mAllowDot = toAllow;
}
....
private boolean allowed(char c){
return mAllowDot || c != '.';
}
}
public void forceText(String text) {
mInputFilter.setAllowDot(true);
mEditText.setText(text);
mInputFilter.setAllowDot(false);
}
mInputFilter = new AllowableInputFilter();
mInputFilter.setAllowDot(false);
mEditText.setFilters(new InputFilter[] {mInputFilter});
forceText("Okaaayy....");
try this out :
if (textedit.getText().toString().startsWith(".")){
//Do something about it
}
now entering . you can show a message or something else.also put this code under onTextChanged method(text watcher).
Hope it helps you out.
user digits property inside xml in EditText
android:digits="0123456789"
so now edittext only allow digit from 0 to 9
Related
I´m trying to use setText method to show all the elements from an ArrayList of Objects into a TextView.
I have 6 buttons in 6 different shelves (A,B,C,D,E,F) with a popup menu each one, where the user chose a cardinal point (N,S,E,W) and after that show the shelve letter and the item clicked in a text view. This is the map:
Here is the code I´m using:
Button buttonA, buttonB, buttonC, buttonD, buttonE, buttonF;
private TextView coordenada_view;
ArrayList<PickUpPoint> pickuppoint_array = new ArrayList<PickUpPoint>();
#Override
protected void onCreate{......
buttonA.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final PopupMenu popupMenu = new PopupMenu(Mapa.this, buttonA);
popupMenu.getMenuInflater().inflate(R.menu.popup_menu, popupMenu.getMenu());
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
String mShelving = buttonA.getText().toString();
String mCardinalPoint = item.getTitle().toString();
pickuppoint_array.add(new PickUpPoint(mShelving,mCardinalPoint));
PickUpPoint pickUpPoint = new PickUpPoint(mShelving,mCardinalPoint);
//Here I´m trying to show all the elements of the ArrayList into the TextView
for (int i = 0; i < pickuppoint_array.size(); i++){
coordenada_view.setText( pickuppoint_array.get(i).toString());
}
return true;
}
});
popupMenu.show();
buttonB.setOnClickListener....
buttonC.setOnClickListener....
}
This is the class PickUpPoint:
class PickUpPoint {
public String shelving;
public String cardinalPoint;
public String getShelving() {
return shelving;
}
public String getCardinalPoint() {
return cardinalPoint;
}
PickUpPoint(String shelving, String cardinalPoint) {
this.shelving = shelving;
this.cardinalPoint = cardinalPoint;
}
}
But I got this from the array list:
So, my question is...How to get all the elements from the array list like this?
Use this method to set text from Arraylist
Also check if Arraylist is not null and empty
public void setTextViewFromList(ArrayList<PickUpPoint> arraylist, TextView textview) {
//Variable to hold all the values
String output = "";
for (int i = 0; i < arraylist.size(); i++) {
//Append all the values to a string
output += arraylist.get(i).getShelving();//whatever you want to show here like shelving or cordinalpoint use getCordinalPoint()
output += "\n";
}
//Set the textview to the output string
textview.setText(output);
}
USAGE
Call this method like this
setTextViewFromList(pickuppoint_array,coordenada_view)
I assume that the coordenada_view#setTextcan only be called once.
So you need to convert the Elements in pickuppoint_array into a String first
and then supply this to the setText method.
StringBuilder content = new StringBuilder();
for (int i = 0; i < pickuppoint_array.size(); i++) {
content.append(pickuppoint_array.get(i).toString());
content.append('\n');
}
coordenada_view.setText(content.toString());
You also want to implement the toString() method in your PickUpPoint class to return the desired representation of each object, for example:
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("SHELVING ");
builder.append(shelving);
builder.append(" - ");
builder.append(cardinalPoint);
return builder.toString();
}
Ps.:
If you know the expected length of these strings you should supply this as parameter to the StringBuilder constructor, so the jvm does not need to waste time with resizing it.
new StringBuilder(18) might work for the toString method,
and new StringBuilder(19 * pickuppoint_array.size()) might work for the other one.
I have been trying to build a simple calculator in android studio. Everything is fine but i have a problem, when i run the calculator and i press the dot button, it shows in the textview "." instead "0."
Also, i need to check the existence of two decimal points in a single numeric value.
here is an image:
it shows "."
and i want:
how can i change this??, here is my code:
private int cont=0;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
display=(TextView)findViewById(R.id.display);
text="";
}
public void numero1(View view){ /*when i press a number, this method executes*/
Button button = (Button) view;
text += button.getText().toString();
display.setText(text);
}
public void dot(View view){ /*This is not finished*/
display.setText{"0."}
}
I was thinking in creating another method for the dot button, but the content of the text value disappears when i press another button, how to fix this?
try this
public void numero1(View view){ /*when i press a number, this method executes*/
Button button = (Button) view;
text += button.getText().toString();
if(text.substring(0,1).equals("."))
text="0"+text;
display.setText(text);
}
try this way
public void dot(View view){ /*This is not finished*/
String str=display.getText().toString().trim();
if(str.length()>0){
display.seText(str+".")
}else{
display.setText("0.")
}
}
Use a string builder and append all the text entered to already existing string. Before display, just use the toString() method on the string builder.
Create a class that represents your character sequence to be displayed and process the incoming characters.
For example:
class Display {
boolean hasPoint = false;
StringBuilder mSequence;
public Display() {
mSequence = new StringBuilder();
mSequence.append('0');
}
public void add(char pChar) {
// avoiding multiple floating points
if(pChar == '.'){
if(hasPoint){
return;
}else {
hasPoint = true;
}
}
// avoiding multiple starting zeros
if(!hasPoint && mSequence.charAt(0) == '0' && pChar == '0'){
return;
}
// adding character to the sequence
mSequence.append(pChar);
}
// Return the sequence as a string
// Integer numbers get trailing dot
public String toShow(){
if(!hasPoint)
return mSequence.toString() + ".";
else
return mSequence.toString();
}
}
Set such a click listener to your numeric and "point/dot" buttons:
class ClickListener implements View.OnClickListener{
#Override
public void onClick(View view) {
// getting char by name of a button
char aChar = ((Button) view).getText().charAt(0);
// trying to add the char
mDisplay.add(aChar);
// displaying the result in the TextView
tvDisplay.setText(mDisplay.toShow());
}
}
Initialize the display in onCreate() of your activity:
mDisplay = new Display();
tvDisplay.setText(mDisplay.toShow());
note: I've created a GitHub repo containing the repro for this bug here. Feel free to clone and try the app out yourself to see the bug. The relevant code is here: with the commented part kept in a comment it works fine, uncomment it and you will experience the bug.
I'm building a source code editor app for Android. I have a custom Editable type that wraps SpannableStringBuilder (which will henceforth be referred to as SSB). Here is its code:
package com.bluejay.myapplication;
import android.text.Editable;
import android.text.InputFilter;
import android.text.SpannableStringBuilder;
public class ColoredText implements Editable {
private final SpannableStringBuilder builder;
public ColoredText(String rawText) {
assert rawText != null;
this.builder = new SpannableStringBuilder(rawText);
}
#Override
public Editable replace(int st, int en, CharSequence source, int start, int end) {
this.builder.replace(st, en, source, start, end);
return this;
}
#Override
public Editable replace(int st, int en, CharSequence text) {
this.builder.replace(st, en, text);
return this;
}
#Override
public Editable insert(int where, CharSequence text, int start, int end) {
this.builder.insert(where, text, start, end);
return this;
}
#Override
public Editable insert(int where, CharSequence text) {
this.builder.insert(where, text);
return this;
}
#Override
public Editable delete(int st, int en) {
this.builder.delete(st, en);
return this;
}
#Override
public Editable append(CharSequence text) {
this.builder.append(text);
return this;
}
#Override
public Editable append(CharSequence text, int start, int end) {
this.builder.append(text, start, end);
return this;
}
#Override
public Editable append(char text) {
this.builder.append(text);
return this;
}
#Override
public void clear() {
this.builder.clear();
}
#Override
public void clearSpans() {
this.builder.clearSpans();
}
#Override
public void setFilters(InputFilter[] filters) {
this.builder.setFilters(filters);
}
#Override
public InputFilter[] getFilters() {
return this.builder.getFilters();
}
#Override
public void getChars(int start, int end, char[] dest, int destoff) {
this.builder.getChars(start, end, dest, destoff);
}
#Override
public void setSpan(Object what, int start, int end, int flags) {
this.builder.setSpan(what, start, end, flags);
}
#Override
public void removeSpan(Object what) {
this.builder.removeSpan(what);
}
#Override
public <T> T[] getSpans(int start, int end, Class<T> type) {
return this.builder.getSpans(start, end, type);
}
#Override
public int getSpanStart(Object tag) {
return this.builder.getSpanStart(tag);
}
#Override
public int getSpanEnd(Object tag) {
return this.builder.getSpanEnd(tag);
}
#Override
public int getSpanFlags(Object tag) {
return this.builder.getSpanFlags(tag);
}
#Override
public int nextSpanTransition(int start, int limit, Class type) {
return this.builder.nextSpanTransition(start, limit, type);
}
#Override
public int length() {
return this.builder.length();
}
#Override
public char charAt(int index) {
return this.builder.charAt(index);
}
#Override
public CharSequence subSequence(int start, int end) {
return this.builder.subSequence(start, end);
}
}
As you can see, this type is a simple wrapper for SSB. new ColoredText(str) creates the underlying SSB from str, and all of its method calls (with the exception of append, delete, etc. which return this instead of the SSB) simply forward to the SSB.
Now when I have an EditText and I try to set the ColoredText as the underlying text of the EditText, like so
EditText editText = (EditText) findViewById(R.id.editText);
// By default, setText() will attempt to copy the passed CharSequence into a new SSB.
// See https://github.com/android/platform_frameworks_base/blob/master/core/java/android/widget/TextView.java#L4396
// and https://github.com/android/platform_frameworks_base/blob/master/core/java/android/text/Editable.java#L143
// I want to prevent this and have the ColoredText instead of an SSB be the EditText's
// underlying text, that is, I want the mText member to be of type ColoredText.
editText.setEditableFactory(new Editable.Factory() {
#Override
public Editable newEditable(CharSequence source) {
return (Editable) source; // source is ColoredText
}
});
ColoredText text = new ColoredText("Hello world!\nHello world again!");
editText.setText(text, TextView.BufferType.EDITABLE);
The EditText will behave quite glitchy when edited. In the above example, tap anywhere on the first line with Hello world! and start typing random characters. The second line will be affected, and somehow (even if you don't touch a newline or arrow keys) the cursor will eventually spill over into the second line. And some of the chars you type may not get displayed, even though the cursor will move.
Now if you comment out the setEditableFactory part, so the text is copied into an SSB during setText(), and you run the app again, you will see there are no glitches.
It even works if you leave the setEditableFactory part intact, but replace the variable initialization of text with
SpannableStringBuilder text = new SpannableStringBuilder("Hello world!\nHello world again!");
Clearly, although setText() says it'll accept any Editable, it doesn't work well when dealing with anything other than an SSB. Why does this happen and how can I fix it? Thanks.
By digging the source code of SpannableStringBuilder I figured out that it not only fulfils the responsibilities defined by the Interfaces Editable, etc. but also reports the span change by calling SpanWatcher.onSpanChanged() by passing this. DynamicLayout (the real workhorse of EditText) responds to onSpanChanged() by checking the equality of passed in reference with it's member (which is our actual ColoredSpan instance). Obviously they are different and I suspect that this is a problem.
Actually SpannableStringBuilder is not just Editable, but more than that. If you need a custom Editable subclassing SpannableStringBuilder may work.
I'm kinda new to java programming for android, so if i make stupid mistakes, i'm sorry.
So basically, what i wanna make is an app where if you type in the answer correctly, the next textview is gonna be displayed. And when the next textView is displayed, you're needing to give a answer to that textView, when the answer is given correctly. The textview changes again. And so on.
Does anybody have an idea how to do this?
If you don't undarstand what im saying, here is a example:
public class Game extends AppCompatActivity {
public static EditText editText_ans;
public static TextView textView_1;
String enteredText = editText.getText().toString();
If(enteredText = 3 && textView_1 = #string/1+2){
setText.textView_1(#string/3+4)
}
If(enteredText = 7 && textView_1 = #string/3+4){
setText.textView_1("100 - 23")
I'm really stuck and i hope that you guys wanna help me.
If you wanted to change the view without button you can use method addTextChangeListner() which will notify you when when the text hasbeen change for particular edittext.
edittext.addTextChangedListener(textWatcher);
private final TextWatcher textWatcher = new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
textView.setVisibility(View.VISIBLE);
}
public void afterTextChanged(Editable s) {
if (s.length() == 0) {
textView.setVisibility(View.GONE);
} else{
textView.setText("You have entered : " + editText.getText());
}
}
};
int x=0; //to keep track of qustions
private List<String> mQuestionList=new ArrayList<>(); //array of question
private List<String> mAnswerList=new ArrayList<>(); //array of question answer
displayquestion.settext(mQuestionList.get(x);//displayquestion is textview
//nextquestion is the button when user click it will first check answer and than move to next question if answer is correct
nextquestion.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String answer=editText.getText().toString();
if(answer.equal(mAnswerList.get(x)){
x=x+1;
displayquestion.settext(mQuestionList.get(x); //answer is correct display next quesion
}else{
//wrong answer
}
}
});
All- I have been struggling with this for a while and have looked at all the other questions about this sort of thing but I just can't figure it out: I have an edttext field that needs to be formatted for currency. I have tried the code in all of the other questions relating to this but no matter what I try it just doesn't work. Here is my code:
EditText text = (EditText)findViewById(R.id.edit_bill);
text.setRawInputType(Configuration.KEYBOARD_12KEY);
text.addTextChangedListener(new TextWatcher(){
EditText text = (EditText)findViewById(R.id.edit_bill);
DecimalFormat dec = new DecimalFormat("0.00");
public void afterTextChanged(Editable arg0) {
}
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
public void onTextChanged(CharSequence s, int start,
int before, int count) {
if(!s.toString().matches("^\\$(\\d{1,3}(\\,\\d{3})*|(\\d+))(\\.\\d{2})?$"))
{
String userInput= ""+s.toString().replaceAll("[^\\d]", "");
if (userInput.length() > 0) {
Float in=Float.parseFloat(userInput);
float percen = in/100;
text.setText("$"+dec.format(percen));
text.setSelection(text.getText().length());
}
}
}
});
This code is inside of an onClick method. Does that make a difference (eg. the text will only be formatted when the user clicks the button)?. Thanks in advance!
I have used this method in the past for formatting money.
static public String customFormat(String pattern, double s ) {
DecimalFormat myFormatter = new DecimalFormat(pattern);
String stringFormatOutput = myFormatter.format(s);
return stringFormatOutput;
}
it can be used like this:
String strPrice = customFormat("$###,##0.00", 300.2568);
mTxt.setText(strPrice);
just change the "300.2568" to be your price. This probably could work just as well for floats instead of doubles.