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?

damaxxed
źródło

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" 
Andrew Webber
źródło
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"/>
G_V
źródło
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);
damaxxed
źródło
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;
        }
    }
}
havexz
źródło
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;
}
Dave Haines
źródło
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);
bapjg
źródło
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"/>
eckc
źródło
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) {
  }
});
user4215456
źródło
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


ceph3us
źródło
0

Kod roboczy Programowo:

mp.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);

XML:

android:descendantFocusability="blocksDescendants" 
Vinayak
źródło