Empêcher EditText de se concentrer au démarrage de L'activité
j'ai un Activity
dans Android, avec deux éléments:
-
EditText
-
ListView
quand mon Activity
commence, le EditText
a immédiatement le focus d'entrée (curseur clignotant). Je ne veux pas de contrôle au démarrage. J'ai essayé:
EditText.setSelected(false);
pas de chance. Comment puis-je convaincre le EditText
de ne pas se Activity
commence?
30 réponses
excellentes réponses de Luc et Mark cependant, il manque un bon échantillon de code. Ajouter l'étiquette 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"/>
est le vrai problème que vous ne voulez pas qu'il se concentre du tout? Ou vous ne voulez pas afficher le clavier virtuel comme un résultat de concentrer la EditText
? Je ne vois pas vraiment de problème avec le EditText
qui se concentre sur le démarrage, mais c'est certainement un problème d'avoir la fenêtre softInput ouverte quand l'utilisateur n'a pas explicitement demandé de se concentrer sur le EditText
(et d'ouvrir le clavier en conséquence).
Si c'est le problème du clavier virtuel, voir le AndroidManifest.xml
android:windowSoftInputMode="stateHidden"
- toujours le cacher en entrant dans l'activité.
ou android:windowSoftInputMode="stateUnchanged"
- ne le modifiez pas (par exemple, ne montrez pas si elle n'est pas déjà affichée, mais si elle était ouverte au moment d'entrer dans l'activité, laissez-la Ouverte).
une solution plus simple existe. Définissez ces attributs dans la mise en page de votre parent:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mainLayout"
android:descendantFocusability="beforeDescendants"
android:focusableInTouchMode="true" >
et maintenant, lorsque l'activité commence, cette mise en page principale sera mise au point par défaut.
aussi, nous pouvons supprimer le focus des vues des enfants à l'exécution (par exemple, après avoir terminé l'édition enfant) en donnant le focus à la mise en page principale à nouveau, comme ceci:
findViewById(R.id.mainLayout).requestFocus();
bon commentaire de Guillaume Perrot :
android:descendantFocusability="beforeDescendants"
semble être le par défaut (valeur entière de 0). Cela fonctionne juste en ajoutantandroid:focusableInTouchMode="true"
.
Vraiment, nous pouvons voir que le beforeDescendants
définir comme défaut dans le ViewGroup.initViewGroup()
méthode (Android 2.2.2). Mais pas égal à 0. ViewGroup.FOCUS_BEFORE_DESCENDANTS = 0x20000;
merci à Guillaume.
la seule solution que j'ai trouvée est:
- Créer un LinearLayout (je ne sais pas si d'autres types de Mise en page du travail)
- définit les attributs
android:focusable="true"
etandroid:focusableInTouchMode="true"
Et le EditText
ne sera pas obtenir le focus après le démarrage de l'activité
le problème semble provenir d'une propriété que je ne vois que dans le XML form
du layout.
assurez-vous de supprimer cette ligne à la fin de la déclaration dans les balises XML EditText
:
<requestFocus />
qui 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>
en utilisant les informations fournies par d'autres posters, j'ai utilisé la solution suivante:
dans le schéma de configuration 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();
}
ce qui suit empêchera edittext de se focaliser lors de sa création, mais l'attrapera quand vous les toucherez.
<EditText
android:id="@+id/et_bonus_custom"
android:focusable="false" />
ainsi vous définissez Focus À false dans le xml, mais la clé est dans le java, que vous ajoutez l'auditeur 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 mise au point se déroulera comme d'habitude.
Essayer clearFocus() au lieu de setSelected(false)
. Chaque vue sur Android est à la fois focalisable et sélectionnable, et je pense que vous voulez juste clarifier la mise au point.
j'avais essayé plusieurs réponses individuellement, mais l'accent est toujours mis à l'EditText. J'ai seulement réussi à le résoudre en utilisant deux de la solution 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 L'Argent https://stackoverflow.com/a/8639921/15695 )
et supprimer
<requestFocus />
at EditText
(référence de floydaddict https://stackoverflow.com/a/9681809 )
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>
solution Simple:
Dans AndroidManifest
dans Activity
utilisation de la balise
android:windowSoftInputMode="stateAlwaysHidden"
vous pouvez simplement définir " focalisable " et " focalisable en mode touch " pour évaluer true sur le premier TextView
du layout
. De cette façon , lorsque l'activité commencera, le TextView
sera concentré mais ,en raison de sa nature, vous ne verrez rien concentré sur l'écran et, bien sûr, il y aura Non clavier affiché...
La travaillé pour moi dans Manifest
. Ecris,
<activity
android:name=".MyActivity"
android:windowSoftInputMode="stateAlwaysHidden"/>
il fallait que je me concentre sur tous les domaines de façon programmatique. Je viens d'ajouter les deux énoncés suivants à ma définition de la mise en page principale.
myLayout.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
myLayout.setFocusableInTouchMode(true);
C'est ça. Fixe mon problème instantanément. Merci, Silver, de m'avoir montré la bonne direction.
réponse la plus simple, il suffit d'ajouter ceci dans la mise en page parent du XML.
android:focusable="true"
android:focusableInTouchMode="true"
si vous avez un autre point de vue sur votre activité comme un ListView
, vous pouvez aussi faire:
ListView.requestFocus();
dans votre onResume()
pour saisir la mise au point du editText
.
je sais que cette question a été répondu, mais juste en fournissant une solution alternative qui a fonctionné pour moi:)
essayez ceci avant votre premier champ modifiable:
<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();
ajouter ce qui suit dans onCreate
méthode:
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
étant donné que je n'aime pas polluer le XML avec quelque chose qui est lié à la fonctionnalité, j'ai créé cette méthode qui vole" de façon transparente " la mise au point de la première vue focalisable et s'assure ensuite de se retirer lorsque 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;
}
en retard, mais peut-être utile. Créez un faux texte D'édition en haut de votre mise en page puis appelez myDummyEditText.requestFocus()
dans onCreate()
<EditText android:id="@+id/dummyEditTextFocus"
android:layout_width="0px"
android:layout_height="0px" />
Qui semble se comporter comme prévu. Pas besoin de gérer les changements de configuration, etc. J'en avais besoin pour une activité avec un long TextView (instructions).
Oui j'ai fait la même chose-créer une disposition linéaire "factice" qui obtient la mise au point initiale. De plus, j'ai configuré les ID' next 'focus pour que l'utilisateur ne puisse plus se concentrer 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
écrivez cette ligne dans la mise en page de votre Parent...
android:focusableInTouchMode="true"
pour moi, ce qui a fonctionné sur tous les appareils est ceci:
<!-- 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" />
mettez juste ceci comme une vue avant la vue focalisée problématique, et c'est tout.
la chose la plus simple que j'ai faite est de mettre l'accent sur un autre point de vue dans onCreate:
myView.setFocusableInTouchMode(true);
myView.requestFocus();
cela a stoppé le clavier mou à venir et il n'y avait pas de curseur clignotant dans L'EditText.
écrivez ce code à l'intérieur du fichier Manifest
dans le fichier 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>
<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"/>
à onCreate
de votre activité, ajoutez simplement clearFocus()
à votre élément EditText.
Par exemple,
edittext = (EditText) findViewById(R.id.edittext);
edittext.clearFocus();
Et si vous voulez détourner le focus à un autre élément, utilisez requestFocus()
.
Par exemple,
button = (Button) findViewById(R.id.button);
button.requestFocus();
vous pouvez y parvenir en créant un mannequin EditText
avec la largeur de disposition et la hauteur définie à 0dp
, et demander la mise au point de cette vue.
Ajouter 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>