2013-09-22 3 views
3

В activity_main.xml:NumberPicker не работает с клавиатурой

<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" /> 

В MainActivity.java внутри oncreate:

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

Когда я изменить значение с клавиатуры, значение, которое я получаю программно Безразлично» t, но если я нажму +, тогда - он работает.

Как я могу заставить его работать без нажатия + и -?


EDIT:

Я создал новый проект с кодом Мелиха Алтинтаса и отображается целый новый numberpicker !! (Тот, где вы скользят пальцем и не можете вводить текст). Затем я сравнил свой проект и увидел android:theme="@android:style/Theme.NoTitleBar". Я добавил его в новый проект, а затем номерчик стал тем, к которому я привык.

+0

У меня такая же проблема, есть ли у кого-нибудь лучший ответ для этого, но все же? –

ответ

10

NumberPicker не был создан для этого взаимодействия. Когда вы меняете значение с помощью клавиатуры, вы вносите изменения непосредственно в виджет из NumberPicker, и сам виджет не видит этого изменения, поэтому вы получаете последнее сохраненное значение. Чтобы обойти это, вам понадобится какой-то взломанный код, который на самом деле не рекомендуется, потому что вам нужно получить доступ к базовому EditText (при условии, что производитель телефона не изменил его в первую очередь):

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; 
} 

, а затем вы будете использовать этот код, чтобы установить TextWatcher на найденной EditText увидеть, когда она изменяется вручную (и пусть NumberPicker знать об этих изменениях):

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); 

Другой вариант должен был бы сделать свой собственной реализации виджета NumberPicker и вставьте функциональность, которую вы ta rget.

+0

Вы протестировали это? Я имею в виду, вы уверены? он должен работать? Поскольку это приводит к сбою моего приложения с 'Invalid int:" "'. (Btw, я переместил 'input.addTextChangedListener (tw);' внизу, потому что tw не будет определен) – Mageek

+0

@Mageek Строка 'np.setValue (Integer.parseInt (s.toString()));' должна быть завернута в check, чтобы проверить, не является ли String пустой (например, при удалении всех чисел): 'if (s.toString(). length() == 0) {np.setValue(). getMinValue(); } else {np.setValue (Integer.parseInt (s.toString()));} ' – Luksprog

+0

Вы уверены, что это' np.setValue(). getMinValue(); '? Потому что аргументов нет ... (Извините, я все еще новичок в программировании на Java и Андроиде) – Mageek

1

Чтобы изменить значение программного обеспечения, необходимо нажать кнопку Done.

+0

Я только что попробовал, и это не сработало:/ – Mageek

+0

работает сейчас, поэтому, когда у вас есть слушатель, чтобы нажать положительную кнопку, если вы нажмете кнопку очистки, она должна работать. На этом этапе есть два предположения. Почему это работает, потому что предположение состоит в том, что вы уже ввели текст, и когда вы вызываете clearFocus во внутренней реализации этого метода, вы получите значение и установите его на внутреннем сборщике номеров edittext –

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

Я не знаю почему, но это ( – Mageek

+0

Я просто нашел что-то действительно странное, см. мое редактирование. Знаете ли вы, что делать? – Mageek

+0

Это странный андроид: theme = "@ android: style/Theme.Light.NoTitleBar" относится к строке состояния Если вы хотите удалить строку состояния, а затем использовать ее –

10

Если кто-то хочет простую обходную процедуру, просто добавьте код ниже, прежде чем сохранять значение.

numberPicker.clearFocus(); 
+0

IMO это простейшее исправление и лучше всего: он работает. –

+0

Он работает! Благодаря !! – ElOjcar

+0

Вы настоящий MVP – mariozawa

1

Я вижу, что у вас уже есть ответ, однако это может быть полезно другим. Вы можете расширить android.widget.NumberPicker и сделать свой собственный, где вы можете настроить EditText. Когда вы вводите на мягкую клавиатуру, значение вашего NumPicker сразу устанавливается на значение, которое вы вводите.

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 
        } 
       }});  
      } 
      } 
    } 

В вашем XML-файл, который вы поместите следующее:

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

причина, почему он не работает это, потому что если вы посмотрите на реализацию SetValue в NumberPicker, он вызывает другой метод setValueInternal (int, boolean), который принимает 2 параметра новое значение и, конечно, bugger boolean, который представляет, должен ли он уведомлять пользовательский интерфейс о любых изменениях или нет. И угадайте, что, в setValue, логическое значение всегда имеет значение false. Godammit. Но есть еще один трюк, который я вижу, что validateInputTextView на самом деле делает это правильно, и он вызывает, когда текст редактирования не имеет фокуса. возможно, в нужное время очистка фокуса будет делать то, что должно делать.

Смежные вопросы