NumberPicker does not work with the 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 oncreate :

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

When I edit the value using the keyboard, the value that I get programmatically does not change, but if I press + , then it works.

How can I make it work without pressing + and - ?


EDIT:

I created a new project with code Melih Altıntaş and it showed a completely new number! (The one where you slide your finger and cannot enter text). Then I compared my project and saw android:theme="@android:style/Theme.NoTitleBar" . I added it to a new project, and then the number became the one I'm used to.

+3
source share
6 answers

NumberPicker not designed for this interaction. When you change a value using the keyboard, you make changes directly to the widget from NumberPicker , and the widget itself does not see this change, so you end up with the last saved value. To get around this, you will need some hacked code, which is actually not recommended, because you need to access the basic EditText (provided that the phone manufacturer did not change 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 will use this code to set the TextWatcher to the found EditText to see when it was manually changed (and let 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 is to make your own implementation of the NumberPicker widget and insert the target functions.

+10
source

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

 numberPicker.clearFocus(); 
+10
source

You must press the Done button to change the program value.

+1
source
 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); 
+1
source

I see that you already have an answer, but it may be useful to others. You can extend android.widget.NumberPicker and make your own where you can customize EditText. When you type on a soft keyboard, the value of your NumberPicker is immediately set to the value you enter.

 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" /> 
+1
source

the reason it doesn't work is because if you look at the implementation of setValue in NumberPicker, it calls another setValueInternal (int, boolean) method, which takes 2 parameters a new value and, of course, bugger boolean, representing whether it should notify the user interface about any changes or not. And guess that, in setValue, the boolean value is always false. Godammit. But there is another trick that I see that validateInputTextView actually does it right, and it calls when the edit text has no focus. perhaps at the right time, clearing the focus will do what it should do.

0
source

Source: https://habr.com/ru/post/956127/


All Articles