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をクリックするとソフトキーボードが表示されます。何か案は?

回答:


475

ちょうどこれを見つけて、それは魅力のように機能します:

myNumberPicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);

これをXMLで設定することもできます。

android:descendantFocusability="blocksDescendants" 

1
私が何かを欠落していない限り、これはNumberPickerの値を入力する機能を削除します。ピッカーの使用方法によっては、必ずしも悪いことではありませんが、ソリューションの制限のように見えます。
frenziedherring

76
これをXMLで設定することもできます:android:descendantFocusability = "blocksDescendants"
Ben Clayton

1
ああ、blocks子孫、もちろん。ありがとうございました:)
Lev

素晴らしい解決策、私を救った!
Hamzeh Soboh

56

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

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は時々非常にまばらです。
2012年

6

@MaxVoglerのansを強化し(この投票に@MaxVoglerも投票したくない場合)、堅牢なハックにしました。またsetOnFocusChangeListener、とを呼び出す必要はありませんsetInputType。のみsetFocusablefalseに行います。

以下は機能を有効/無効にするヘルパー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)はfalseを返し、その後、通常の値にリセットnumberpickerの子孫フォーカス特性。

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

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

*これを呼び出す:

  • 子孫のフォーカス機能をブロックしません(numberpickerは編集可能です)

  • 作成時にソフト入力を非表示にします

  • (入力を処理する)getValue()が適切な値を取得する前に



0

プログラムによるコードの作業

mp.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);

XML:

android:descendantFocusability="blocksDescendants" 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.