开发者

EditText Values in range

I would like to enter the values in a range like 1-60. The EditText 开发者_高级运维shouldn't accept values like 61,62..., or 0,-1,-2...

How can we give the range 1-60 to EditText in android? I have done in main.xml as

 <EditText android:layout_height="wrap_content" 
    android:id="@+id/editText1" 
    android:layout_width="160dip" 
    android:inputType="number">
    </EditText>


You can assign a TextWatcher to your EditText and listen for text changes there, for example:

public void afterTextChanged(Editable s) {
   try {
     int val = Integer.parseInt(s.toString());
     if(val > 60) {
        s.replace(0, s.length(), "60", 0, 2);
     } else if(val < 1) {
        s.replace(0, s.length(), "1", 0, 1);
     }
   } catch (NumberFormatException ex) {
      // Do something
   }
}

As mentioned by Devunwired, notice that calls to s.replace() will call the TextWatcher again recursively.

It is typical to wrap these changes with a check on a boolean "editing" flag so the recursive calls skip over and simply return while the changes that come from within.


I have come across a neat solution here:

public class InputFilterMinMax implements InputFilter {

private int min, max;

public InputFilterMinMax(int min, int max) {
    this.min = min;
    this.max = max;
}

public InputFilterMinMax(String min, String max) {
    this.min = Integer.parseInt(min);
    this.max = Integer.parseInt(max);
}

@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    try {
        int input = Integer.parseInt(dest.toString() + source.toString());
        if (isInRange(min, max, input))
            return null;
    } catch (NumberFormatException nfe) { }
    return "";
}

private boolean isInRange(int a, int b, int c) {
    return b > a ? c >= a && c <= b : c >= b && c <= a;
}
}

And simply apply this filter to an edit text like so:

mCentsEditText = (EditText)v.findViewById(R.id.cents_edit_text);
InputFilterMinMax filter = new InputFilterMinMax("0", "99") {};
mCentsEditText.setFilters(new InputFilter[]{filter});


I fixed Daniel Wilson's solution:

public class InputFilterMinMax implements InputFilter {

private int min, max;

public InputFilterMinMax(int min, int max) {
    this.min = min;
    this.max = max;
}

public InputFilterMinMax(String min, String max) {
    this.min = Integer.parseInt(min);
    this.max = Integer.parseInt(max);
}

@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    try {
        //The commented line below only works if you append/modify the end of the text (not the beginning or middle)
        //int input = Integer.parseInt(dest.toString() + source.toString());
        //corrected solution below (3lines)
        CharSequence part1 = dest.subSequence(0, dstart);
        CharSequence part2 = dest.subSequence(dend, dest.length());
        int input = Integer.parseInt(part1 + source.toString() + part2);

        if (isInRange(min, max, input))
            return null;
    } catch (NumberFormatException nfe) { }
    return "";
}

private boolean isInRange(int a, int b, int c) {
    return b > a ? c >= a && c <= b : c >= b && c <= a;
}
}

Finally add the InputFilter to your EditText control:

mCentsEditText = (EditText)findViewById(R.id.cents_edit_text);
InputFilterMinMax filter = new InputFilterMinMax("1", "60") {};
mCentsEditText.setFilters(new InputFilter[]{filter});


Try this..

   EditText.setOnEditorActionListener(new OnEditorActionListener()
    {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event)
{
    //add your condtion here.
    return false;
}   
});


Why not use a Seekbar Instead of EditText? That way, only numbers can be entered and the maximum limit can be specified/modified as and when you need.

public class SeekBar1 extends Activity implements SeekBar.OnSeekBarChangeListener {
 @Override
 protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   ..
   mSeekBar = (SeekBar)findViewById(R.id.seekBar);
   mSeekBar.setOnSeekBarChangeListener(this);
   ..
 }
 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
   //Do your Changes Here
 }
 public void onStartTrackingTouch(SeekBar seekBar) {
    //On First Track Touch
 }
 public void onStopTrackingTouch(SeekBar seekBar) {
    //On Stop Track Touch
 }
}

For numerical Input type values, Seekbar is the best possible UI. Although, the precision on it is questionable.


Very interesting question.

I guess the best way to do this is implementing a new inputType, but the setInputType method receives an int. Nothing to do there :(

In that method doc it says:

Set the type of the content with a constant as defined for inputType. This will take care of changing the key listener, by calling setKeyListener(KeyListener), to match the given content type.

Excellent, you can provide a keyListener with setKeyListener.

You can extend android.text.method.DigitsKeyListener to create your new keyListener, avoiding the issue with the TextWatcher.


I don't have enough priviledges to comment on Ashok Felix's answer but I'd like to add that I have found some code premitting to display a SeekBar in preferences.

It is very easy to use (I'm not the author). See the SeekBarPreference code by Matthew Wiggins: http://android.hlidskialf.com/blog/code/android-seekbar-preference


This works but not live.

editText.setOnFocusChangeListener(new OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                try {
                    int val = Integer.parseInt(editText.getText()
                            .toString());
                    if (val > 2000) {
                        editText.setText("");
                    } else if (val < 100) {
                        editText.setText("");
                    }
                } catch (NumberFormatException ex) {
                }
            }
        });
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜