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

168

Я пытаюсь отключить программную клавиатуру при использовании NumberPicker для ввода числовых значений (по эстетическим соображениям). Это мой layout-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. Любые идеи?

damaxxed
источник

Ответы:

475

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

myNumberPicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);

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

android:descendantFocusability="blocksDescendants" 
Эндрю Уэббер
источник
1
Если я что-то не упустил, это исключает возможность ввода значения для NumberPicker. Это не обязательно плохо, в зависимости от того, как вы используете сборщик, но, похоже, это ограничение решения.
frenziedherring
76
Вы также можете установить это в XML: android: downndantFocusability = "blocksDescendants"
Бен Клейтон
1
Аааа, блоки потомки, конечно. Спасибо большое :)
Лев
Удивительное решение, спасло меня!
Хамзех Собох
56

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

android:descendantFocusability="blocksDescendants"

пример

<NumberPicker
        android:id="@+id/your_numberpicker"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:descendantFocusability="blocksDescendants"/>
G_v
источник
7

Прочитав исходный код 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);
damaxxed
источник
Да, мне пришлось напрямую редактировать дочерние представления NumberPicker. Android API иногда очень скуден.
Damaxxed
6

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

Ниже приведен вспомогательный 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;
        }
    }
}
havexz
источник
4

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

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

numberPicker               = (NumberPicker) myDialogView.findViewById(R.id.myViewId);
EditText numberPickerChild = (EditText) numberPicker.getChildAt(0);
numberPickerChild.setFocusable(false);
numberPickerChild.setInputType(InputType.TYPE_NULL);
bapjg
источник
2

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

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

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

    <!-- 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"/>
eckc
источник
1

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

numberPicker.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View view) {
  }
});
user4215456
источник
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();
        }
    }
}

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

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

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

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


ceph3us
источник
0

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

mp.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);

XML:

android:descendantFocusability="blocksDescendants" 
Винаяк
источник