Search code examples
javaandroidnumberpicker

NumberPicker doesn't work with keyboard


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.


Solution

  • 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.