NumberPicker에서 소프트 키보드 비활성화


168

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를 클릭하면 소프트 키보드가 계속 나타납니다. 어떤 아이디어?

답변:


475

방금 이것을 발견했으며 매력처럼 작동합니다.

myNumberPicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);

이것을 XML로 설정할 수도 있습니다 :

android:descendantFocusability="blocksDescendants" 

1
내가 빠진 것이 아니라면 NumberPicker에 값을 입력하는 기능이 제거됩니다. 선택기를 사용하는 방법에 따라 반드시 나쁜 것은 아니지만 솔루션의 한계로 보입니다.
frenziedherring

76
android : descendantFocusability = "blocksDescendants"
Ben Clayton

1
Aaah, 블록, 자손, 물론. 대단히 감사합니다 :)
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의 자식 뷰를 직접 편집해야했습니다. 안드로이드 API는 때때로 매우 드물다.
damaxx.

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

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

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 ()는 적절한 walue를 얻을 수 있습니다.



0

프로그래밍 방식으로 작업 코드 :

mp.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);

XML :

android:descendantFocusability="blocksDescendants" 
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.