133

Я пытаюсь деактивировать мягкую клавиатуру при использовании NumberPicker для ввода числовых значений (по эстетическим соображениям). Это мой макет-XML-код:Отключить мягкую клавиатуру на NumberPicker

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" > 

    <LinearLayout 
     android:id="@+id/linearLayout2" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center_horizontal" 
     android:layout_marginBottom="30dp" 
     android:layout_marginTop="30dp" > 

     <NumberPicker 
      android:id="@+id/repetitionPicker" 
      android:layout_width="40dp" 
      android:layout_height="wrap_content" /> 

     <TextView 
      android:id="@+id/textView1" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_gravity="center_vertical" 
      android:text="@string/repetitions_short_divider" 
      android:textAppearance="?android:attr/textAppearanceMedium" /> 

     <NumberPicker 
      android:id="@+id/weightPicker" 
      android:layout_width="40dp" 
      android:layout_height="wrap_content" 
      android:layout_marginLeft="40dp" /> 

     <TextView 
      android:id="@+id/textView2" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_gravity="center_vertical" 
      android:text="@string/pounds" 
      android:textAppearance="?android:attr/textAppearanceMedium" /> 
    </LinearLayout> 


    <Button 
     android:id="@+id/saveButton" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center_horizontal" 
     android:text="@string/save" /> 

</LinearLayout> 

И, наконец, это код, в котором я пытаюсь заблокировать клавиатуру в OnCreate() - метод:

// hide keyboard 
View.OnClickListener disableKeyBoardListener = new View.OnClickListener() { 
    public void onClick(View v) { 
     ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)) 
       .hideSoftInputFromWindow(v.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); 
    } 
}; 

((EditText) weightPicker.getChildAt(1)).setInputType(InputType.TYPE_NULL); 
((EditText) repetitionPicker.getChildAt(1)).setInputType(InputType.TYPE_NULL); 

((EditText) weightPicker.getChildAt(1)).setOnClickListener(disableKeyBoardListener); 
//((EditText) repetitionPicker.getChildAt(1)).setOnClickListener(disableKeyBoardListener); 
//weightPicker.setOnClickListener(disableKeyBoardListener); 
//repetitionPicker.setOnClickListener(disableKeyBoardListener);  

getWindow().setSoftInputMode(
     WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); 

К сожалению, мягкая клавиатура все еще появляется при нажатии на NumberPicker. Есть идеи?

ответ

380

Просто нашел это, и он работает как шарм:

myNumberPicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);

Вы также можете установить это в XML:

android:descendantFocusability="blocksDescendants" 
+1

Если я чего-то не упускаю, это удаляет возможность вводить значение для NumberPicker. Это не обязательно плохо, в зависимости от того, как вы используете сборщик, но это, по-видимому, является ограничением решения. – frenziedherring

+67

Вы также можете установить это в XML: android: descendantFocusability = "blocksDescendants" –

+1

Aaah, blocksDescendants, конечно. Большое спасибо :) – Lev

6

После прочтения через COM/Android/внутренний/виджет/NumberPicker.java исходного кода я получил к следующему решению:

// Hide soft keyboard on NumberPickers by overwriting the OnFocusChangeListener 
OnFocusChangeListener fcl = new OnFocusChangeListener() { 
    public void onFocusChange(View v, boolean hasFocus) { 
     // Do nothing to suppress keyboard 
    } 
}; 

((EditText) numberPicker.getChildAt(1)).setOnFocusChangeListener(fcl); 

// Suppress soft keyboard from the beginning 
((EditText) numberPicker.getChildAt(1)).setInputType(InputType.TYPE_NULL); 
+0

Ну его рода хак право? – havexz

+0

Да, мне пришлось непосредственно редактировать дочерние представления NumberPicker. Иногда API Android очень редкий. – damaxxed

+0

+1 для поиска hack ... :) – havexz

6

Просто усиливается анс @MaxVogler «s (так что если wannt голосовать этот голос @MaxVogler тоже) и сделать его надежным взломом. Также нам не нужно звонить setOnFocusChangeListener и setInputType. Только setFocusable на false будет делать.

Ниже помощник апи, чтобы включить/отключить функцию

public static void enableNumberPickerManualEditing(NumberPicker numPicker, 
     boolean enable) { 
    int childCount = numPicker.getChildCount(); 

    for (int i = 0; i < childCount; i++) { 
     View childView = numPicker.getChildAt(i); 

     if (childView instanceof EditText) { 
      EditText et = (EditText) childView; 
      et.setFocusable(enable); 
      return; 
     } 
    } 
} 
3

Вот еще один способ сделать это, что позволяет e пользователь по-прежнему редактирует номер, если захочет - он просто подавляет мягкую клавиатуру изначально. Используйте NumberPicker.setDescendantFocusability(FOCUS_BLOCK_DESCENDANTS) для подавления мягкой клавиатуры, когда интерфейс сначала показывает в соответствии с приведенными выше ответами. Затем запустите свой диалог или активность, чтобы реализовать View.OnTouchListener, позвоните setOnTouchListener(this) на свой NumberPicker, а в вашей реализации onTouch(View v,MotionEvent e) сбросьте фокусность потомка с цифровым именем до его нормального значения, а затем верните false.

Возврат false означает, что прикосновение по-прежнему обрабатывается NumberPicker, а это означает, что если пользователь удаляет окно редактирования, появляется мягкая клавиатура. Это происходит именно так, что я хотел столкнуться с одной и той же проблемой - если мягкая клавиатура придумала диалог, когда он впервые показывает, это неприятно, когда он сдвигает диалог вверх после его появления.

public class GetBufferDialog extends DialogFragment implements View.OnTouchListener { 

после создания Диалог в методе onCreateDialog() и найти NumberPicker:

m_oldFocus = m_numberpicker.getDescendantFocusability(); 
m_numberpicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS); 
m_numberpicker.setOnTouchListener(this); 

и вот метод OnTouch:

public boolean onTouch(View v, MotionEvent event) { 
    m_numberpicker.setDescendantFocusability(m_oldFocus); 
    return false; 
} 
+0

только этот помог мне решить мою проблему, спасибо за ваш подход – smoothumut

2

Простейшим я нашел работу было:

numberPicker    = (NumberPicker) myDialogView.findViewById(R.id.myViewId); 
EditText numberPickerChild = (EditText) numberPicker.getChildAt(0); 
numberPickerChild.setFocusable(false); 
numberPickerChild.setInputType(InputType.TYPE_NULL); 
+0

Спасибо большое! Я пробовал все безрезультатно, но это отлично работает ... – Christian

0
/** 
* set focus to top level window 
* disposes descendant focus 
* disposes softInput 
* @param context - activity context 
* @param enable - state of focus 
* */ 
public static void topLevelFocus(Context context, boolean enable){ 
    if(Activity.class.isAssignableFrom(context.getClass())){ 
     ViewGroup tlView = (ViewGroup) ((Activity) context).getWindow().getDecorView(); 
     if(tlView!=null){ 
      tlView.setFocusable(enable); 
      tlView.setFocusableInTouchMode(enable); 
      tlView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS); 
      tlView.requestFocus(); 
     } 
    } 
} 

* называет это:

  • не будет блокировать потомок фокусируемости (numberpicker будет доступен для редактирования)

  • скроет мягкий вход на создание

  • до (обработки ввода) getValue() позволит получить правильную сумму


47

Xml версия ответа Эндрю Уэббера

android:descendantFocusability="blocksDescendants" 

Пример

<NumberPicker 
     android:id="@+id/your_numberpicker" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:descendantFocusability="blocksDescendants"/> 
Смежные вопросы