在NumberPicker上禁用软键盘


168

我试图在使用NumberPicker输入数字值(出于美观原因)时停用软键盘。这是我的layout-xml-code:

<?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时仍会显示软键盘。有任何想法吗?

Answers:


475

刚刚发现,它就像一个魅力:

myNumberPicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);

您也可以使用XML进行设置:

android:descendantFocusability="blocksDescendants" 

1
除非我缺少任何内容,否则将无法输入NumberPicker的值。取决于您使用选择器的方式,这不一定是一件坏事,但这确实是解决方案的局限性。
frenziedherring

76
您也可以在XML中进行设置:android:descendantFocusability =“ blocksDescendants”
Ben Clayton

1
Aaah,当然是后裔。非常感谢您:)
Lev

了不起的解决方案,救了我!
Hamzeh Soboh,

56

Xml版本的Andrew Webber的答案

android:descendantFocusability="blocksDescendants"

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

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

是的,我必须直接编辑NumberPicker的子视图。有时,Android API非常稀疏。
damaxxed

6

刚刚增强了@MaxVogler的ans(因此,如果还要投票,请投票@MaxVogler),并使其成为一个强大的工具。另外,我们不需要致电setOnFocusChangeListenersetInputType。只有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;
        }
    }
}

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


2

我发现最简单的工作是:

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

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

1

我不知道为什么会这样,但是设置什么都不做的OnClickListener会阻止键盘显示(Lollipop)

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

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

*称为:

  • 不会阻止后代的可聚焦性(数字选择器将可编辑)

  • 将在创建时隐藏软输入

  • 之前(处理输入)getValue()将允许获得适当的收益



0

编程方式工作代码

mp.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);

XML:

android:descendantFocusability="blocksDescendants" 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.