Wyłącz klawiaturę numeryczną w NumberPicker


168

Próbuję dezaktywować klawiaturę programową, gdy używam NumberPicker do wprowadzania wartości liczbowych (ze względów estetycznych). To jest mój kod układu-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>

I na koniec jest to kod, w którym próbuję zablokować klawiaturę w metodzie 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); 

Niestety, po kliknięciu elementu NumberPicker nadal pojawia się klawiatura programowa. Jakieś pomysły?

Odpowiedzi:


475

Właśnie to znalazłem i działa jak marzenie:

myNumberPicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);

Możesz również ustawić to w XML:

android:descendantFocusability="blocksDescendants" 

1
O ile czegoś nie brakuje, usuwa to możliwość wpisania wartości dla NumberPicker. Niekoniecznie jest to zła rzecz, w zależności od tego, jak używasz selektora, ale wydaje się, że jest to ograniczenie rozwiązania.
frenziedherring

76
Możesz również ustawić to w XML: android: descendantFocusability = "blocksDescendants"
Ben Clayton,

1
Aaach, bloki, potomkowie, oczywiście. Dziękuję bardzo :)
Lev

Niesamowite rozwiązanie, uratowało mnie!
Hamzeh Soboh

56

Wersja XML odpowiedzi Andrew Webbera

android:descendantFocusability="blocksDescendants"

Przykład

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

7

Po przeczytaniu kodu źródłowego com / android / internal / widget / NumberPicker.java dotarłem do następującego rozwiązania:

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

Tak, musiałem bezpośrednio edytować widoki potomne NumberPicker. Interfejs API systemu Android jest czasami bardzo rzadki.
damaxxed

6

Właśnie ulepszyliśmy odpowiedzi @MaxVogler (więc jeśli nie chcesz głosować w tym głosowaniu również @MaxVogler) i uczyń z niego solidnego hacka. Nie musimy też dzwonić setOnFocusChangeListeneri setInputType. Tylko setFocusablefałsz zrobi.

Poniżej znajduje się pomocniczy interfejs API do włączania / wyłączania tej funkcji

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

Oto inny sposób, aby to zrobić, który pozwala użytkownikowi nadal edytować numer, jeśli chce - po prostu początkowo wyłącza klawiaturę programową. Służy NumberPicker.setDescendantFocusability(FOCUS_BLOCK_DESCENDANTS)do wyłączania klawiatury ekranowej, gdy interfejs wyświetla się po raz pierwszy zgodnie z powyższymi odpowiedziami. Następnie weź swoje okno dialogowe lub działanie do zaimplementowania View.OnTouchListener, zadzwoń setOnTouchListener(this)do swojego NumberPicker, aw swojej implementacji onTouch(View v,MotionEvent e)zresetuj możliwość ustawiania ostrości potomka Numberpicker do normalnej wartości, a następnie zwróć false.

Zwrócenie wartości false oznacza, że ​​dotknięcie jest nadal przetwarzane przez NumberPicker, co oznacza, że ​​jeśli użytkownik dotknie pola edycji, pojawi się klawiatura programowa. Tak się składa, że ​​jest to dokładnie to, co chciałem zmierzyć się z tym samym problemem - posiadanie miękkiej klawiatury przy wyświetlaniu okna dialogowego po raz pierwszy jest niezadowalające, ponieważ przesuwa okno dialogowe w górę po jego pojawieniu się.

public class GetBufferDialog extends DialogFragment implements View.OnTouchListener {

po utworzeniu Dialogu w onCreateDialog()metodzie i znalezieniu NumberPicker:

m_oldFocus = m_numberpicker.getDescendantFocusability();
m_numberpicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS); 
m_numberpicker.setOnTouchListener(this);

a oto metoda OnTouch:

public boolean onTouch(View v, MotionEvent event) {
    m_numberpicker.setDescendantFocusability(m_oldFocus);
    return false;
}

1
tylko ten pomógł mi rozwiązać mój problem, dzięki za podejście
smoothumut

2

Najprostszy, jaki znalazłem, to:

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

2

Jeśli chcesz tylko ukryć klawiaturę programową podczas ładowania widoku za pomocą selektora numerów, ale nadal chcesz, aby użytkownicy mogli edytować po załadowaniu widoku, nie powinieneś blokować możliwości ustawiania ostrości na elementach potomnych. Zamiast tego po prostu nie pozwól, aby selektor liczb był pierwszym aktywnym elementem w widoku.

Zobacz tę odpowiedź, aby uzyskać szczegółowe informacje.

Na podstawie powyższej odpowiedzi:

    <!-- 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

Nie wiem, dlaczego to działa, ale ustawienie OnClickListener, które nic nie zapobiega wyświetlaniu klawiatury (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();
        }
    }
}

* nazywając to:

  • nie będzie blokować ostrości potomków (wybieranie numerów będzie edytowalne)

  • ukryje miękkie dane wejściowe podczas tworzenia

  • before (przetwarzanie danych wejściowych) getValue () pozwoli uzyskać właściwą walue



0

Kod roboczy Programowo:

mp.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);

XML:

android:descendantFocusability="blocksDescendants" 
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.