Отключить мягкую клавиатуру на NumberPicker

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

<?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. Любые идеи?

Ответ 1

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

myNumberPicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);

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

android:descendantFocusability="blocksDescendants" 

Ответ 2

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

android:descendantFocusability="blocksDescendants"

Пример

<NumberPicker
        android:id="@+id/your_numberpicker"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:descendantFocusability="blocksDescendants"/>

Ответ 3

После прочтения исходного кода com/android/internal/widget/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);

Ответ 4

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

Ниже приведена вспомогательная функция api для включения/выключения функции

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

Ответ 5

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

Ответ 6

Самый простой, который я нашел для работы, был:

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

Ответ 7

Я не знаю, почему это работает, но настройка OnClickListener, которая ничего не делает, не дает клавиатуре отображаться (Lollipop)

numberPicker.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View view) {
  }
});

Ответ 8

Если вы хотите скрыть программную клавиатуру только при загрузке представления с помощью средства выбора номера, но при этом хотите, чтобы пользователи могли редактировать после загрузки представления, то не следует блокировать возможность фокусировки по потомкам. Вместо этого просто не позволяйте сборщику чисел быть первым целевым элементом в вашем представлении.

Смотрите этот ответ для деталей.

Основываясь на ответе выше:

    <!-- Dummy item to prevent Number Picker from receiving focus -->
    <LinearLayout        
        android:focusable="true" 
        android:focusableInTouchMode="true"
        android:layout_width="0px" 
        android:layout_height="0px"/>

    <!-- :nextFocusUp and :nextFocusLeft have been set to the id of this component 
         to prevent the dummy from receiving focus again -->
    <NumberPicker 
        android:id="@+id/number_picker"
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content"
        android:nextFocusUp="@id/number_picker" 
        android:nextFocusLeft="@id/number_picker"/>

Ответ 9

/**
 * 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 будет редактироваться)

  • будет скрывать мягкий ввод при создании

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


Ответ 10

Рабочий код программно:

mp.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);

XML:

android:descendantFocusability="blocksDescendants"