web-dev-qa-db-fra.com

Comment supprimer le focus sans définir le focus sur un autre contrôle?

J'aime que mes interfaces utilisateur soient intuitives; chaque écran doit naturellement guider l'utilisateur vers l'étape suivante de l'application. À part cela, je m'efforce de rendre les choses aussi déroutantes que possible.

Je rigole :-)

J'ai trois TableRows, chacun contenant un contrôle EditText en lecture seule et non activable, puis un bouton à sa droite. Chaque bouton lance la même activité mais avec un argument différent. L'utilisateur fait une sélection à cet endroit et la sous-activité se termine, en renseignant la variable EditText appropriée avec la sélection de l'utilisateur.

C'est le mécanisme classique des valeurs en cascade; chaque sélection réduit les options disponibles pour la sélection suivante, etc. Ainsi, je désactive les deux contrôles sur chacune des lignes suivantes jusqu'à ce que le texte d'édition de la ligne actuelle contienne une valeur.

Je dois faire l'une des deux choses, dans cet ordre de préférence:

  1. Lorsque vous cliquez sur un bouton, supprimez immédiatement le focus sans définir le focus sur un autre bouton.
  2. Définir le focus sur le premier bouton lorsque l'activité commence

Le problème se manifeste après le retour de la sous-activité; le bouton sur lequel vous avez cliqué conserve le focus.

Re: # 1 ci-dessus - Il ne semble pas y avoir de méthode removeFocus(), ni quelque chose de similaire.

Re: # 2 ci-dessus - je peux utiliser requestFocus() pour définir le bouton sur la touche de la rangée suivante, et cela fonctionne après le retour de la sous-activité, mais pour une raison quelconque, cela ne fonctionne pas dans la fonction onCreate() de l'activité parent.

J'ai besoin de la cohérence de l'interface utilisateur dans un sens ou dans l'autre - aucun bouton n'est actif une fois la sous-activité terminée ou chaque bouton reçoit le focus en fonction de sa place dans le flux logique, y compris le premier (et le seul) bouton actif avant toute sélection.

76
InteXX

L'utilisation de clearFocus () ne semble pas fonctionner pour moi non plus, comme vous l'avez constaté (voir dans les commentaires d'une autre réponse), mais ce qui a bien fonctionné pour moi a été d'ajouter: 

<LinearLayout 
    Android:id="@+id/my_layout" 
    Android:focusable="true" 
    Android:focusableInTouchMode="true" ...>

à mon très haut niveau Layout View (une mise en page linéaire). Pour supprimer le focus de tous les boutons/EditTexts, etc., vous pouvez simplement faire

LinearLayout myLayout = (LinearLayout) activity.findViewById(R.id.my_layout);
myLayout.requestFocus();

Demander la mise au point n'a rien fait, sauf si je règle la vue pour qu'elle puisse être mise au point.

155
actionshrimp

Vieille question, mais je l’ai trouvée quand j’avais eu un problème similaire et je pensais partager ce que j’ai finalement fait. 

La vue qui gagnait l’attention était différente à chaque fois, j’ai donc utilisé le très générique:

View current = getCurrentFocus();
if (current != null) current.clearFocus();
69
willlma
  1. Vous pouvez utiliser View.clearFocus().

  2. Utilisez View.requestFocus() appelé à partir de onResume().

8
siliconeagle
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
          xmlns:app="http://schemas.Android.com/apk/res-auto"
          Android:id="@+id/ll_root_view"
          Android:layout_width="match_parent"
          Android:layout_height="match_parent"
          Android:orientation="vertical">

LinearLayout llRootView = findViewBindId(R.id.ll_root_view);
llRootView.clearFocus();

J'utilise ceci lorsque j'ai déjà fini de mettre à jour les informations de profil et de supprimer tout le focus de EditText dans ma mise en page

====> Mise à jour: dans le contenu de la présentation parent, ma ligne d’ajout EditText:

Android:focusableInTouchMode="true"
5
Ho Luong

Pourquoi ne pas ajouter Android:windowSoftInputMode="stateHidden" à votre activité dans le manifeste? 

Extrait d'un homme intelligent commentant ceci: https://stackoverflow.com/a/2059394/956975

3
marienke

J'ai essayé de désactiver et d'activer la mise au point pour l'affichage et cela a fonctionné pour moi (la mise au point a été réinitialisée):

focusedView.setFocusable(false);
focusedView.setFocusableInTouchMode(false);
focusedView.setFocusable(true);
focusedView.setFocusableInTouchMode(true);
2
Serhiy

Android:descendantFocusability="beforeDescendants"

l'utilisation de ce qui suit dans l'activité avec certaines options de mise en page ci-dessous semble fonctionner comme vous le souhaitez.

 getWindow().getDecorView().findViewById(Android.R.id.content).clearFocus();

en relation avec les paramètres suivants de la vue racine.

<?xml
    Android:focusable="true"
    Android:focusableInTouchMode="true"
    Android:descendantFocusability="beforeDescendants" />

https://developer.Android.com/reference/Android/view/ViewGroup#attr_Android:descendantFocusability

Répondez grâce à: https://forums.xamarin.com/discussion/1856/how-to-disable-auto-focus-on-edit-text

À propos de windowSoftInputMode

Il y a encore un autre point de discorde dont il faut être conscient. Par défaut, Android assignera automatiquement le focus initial au premier EditText ou un contrôle focalisable dans votre activité. Il s'ensuit naturellement que le InputMethod (généralement le clavier logiciel) répondra au focus événement en se montrant. L'attribut windowSoftInputMode dans AndroidManifest.xml, lorsqu'il est défini sur stateAlwaysHidden, indique au clavier pour ignorer ce focus initial attribué automatiquement.

<activity
    Android:name=".MyActivity"
    Android:windowSoftInputMode="stateAlwaysHidden"/>

excellente référence

2
CrandellWS

Tout d'abord, cela fonctionnera à 100% ........

  1. Créer la méthode onResume().
  2. Dans cette onResume(), trouvez la vue qui fait l'objet d'une mise au point constante par findViewById().
  3. Dans cette onResume(), définissez requestFocus() sur cette vue.
  4. Dans cette onResume(), définissez clearFocus sur cette vue.
  5. Allez au format xml de la même présentation et trouvez la vue de dessus sur laquelle vous voulez vous concentrer et définissez focusable true et focusableInTuch true.
  6. Dans cette onResume(), trouvez la vue de dessus ci-dessus par findViewById 
  7. Dans cette onResume(), définissez requestFocus() sur la dernière vue.
  8. Et maintenant profitez de ......
2
vishambar pandey

Vous pouvez essayer de désactiver la capacité de l'activité principale à enregistrer son état (lui faisant ainsi oublier quel contrôle avait le texte et ce qui avait le focus). Vous aurez besoin d'une autre manière de vous souvenir de ce que vos EditText ont et de les repeupler onResume (). Lancez vos sous-activités avec startActivityForResult () et créez un gestionnaire onActivityResult () dans votre activité principale pour mettre à jour correctement le texte d'édition. De cette façon, vous pouvez définir le bon bouton sur lequel vous souhaitez vous concentrer tout en repeuplant le EditText en utilisant un myButton.post (new Runnable () {run () {my {{{}}} (};}});

La méthode View.post () est utile pour définir le focus initialement car cet exécutable sera exécuté après la création de la fenêtre et le rétablissement de la situation, permettant ainsi au mécanisme de focus de fonctionner correctement à ce moment-là. Essayer de définir le focus au cours de onCreate/Start/Resume () a généralement des problèmes, j'ai trouvé.

Veuillez noter que ceci est pseudo-code et non testé, mais c'est une direction possible que vous pouvez essayer.

1
Uncle Code Monkey

Essayez ce qui suit (appelez clearAllEditTextFocuses();)

private final boolean clearAllEditTextFocuses() {
    View v = getCurrentFocus();
    if(v instanceof EditText) {
        final FocusedEditTextItems list = new FocusedEditTextItems();
        list.addAndClearFocus((EditText) v);

        //Focus von allen EditTexten entfernen
        boolean repeat = true;
        do {
            v = getCurrentFocus();
            if(v instanceof EditText) {
                if(list.containsView(v))
                    repeat = false;
                else list.addAndClearFocus((EditText) v);
            } else repeat = false;
        } while(repeat);

        final boolean result = !(v instanceof EditText);
        //Focus wieder setzen
        list.reset();
        return result;
    } else return false;
}

private final static class FocusedEditTextItem {

    private final boolean focusable;

    private final boolean focusableInTouchMode;

    @NonNull
    private final EditText editText;

    private FocusedEditTextItem(final @NonNull EditText v) {
        editText = v;
        focusable = v.isFocusable();
        focusableInTouchMode = v.isFocusableInTouchMode();
    }

    private final void clearFocus() {
        if(focusable)
            editText.setFocusable(false);
        if(focusableInTouchMode)
            editText.setFocusableInTouchMode(false);
        editText.clearFocus();
    }

    private final void reset() {
        if(focusable)
            editText.setFocusable(true);
        if(focusableInTouchMode)
            editText.setFocusableInTouchMode(true);
    }

}

private final static class FocusedEditTextItems extends ArrayList<FocusedEditTextItem> {

    private final void addAndClearFocus(final @NonNull EditText v) {
        final FocusedEditTextItem item = new FocusedEditTextItem(v);
        add(item);
        item.clearFocus();
    }

    private final boolean containsView(final @NonNull View v) {
        boolean result = false;
        for(FocusedEditTextItem item: this) {
            if(item.editText == v) {
                result = true;
                break;
            }
        }
        return result;
    }

    private final void reset() {
        for(FocusedEditTextItem item: this)
            item.reset();
    }

}
0
user2830808
Android:focusableInTouchMode="true"
Android:focusable="true"
Android:clickable="true"

Ajoutez-les à votre ViewGroup qui inclut votre EditTextView . Il fonctionne correctement dans ma présentation de contrainte J'espère que cette aide

0
Tánh Lee