it-roy-ru.com

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

Я пытаюсь отключить программную клавиатуру при использовании 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. Есть идеи?

161
damaxxed

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

myNumberPicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);

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

Android:descendantFocusability="blocksDescendants" 
451
Andrew Webber

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

Android:descendantFocusability="blocksDescendants"

Пример

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

Прочитав исходный код 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);
7
damaxxed

Просто улучшил ответ @MaxVogler (так что если вы хотите проголосовать и за этот голос @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;
        }
    }
}
6
havexz

Вот еще один способ сделать это, который позволяет пользователю по-прежнему редактировать число, если он хочет - он просто подавляет программную клавиатуру на начальном этапе. Используйте 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;
}
4
Dave Haines

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

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

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

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

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

    <!-- 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"/>
1
eckc

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

numberPicker.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View view) {
  }
});
1
user4215456
/**
 * 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 () позволит получить правильное значение


0
ceph3us

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

mp.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);

XML:

Android:descendantFocusability="blocksDescendants" 
0
Vinayak