web-dev-qa-db-fra.com

Désactiver le clavier logiciel sur NumberPicker

J'essaie de désactiver le clavier logiciel lorsque j'utilise un NumberPicker pour saisir des valeurs numériques (pour des raisons esthétiques). Ceci est mon 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>

Et enfin c'est le code où j'essaie de bloquer le clavier dans la méthode 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); 

Malheureusement, le clavier logiciel apparaît toujours lorsque vous cliquez sur un NumberPicker. Des idées?

162
damaxxed

Je viens de trouver ceci et cela fonctionne comme un charme:

myNumberPicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);

Vous pouvez également définir ceci en XML:

Android:descendantFocusability="blocksDescendants" 
458
Andrew Webber

Version XML de la réponse d'Andrew Webber

Android:descendantFocusability="blocksDescendants"

Exemple

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

Après avoir lu le code source com/Android/internal/widget/NumberPicker.Java, je suis parvenu à la solution suivante:

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

Juste amélioré le @MaxVogler 's ans (donc si vous voulez voter ce vote aussi @MaxVogler) et en faire un hack robuste. Aussi, nous n’avons pas besoin d’appeler setOnFocusChangeListener et setInputType. Seul setFocusable à false suffira.

Ci-dessous se trouve une API pour activer/désactiver la fonctionnalité.

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

Voici une autre façon de le faire qui permet à l'utilisateur de toujours modifier un numéro s'il le souhaite: il supprime simplement le clavier virtuel initialement. Utilisez NumberPicker.setDescendantFocusability(FOCUS_BLOCK_DESCENDANTS) pour supprimer le clavier virtuel dès que l'interface s'affiche pour la première fois, conformément aux réponses ci-dessus. Ensuite, demandez à votre boîte de dialogue ou à votre activité d’implémenter View.OnTouchListener, Appelez setOnTouchListener(this) sur votre NumberPicker et, dans votre implémentation de onTouch(View v,MotionEvent e), réinitialisez la focalisation descendante du sélecteur de numéros à sa valeur normale, puis retourne false.

Renvoyer false signifie que le Touch est toujours traité par NumberPicker, ce qui signifie que si l'utilisateur appuie sur la zone d'édition, le clavier virtuel apparaît. C’est exactement ce que je voulais faire face au même problème: il est déplaisant d’avoir la boîte de dialogue ouverte lorsqu’elle s’affiche pour la première fois, ce qui la déplace vers le haut.

public class GetBufferDialog extends DialogFragment implements View.OnTouchListener {

après avoir créé le dialogue dans la méthode onCreateDialog() et trouvé le NumberPicker:

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

et voici la méthode OnTouch:

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

Si vous souhaitez uniquement masquer le clavier du logiciel lors du chargement de la vue avec votre sélecteur de numéros, mais que vous souhaitez tout de même que les utilisateurs puissent éditer après le chargement de la vue, vous ne devez pas bloquer la mise au point descendante. Empêchez simplement que le sélecteur de numéros soit le premier élément ciblé de votre vue.

Voir cette réponse pour plus de détails.

Basé sur la réponse ci-dessus:

    <!-- 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"/>
2
eckc

Le plus simple que j'ai trouvé pour travailler était:

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

Je ne sais pas pourquoi cela fonctionne, mais la définition de OnClickListener, qui ne fait rien, empêche l'affichage du clavier (Lollipop)

numberPicker.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View view) {
  }
});
1
user4215456
/**
 * 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();
        }
    }
}

* appelant ceci:

  • ne bloquera pas la focalisation des descendants (numberpicker sera éditable)

  • cachera une entrée douce lors de la création

  • avant (en traitant l’entrée) getValue () permettra d’obtenir la bonne valeur


0
ceph3us

Code de travail par programme:

mp.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);

XML:

Android:descendantFocusability="blocksDescendants" 
0
Vinayak