web-dev-qa-db-fra.com

Empêcher EditText de se concentrer au démarrage de l'activité

J'ai une Activity dans Android, avec deux éléments:

  1. EditText 
  2. ListView

Lorsque ma Activity démarre, la EditText est immédiatement activée (curseur clignotant). Je ne veux pas qu'un contrôle ait le focus d'entrée au démarrage. J'ai essayé:

EditText.setSelected(false);

Pas de chance. Comment puis-je convaincre la EditText de ne pas se sélectionner elle-même lorsque la Activity commence?

2581
Mark

Excellentes réponses de Luc et Mark, mais il manque un bon échantillon de code. Ajouter la balise Android:focusableInTouchMode="true" à <LinearLayout> comme dans l'exemple suivant résoudra le problème.

<!-- Dummy item to prevent AutoCompleteTextView 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 -->
<AutoCompleteTextView Android:id="@+id/autotext"
    Android:layout_width="fill_parent" 
    Android:layout_height="wrap_content"
    Android:nextFocusUp="@id/autotext" 
    Android:nextFocusLeft="@id/autotext"/>
2265

Le problème actuel est-il que vous ne voulez pas qu'il soit concentré du tout? Ou vous ne voulez pas que le clavier virtuel apparaisse suite à la focalisation de la variable EditText? Je ne vois pas vraiment d'inconvénient à ce que EditText se concentre sur le démarrage, mais il est certainement problématique que la fenêtre softInput soit ouverte lorsque l'utilisateur ne demande pas explicitement à se concentrer sur la EditText (et ouvre le clavier en conséquence).

Si c'est le problème du clavier virtuel, consultez la documentation AndroidManifest.xml<activity> } _.

Android:windowSoftInputMode="stateHidden" - le cache toujours en entrant dans l'activité.

ou Android:windowSoftInputMode="stateUnchanged" - ne le modifiez pas (par exemple, ne show pas s'il n'est pas déjà affiché, mais s'il était ouvert lors de la saisie de l'activité, laissez-le ouvert).

1605
Joe

Une solution plus simple existe. Définissez ces attributs dans votre mise en page parent:

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/mainLayout"
    Android:descendantFocusability="beforeDescendants"
    Android:focusableInTouchMode="true" >

Et maintenant, quand l'activité commence, cette disposition principale aura le focus par défaut.

En outre, nous pouvons supprimer le focus des vues enfant au moment de l'exécution (par exemple, une fois la modification de l'enfant terminée) en redonnant le focus à la présentation principale, comme suit:

findViewById(R.id.mainLayout).requestFocus();

Bon commentaire de Guillaume Perrot :

Android:descendantFocusability="beforeDescendants" semble être le défaut (la valeur entière est 0). Cela fonctionne simplement en ajoutant Android:focusableInTouchMode="true".

Vraiment, nous pouvons voir que la variable beforeDescendants est définie par défaut dans la méthode ViewGroup.initViewGroup() (Android 2.2.2). Mais pas égal à 0. ViewGroup.FOCUS_BEFORE_DESCENDANTS = 0x20000;

Merci à Guillaume.

1060
Silver

La seule solution que j'ai trouvée est:

  • Créer un LinearLayout (Je ne sais pas si d'autres types de Layout fonctionneront)
  • Définissez les attributs Android:focusable="true" et Android:focusableInTouchMode="true"

Et la EditText n'aura pas le focus après le début de l'activité

403
Luc

Le problème semble provenir d'une propriété que je ne peux voir que dans le XML form de la présentation.

Assurez-vous de supprimer cette ligne à la fin de la déclaration dans les balises XML EditText:

<requestFocus />

Cela devrait donner quelque chose comme ça:

<EditText
   Android:id="@+id/emailField"
   Android:layout_width="fill_parent"
   Android:layout_height="wrap_content"
   Android:inputType="textEmailAddress">

   //<requestFocus /> /* <-- without this line */
</EditText>
73
floydaddict

en utilisant les informations fournies par d'autres affiches, j'ai utilisé la solution suivante:

dans la mise en page XML

<!-- Dummy item to prevent AutoCompleteTextView from receiving focus -->
<LinearLayout
    Android:id="@+id/linearLayout_focus"
    Android:focusable="true"
    Android:focusableInTouchMode="true"
    Android:layout_width="0px"
    Android:layout_height="0px"/>

<!-- AUTOCOMPLETE -->
<AutoCompleteTextView
    Android:id="@+id/autocomplete"
    Android:layout_width="200dip"
    Android:layout_height="wrap_content"
    Android:layout_marginTop="20dip"
    Android:inputType="textNoSuggestions|textVisiblePassword"/>

dans onCreate ()

private AutoCompleteTextView mAutoCompleteTextView;
private LinearLayout mLinearLayout;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.mylayout);

    //get references to UI components
    mAutoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.autocomplete);
    mLinearLayout = (LinearLayout) findViewById(R.id.linearLayout_focus);
}

et enfin, dans onResume ()

@Override
protected void onResume() {
    super.onResume();

    //do not give the editbox focus automatically when activity starts
    mAutoCompleteTextView.clearFocus();
    mLinearLayout.requestFocus();
}
67

Essayez clearFocus () au lieu de setSelected(false). Chaque vue dans Android a la focalisation et la sélection, et je pense que vous voulez effacer le focus.

63
Konklone

Ce qui suit empêchera edittext de prendre le focus lors de sa création, mais le saisira lorsque vous les toucherez.

<EditText
    Android:id="@+id/et_bonus_custom"
    Android:focusable="false" />

Donc, vous définissez focusable sur false dans le xml, mais la clé est dans Java, vous ajoutez l'écouteur suivant:

etBonus.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        v.setFocusable(true);
        v.setFocusableInTouchMode(true);
        return false;
    }
});

Parce que vous retournez false, c'est-à-dire que vous ne consommez pas l'événement, le comportement de la mise au point se déroulera normalement.

63
MinceMan

J'avais essayé plusieurs réponses individuellement mais l'accent est toujours sur EditText. J'ai seulement réussi à le résoudre en utilisant deux des solutions ci-dessous ensemble.

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
  Android:id="@+id/mainLayout"
  Android:descendantFocusability="beforeDescendants"
  Android:focusableInTouchMode="true" >

(Référence de Silver https://stackoverflow.com/a/8639921/15695 )

et enlever

 <requestFocus />

à EditText 

(Référence de floydaddict https://stackoverflow.com/a/9681809 )

50
Lee Yi Hong

Aucune de ces solutions n'a fonctionné pour moi. La façon dont je corrige l'autofocus était:

<activity Android:name=".Android.InviteFriendsActivity" Android:windowSoftInputMode="adjustPan">
    <intent-filter >
    </intent-filter>
</activity>
40
rallat

Solution simple: Dans AndroidManifest dans Activity balise

Android:windowSoftInputMode="stateAlwaysHidden"
37
Sergey Sheleg

Vous pouvez simplement définir "focusable" et "focusable en mode tactile" sur la valeur true pour la première TextView de la layout. De cette façon, lorsque l'activité commencera, la TextView sera centrée mais, en raison de sa nature, rien ne sera concentré sur l'écran et, bien sûr, il y aura non clavier affiché ...

32
Zeus

Ce qui suit a fonctionné pour moi dans Manifest. Écrire ,

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

La réponse la plus simple, ajoutez simplement ceci dans la mise en page parent du XML.

Android:focusable="true" 
Android:focusableInTouchMode="true"
28
Rishabh Saxena

Je devais effacer le focus de tous les domaines par programmation. Je viens d'ajouter les deux déclarations suivantes à la définition de ma mise en page principale.

myLayout.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
myLayout.setFocusableInTouchMode(true);

C'est tout. Correction de mon problème instantanément. Merci Silver pour m'avoir orienté dans la bonne direction.

26
jakeneff

Ajoutez Android:windowSoftInputMode="stateAlwaysHidden" dans la balise d'activité du fichier Manifest.xml.

La source

24
prgmrDev

Si vous avez une autre vue de votre activité comme une ListView, vous pouvez aussi faire:

ListView.requestFocus(); 

dans votre onResume() pour obtenir le focus de la editText.

Je sais que cette question a été résolue mais fournit juste une solution alternative qui a fonctionné pour moi :)

19
Sid

Essayez ceci avant votre premier champ éditable:

<TextView  
        Android:id="@+id/dummyfocus" 
        Android:layout_width="fill_parent"
        Android:layout_height="wrap_content" 
        Android:text="@string/foo"
        />

----

findViewById(R.id.dummyfocus).setFocusableInTouchMode(true);
findViewById(R.id.dummyfocus).requestFocus();
18
Jack Slater

Ajoutez ce qui suit dans la méthode onCreate:

this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
18
Vishal Raj

Etant donné que je n'aime pas polluer le XML avec quelque chose lié aux fonctionnalités, j'ai créé cette méthode qui vole "de manière transparente" le focus de la première vue focalisable et s'assure ensuite de se supprimer si nécessaire!

public static View preventInitialFocus(final Activity activity)
{
    final ViewGroup content = (ViewGroup)activity.findViewById(Android.R.id.content);
    final View root = content.getChildAt(0);
    if (root == null) return null;
    final View focusDummy = new View(activity);
    final View.OnFocusChangeListener onFocusChangeListener = new View.OnFocusChangeListener()
    {
        @Override
        public void onFocusChange(View view, boolean b)
        {
            view.setOnFocusChangeListener(null);
            content.removeView(focusDummy);
        }
    };
    focusDummy.setFocusable(true);
    focusDummy.setFocusableInTouchMode(true);
    content.addView(focusDummy, 0, new LinearLayout.LayoutParams(0, 0));
    if (root instanceof ViewGroup)
    {
        final ViewGroup _root = (ViewGroup)root;
        for (int i = 1, children = _root.getChildCount(); i < children; i++)
        {
            final View child = _root.getChildAt(i);
            if (child.isFocusable() || child.isFocusableInTouchMode())
            {
                child.setOnFocusChangeListener(onFocusChangeListener);
                break;
            }
        }
    }
    else if (root.isFocusable() || root.isFocusableInTouchMode())
        root.setOnFocusChangeListener(onFocusChangeListener);

    return focusDummy;
}
14
Takhion

En retard, mais peut-être utile. Créez un EditText factice en haut de votre disposition, puis appelez myDummyEditText.requestFocus() dans onCreate().

<EditText Android:id="@+id/dummyEditTextFocus" 
Android:layout_width="0px"
Android:layout_height="0px" />

Cela semble se comporter comme je l'espère. Pas besoin de gérer les changements de configuration, etc. J'avais besoin de cela pour une activité avec un long TextView (instructions).

13
Jim

Écrivez cette ligne dans votre mise en page parent ...

 Android:focusableInTouchMode="true"
12
Vishal Vaishnav

Oui, j'ai fait la même chose: créer une mise en page linéaire factice qui obtienne le focus initial. De plus, j'ai défini les identifiants de focus suivants pour que l'utilisateur ne puisse plus le focaliser après avoir fait défiler une fois:

<LinearLayout 'dummy'>
<EditText et>

dummy.setNextFocusDownId(et.getId());

dummy.setNextFocusUpId(et.getId());

et.setNextFocusUpId(et.getId());

beaucoup de travail juste pour se débarrasser de l'accent sur une vue .. 

Merci

12
mark

Pour moi, ce qui a fonctionné sur tous les appareils est le suivant:

    <!-- fake first focusable view, to allow stealing the focus to itself when clearing the focus from others -->

    <View
    Android:layout_width="0px"
    Android:layout_height="0px"
    Android:focusable="true"
    Android:focusableInTouchMode="true" />

Placez-le simplement comme une vue avant la vue problématique, et c'est tout.

10

C'est la solution parfaite et la plus simple. Je l'utilise toujours dans mon application. 

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
9
user4728480

La chose la plus simple que j'ai faite est de mettre l'accent sur une autre vue dans onCreate:

    myView.setFocusableInTouchMode(true);
    myView.requestFocus();

Cela a empêché le clavier logiciel d'apparaître et il n'y avait aucun curseur clignotant dans l'EditText.

8
Lumis
<TextView
    Android:id="@+id/TextView01"
    Android:layout_width="fill_parent"
    Android:layout_height="wrap_content"
    Android:layout_weight="1"
    Android:singleLine="true"
    Android:ellipsize="Marquee"
    Android:marqueeRepeatLimit="Marquee_forever"
    Android:focusable="true"
    Android:focusableInTouchMode="true"
    style="@Android:style/Widget.EditText"/>
7
atul

Ecrivez ce code dans le fichier Manifest dans la Activity où vous ne voulez pas ouvrir le clavier.

Android:windowSoftInputMode="stateHidden"

Fichier manifeste:

 <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
    package="com.example.projectt"
    Android:versionCode="1"
    Android:versionName="1.0" >

    <uses-sdk
        Android:minSdkVersion="8"
        Android:targetSdkVersion="24" />

    <application
        Android:allowBackup="true"
        Android:icon="@drawable/ic_launcher"
        Android:label="@string/app_name"
        Android:theme="@style/AppTheme" >
         <activity
            Android:name=".Splash"
            Android:label="@string/app_name" >
            <intent-filter>
                <action Android:name="Android.intent.action.MAIN" />

                <category Android:name="Android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            Android:name=".Login"
            **Android:windowSoftInputMode="stateHidden"**
            Android:label="@string/app_name" >
        </activity>

    </application>

</manifest>
7
Tarit Ray

À onCreate de votre activité, ajoutez simplement use clearFocus() sur votre élément EditText . Par exemple,

edittext = (EditText) findViewById(R.id.edittext);
edittext.clearFocus();

Et si vous souhaitez détourner le focus vers un autre élément, utilisez requestFocus() sur celui-ci . Par exemple,

button = (Button) findViewById(R.id.button);
button.requestFocus();
6
Compaq LE2202x

Le moyen le plus simple de masquer le clavier est d'utiliser setSoftInputMode 

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

ou vous pouvez utiliser InputMethodManager et masquer le clavier de cette manière.

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(myEditText.getWindowToken(), 0);
6
Anonymous

Lorsque votre activité est ouverte, le clavier devient automatiquement visible, ce qui provoque la mise au point de EditText. Vous pouvez désactiver le clavier en écrivant la ligne suivante dans votre balise d'activité dans le fichier manifest.xml.

 Android:windowSoftInputMode="stateAlwaysHidden|adjustPan"
6
Mansuu....

Vous pouvez y parvenir en créant une variable EditText avec une largeur et une hauteur de mise en page définies sur 0dp et en demandant au focus de l'afficher . Ajoutez l'extrait de code suivant dans votre mise en page XML:

<EditText
    Android:id="@+id/editText0"
    Android:layout_width="0dp"
    Android:layout_height="0dp"
    Android:hint="@string/dummy"
    Android:ems="10" 
    >
     <requestFocus />
    </EditText>
6
Ish

Assurez-vous de supprimer la ligne "<requestFocus />" de la balise EditText au format xml.

<EditText
   Android:id="@+id/input"
   Android:layout_width="fill_parent"
   Android:layout_height="wrap_content">

   <requestFocus /> <!-- remove this line --> 
</EditText>
6

J'utilise le code suivant pour empêcher un EditText de voler le focus lorsque mon bouton est enfoncé.

addButton.setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
        View focused = internalWrapper.getFocusedChild();
        focused.setVisibility(GONE);
        v.requestFocus();
        addPanel();
        focused.setVisibility(VISIBLE);
    }
});

De manière générale, masquez le texte à modifier, puis affichez-le à nouveau. Cela fonctionne pour moi car le EditText est not in view, donc peu importe qu'il soit affiché ou non.

Vous pouvez essayer de vous cacher et de le montrer successivement pour voir si cela l'aide à perdre la concentration.

5
drei01
/** 
 * set focus to top level window
 * disposes descendant focus 
 * disposes softInput 
 * */
public static void topLevelFocus(Context context){
    if(Activity.class.isAssignableFrom(context.getClass())){
        ViewGroup tlView = (ViewGroup) ((Activity) context).getWindow().getDecorView();
        if(tlView!=null){
            tlView.setFocusable(true);
            tlView.setFocusableInTouchMode(true);
            tlView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
        }
    }
}
4
ceph3us
View current = getCurrentFocus();

if (current != null) 
    current.clearFocus();
4
DkPathak

Le moyen le plus simple consiste à ajouter Android:windowSoftInputMode="stateAlwaysHidden" dans la balise d'activité du fichier Manifest.xml file.

3
Karthik

EditText au sein d'une ListView ne fonctionne pas correctement. Il est préférable d'utiliser TableLayout avec des lignes générées automatiquement lorsque vous utilisez EditText.

3
MSIslam

essayer

edit.setInputType(InputType.TYPE_NULL);

edit.setEnabled(false);
3
Albert Oclarit

J'ai eu un problème comme celui-ci et c'était dû à mon sélecteur. Le premier état était le focus, même si, à mon avis, il était désactivé. vous pouvez définir le premier état sur désactivé comme ceci:

<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">


<item Android:drawable="@drawable/text_field_disabled" Android:state_enabled="false"/>
<item Android:drawable="@drawable/text_field_focused" Android:state_focused="true"/>
<item Android:drawable="@drawable/text_field_normal"/>

2
j2emanue
<EditText
    Android:layout_width="match_parent"
    Android:layout_height="100dp"
    Android:id="@+id/etComments"
    Android:hint="Comments.."
    Android:textSize="14dp"

    Android:focusable="false"

    Android:textStyle="italic"/>
2

Désactivez-le dans onCreate ()

final KeyListener edtTxtMessageKeyListener = edtTxtMessage.getKeyListener();
edtTxtMessage.setCursorVisible(false);
edtTxtMessage.setKeyListener(null);

Et enfin l'activer dans onClick () de EditText

edtTxtMessage.setCursorVisible(true);
edtTxtMessage.setKeyListener(edtTxtMessageKeyListener);

Mais le problème est que nous devons cliquer sur twise pour amener OnScreenKeyboard pour la première fois.

@Solution de contournement

InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);

Essayez aussi dans onClick () :)

2
Amit Yadav

Vous pouvez spécifier le focus sur un autre widget en utilisant le focus sur les requêtes et le code de masquage du clavier.

2
Mary's

remove<requestFocus /> de votre texte d'édition en fichier xml

<EditText
   Android:id="@+id/emailField"
   Android:layout_width="fill_parent"
   Android:layout_height="wrap_content"
   Android:inputType="textEmailAddress">

   //`<requestFocus />` /* <-- remove this tags */
</EditText>`
2
Akshay Paliwal

Faites ceci et faites votre travail!

Android:focusable="true"
Android:focusableInTouchMode="true" 
2
Tulsi

Vous avez éditer le texte et la liste. Dans OnStart/On Create, vous devez définir le focus sur la vue liste: Listview.requestfocus()

1
hassan mirza

Si vous souhaitez masquer le clavier au début de l'activité. Puis mention

Android: windowSoftInputMode = "stateHidden"

À cette activité dans le fichier manifeste. Le problème est résolu.

À votre santé.

0
Rohit Patil

J'efface tout le focus avec bouton d'envoi

// xml file
<LinearLayout
...
Android:id="@+id/linear_layout"
Android:focusableInTouchMode="true"> // 1. make this focusableInTouchMode...
</LinearLayout>

// Activity file
private LinearLayout mLinearLayout; // 2. parent layout element
private Button mButton;

mLinearLayout = findViewById(R.id.linear_layout);
mButton = findViewById(R.id.button);

  mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mLinearLayout.requestFocus(); // 3. request focus

            }
        });

J'espère que ceci vous aide :)

0
Bukunmi

ajouter la ligne ci-dessous dans le fichier manifeste où vous avez mentionné votre activité

Android:windowSoftInputMode="stateAlwaysHidden"
0
Akash Suresh Dandwate

Cela peut être réalisé en héritant de EditText et en remplaçant onTouchEvent.

class NonFocusableEditText: EditText {

    constructor(context: Context): super(context)
    constructor(context: Context, attrs: AttributeSet?): super(context, attrs)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int): super(context, attrs, defStyleAttr)

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        return if (isFocusable) super.onTouchEvent(event) else false
    }
}

Ensuite, vous pouvez l’utiliser dans les mises en page comme suit: EditText:

<com.yourpackage.NonFocusableEditText
        Android:id="@+id/editText"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"    
        Android:hint="@string/your_hint"
        Android:imeOptions="actionDone"
        Android:inputType="textNoSuggestions" />
0
mmBs