NumberPicker doesn't work with keyboard

末鹿安然 提交于 2019-12-31 02:25:07

问题


In activity_main.xml :

<NumberPicker
        android:id="@+id/numberPicker1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView2"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="30dp" />

In MainActivity.java inside the oncreate :

NumberPicker numberPicker1 = (NumberPicker) findViewById(R.id.numberPicker1);
numberPicker1.setMinValue(1);
numberPicker1.setMaxValue(20);

When I edit the value with the keyboard, the value that I get programmatically doesn't change, but if I press + then - it works.

How can I make it work without having to press + and -?


EDIT :

I created a new Project with the code of Melih Altıntaş and it displayed a whole new numberpicker!! (The one where you slide with your finger and can't enter text). Then I compared with my real project and I saw android:theme="@android:style/Theme.NoTitleBar". I added it in the new project and then the numberpicker became the one I was used to.


回答1:


The NumberPicker wasn't designed for that interaction. When you change the value with the keyboard you're making changes directly to a widget from the NumberPicker and the widget itself doesn't see this change so this is why you end up with the last stored value. To get around this you'll need some hacky code, which isn't really recommended, because you'll need to access the underlying EditText(assuming that the phone maker didn't changed this in the first place):

private EditText findInput(ViewGroup np) {
    int count = np.getChildCount();
    for (int i = 0; i < count; i++) {
        final View child = np.getChildAt(i);
        if (child instanceof ViewGroup) {
            findInput((ViewGroup) child);
        } else if (child instanceof EditText) {
            return (EditText) child;
        }
    }
    return null;
}

and then you'll use this code to set a TextWatcher on the found EditText to see when it's manually modified(and let the NumberPicker know about this change):

EditText input = findInput(np);    
TextWatcher tw = new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before,
                int count) {}

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {}

        @Override
        public void afterTextChanged(Editable s) {
                if (s.toString().length() != 0) {
                    Integer value = Integer.parseInt(s.toString());
                    if (value >= np.getMinValue()) {
                        np.setValue(value);
                    }
                }
        }
    };
input.addTextChangedListener(tw);

Another option would be to make your own implementation of the NumberPicker widget and insert the functionality you target.




回答2:


If anyone wants a simple workaround, just add the below code before saving the value.

numberPicker.clearFocus();



回答3:


You have to press the Done button for the value to programmatically change.




回答4:


NumberPicker np = (NumberPicker) findViewById(R.id.numberPicker1);
String[] nums = new String[20];
for(int i=0; i<nums.length; i++)
       nums[i] = Integer.toString(i);

np.setMinValue(1);
np.setMaxValue(20);
np.setWrapSelectorWheel(false);
np.setDisplayedValues(nums);
np.setValue(1);



回答5:


I see that you already have an answer, however this may be useful to others. You can extend android.widget.NumberPicker and make your own where you can configure the EditText. As you type on the soft keyboard, the value of your NumberPicker is immediately set to the value you're typing.

public class MyNumberPicker extends android.widget.NumberPicker {

       private EditText eText;

       public MyNumberPicker(Context context, AttributeSet attrs) {
        super(context, attrs);
       }


       @Override
       public void addView(View child) {
         super.addView(child);
         initEditText(child);
       }

       @Override
       public void addView(View child, int index, android.view.ViewGroup.LayoutParams params) {
         super.addView(child, index, params);
         initEditText(child);
       }

       @Override
       public void addView(View child, android.view.ViewGroup.LayoutParams params) {
         super.addView(child, params);
         initEditText(child);
       }

       public void initEditText(View view){
           if(view instanceof EditText){
               EditText eText = (EditText) view;
               eText.addTextChangedListener(new TextWatcher(){

                @Override
                public void afterTextChanged(Editable arg0) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void beforeTextChanged(CharSequence arg0, int arg1,
                        int arg2, int arg3) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                    try{
                        int num = Integer.parseInt(s.toString());
                        setValue(num); //this line changes the value of your numberpicker
                    }catch(NumberFormatException E){
                            //do your catching here
                    }   
                }});     
             }
          }
     }

In your XML-file you put the following:

<com.mypackage.MyNumberPicker
 android:id="@+id/numberPicker1"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content" />



回答6:


the reason why it doesn't work it's because if you look at the implementation of setValue in NumberPicker, it calls another method setValueInternal(int, boolean) which takes 2 parameters the new value and of course the bugger boolean which is representing whether it should notify the UI of any change or not. And guess what, in setValue the boolean goes always with false. Godammit. But there is one more trick I see that the validateInputTextView actually does it correctly, and it invokes when the edit text has no focus. maybe at the right time clearing the focus will do what is supposed to do.



来源:https://stackoverflow.com/questions/18944997/numberpicker-doesnt-work-with-keyboard

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!