Disabilita la tastiera virtuale su NumberPicker


168

Sto cercando di disattivare la tastiera software quando si utilizza un NumberPicker per immettere valori numerici (per motivi estetici). Questo è il mio 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>

E infine questo è il codice in cui provo a bloccare la tastiera nel metodo 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); 

Purtroppo, la tastiera virtuale viene comunque visualizzata quando si fa clic su un NumberPicker. Qualche idea?

Risposte:


475

Ho appena trovato questo e funziona come un fascino:

myNumberPicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);

Puoi anche impostare questo in XML:

android:descendantFocusability="blocksDescendants" 

1
A meno che non mi manchi qualcosa, questo rimuove la possibilità di digitare un valore per NumberPicker. Non è necessariamente una cosa negativa, a seconda di come stai usando il selettore, ma sembra essere una limitazione della soluzione.
Frenziedherring,

76
Puoi anche impostarlo in XML: android: descendantFocusability = "blocksDescendants"
Ben Clayton,

1
Aaah, blocchiDendendes, naturalmente. Grazie mille :)
Lev

Soluzione incredibile, mi ha salvato!
Hamzeh Soboh

56

Versione XML della risposta di Andrew Webber

android:descendantFocusability="blocksDescendants"

Esempio

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

7

Dopo aver letto il codice sorgente com / android / internal / widget / NumberPicker.java sono arrivato alla seguente soluzione:

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

Sì, ho dovuto modificare direttamente le viste figlio di NumberPicker. L'API Android a volte è molto scarsa.
damaxxed

6

Ho appena migliorato la risposta di @MaxVogler (quindi se non voterai anche questo voto su @MaxVogler) e lo trasformerai in un solido hack. Inoltre non abbiamo bisogno di chiamare setOnFocusChangeListenere setInputType. SolosetFocusable farà falso.

Di seguito è riportato un aiutante api per abilitare / disabilitare la funzione

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

Ecco un altro modo per farlo che consente all'utente di modificare ancora un numero se lo desidera: inizialmente elimina solo la tastiera virtuale. Utilizzare NumberPicker.setDescendantFocusability(FOCUS_BLOCK_DESCENDANTS)per sopprimere la tastiera virtuale quando l'interfaccia viene visualizzata per la prima volta secondo le risposte precedenti. Quindi porta la tua finestra di dialogo o attività da implementare View.OnTouchListener, chiama setOnTouchListener(this)il tuo NumberPicker, e nella tua implementazione di onTouch(View v,MotionEvent e)ripristina la focalizzazione del discendente numeratore al suo valore normale, quindi restituisci false.

Restituire false significa che il tocco è ancora elaborato da NumberPicker, il che significa che se l'utente tocca la casella di modifica viene visualizzata la tastiera virtuale. Questo sembra essere esattamente quello che volevo affrontare lo stesso problema: avere la tastiera virtuale con la finestra di dialogo quando mostra per la prima volta è spiacevole mentre sposta la finestra di dialogo dopo che appare.

public class GetBufferDialog extends DialogFragment implements View.OnTouchListener {

dopo aver creato la finestra di dialogo nel onCreateDialog()metodo e aver trovato NumberPicker:

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

ed ecco il metodo OnTouch:

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

1
solo questo mi ha aiutato a risolvere il mio problema, grazie per il tuo approccio
smoothumut

2

Il più semplice che ho trovato a lavorare era:

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

2

Se si desidera nascondere la tastiera del software solo quando si carica la vista con il selettore numeri, ma si desidera comunque che gli utenti siano in grado di modificare dopo il caricamento della vista, non è necessario bloccare la focalizzazione discendente. Invece, evita semplicemente che il selettore numeri sia il primo elemento attivo nella tua vista.

Vedi questa risposta per i dettagli.

Sulla base della risposta sopra:

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

Non so perché funzioni, ma l'impostazione di OnClickListener che non fa nulla impedisce la visualizzazione della tastiera (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();
        }
    }
}

* chiamando questo:

  • non bloccherà la focalizzazione del discendente (il numeratore sarà modificabile)

  • nasconderà l'input morbido al momento della creazione

  • prima (elaborazione dell'input) getValue () consentirà di ottenere una corretta walue



0

Codice di lavoro programmaticamente :

mp.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);

XML:

android:descendantFocusability="blocksDescendants" 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.