Come impedire a EditText di focalizzarsi all'avvio dell'attività in Android


2873

Ne ho uno Activityin Android, con due elementi:

  1. EditText
  2. ListView

Quando il mio Activityinizia, EditTextimmediatamente ha il focus di input (cursore lampeggiante). Non voglio alcun controllo che abbia lo stato attivo all'avvio. Provai:

EditText.setSelected(false);
EditText.setFocusable(false);

Senza fortuna. Come posso convincere EditTexta non selezionarsi quando si Activityavvia?

Risposte:


2593

Ottime risposte da Luc e Mark ma manca un buon esempio di codice. L'aggiunta del tag android:focusableInTouchMode="true"e android:focusable="true"al layout principale (ad es. LinearLayoutO ConstraintLayout) come nell'esempio seguente risolverà il problema.

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

711
Che dire dell'impostazione del layout principale su android:focusableInTouchMode="true"!
Muhammad Babar,

28
Perfetto! Grazie ... Una cosa da notare è che l'oggetto fittizio deve essere POSIZIONATO A DESTRA PRIMA dell'elemento focalizzabile !!! Ho avuto un TextView tra il mio manichino e EditText e il metodo non ha funzionato!
maddob,

25
impostazione android: focusableInTouchMode = "true" per il layout genitore è stato il buon approccio grazie a @Muhammad Babar
sujith s

7
Ottimo codice, mi ha aiutato molto :) Per provare a migliorarlo, android:focusableInTouchMode="true"copre android:focusable="true"+ un po 'di più, quindi in questo caso android:focusable="true"non è necessario e può essere rimosso. Inoltre, la vista fittizia può essere una vista anziché un layout lineare. Ciò consente di risparmiare potenza di elaborazione + di alcuni avvisi. Pertanto, la mia raccomandazione è di sostituire la vista fittizia con<View android:focusableInTouchMode="true" android:layout_width="0px" android:layout_height="0px"/>
Jacob R,

20
@PietroRea Android ha fastidiosi comportamenti di messa a fuoco automatica integrati nel comportamento principale della struttura dell'app. Se gli dici che un testo di modifica sta rilasciando o sta perdendo il focus, prende automaticamente la decisione su dove va il focus. Senza un nuovo oggetto su cui trasferire il focus, seleziona il primo elemento focalizzabile nel layout anche quando quell'elemento è quello che ha appena cancellato il focus! È un po 'pazzo e frustrante, ma forse c'è un motivo valido per questo tipo di comportamento.
Weston Wedding

1676

Il vero problema è che non vuoi che si concentri? O non vuoi che mostri la tastiera virtuale come risultato della messa a fuoco del EditText? Non vedo davvero un problema con il EditTextfocus sull'avvio, ma è sicuramente un problema avere la finestra softInput aperta quando l'utente non ha esplicitamente richiesto di concentrarsi sul EditText(e di conseguenza aprire la tastiera).

Se è il problema della tastiera virtuale, consultare la documentazione AndroidManifest.xml dell'elemento <attività> .

android:windowSoftInputMode="stateHidden" - nascondilo sempre quando entri nell'attività.

oppure android:windowSoftInputMode="stateUnchanged"- non modificarlo (ad es. non mostrarlo se non è già mostrato, ma se era aperto quando si entra nell'attività, lasciarlo aperto).


24
eppure il cursore è ancora nel primo EditText nel layout - anche se la tastiera non è mostrata
martyglaubitz

39
@Anderson: nulla della risposta implicava che avrebbe impedito EditTextdi ottenere la messa a fuoco. In realtà afferma chiaramente che questo è il modo in cui si impedisce alla tastiera del software IME di aprirsi automaticamente a fuoco; perché è più probabile che la preoccupazione maggiore sia la tastiera soft che si apre inaspettatamente, non lo stesso focus. Se il tuo problema riguarda la EditTextmessa a fuoco effettiva, usa la risposta di qualcun altro.
Joe,


3
Non farlo su un'attività con una fotocamera: interrompe il tempo del flash (non chiedermi perché)
Daniel Wilson,

1
@Joe questa domanda non riguarda nascondere la tastiera all'avvio. Tale domanda è stato chiesto qui stackoverflow.com/questions/18977187/...
user924

1141

Esiste una soluzione più semplice. Imposta questi attributi nel layout principale:

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

E ora, quando inizia l'attività, questo layout principale verrà attivato per impostazione predefinita.

Inoltre, possiamo rimuovere lo stato attivo dalle viste figlio in fase di esecuzione (ad esempio, dopo aver terminato la modifica figlio) dando nuovamente lo stato attivo al layout principale, in questo modo:

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

Buon commento di Guillaume Perrot :

android:descendantFocusability="beforeDescendants"sembra essere il valore predefinito (il valore intero è 0). Funziona solo aggiungendo android:focusableInTouchMode="true".

In realtà, possiamo vedere che il beforeDescendantsset è predefinito nel ViewGroup.initViewGroup()metodo (Android 2.2.2). Ma non uguale a 0.ViewGroup.FOCUS_BEFORE_DESCENDANTS = 0x20000;

Grazie a Guillaume.


1
È importante impostare questi attributi sul genitore diretto della vista che si concentra sulla creazione di attività, altrimenti non funzionerà.
Tomrozb,

4
Solo una soluzione perfetta. Funziona con entrambi: 1.Disattivazione della messa a fuoco automatica e 2. Disabilitazione dell'apertura automatica della tastiera virtuale
Incontro il

Bello. Non deve essere un genitore diretto. L'ho impostato a livello di layout di base e sembra funzionare bene.
Kurotsuki,

@DanielWilson quando vorresti una scrollview come genitore diretto di un edittext?
Mark Buikema,

Devi lavorare con l'input soft della finestra come readyandroid.wordpress.com/…
Pronto Android

427

L'unica soluzione che ho trovato è:

  • Crea un LinearLayout (non so se altri tipi di layout funzioneranno)
  • Impostare gli attributi android:focusable="true"eandroid:focusableInTouchMode="true"

E il EditTextnon otterrà il focus dopo aver iniziato l'attività


Semplice!! Inizialmente ho aggiunto queste proprietà alla vista padre, che non è riuscita, quindi le ho impostate su un altro layout e ho funzionato bene. Grazie!!
Rino,

Funziona anche con un ConstraintLayout.
Falco

86

Il problema sembra provenire da una proprietà che posso vedere solo nel XML formlayout.

Assicurati di rimuovere questa riga alla fine della dichiarazione all'interno dei EditTexttag XML:

<requestFocus />

Questo dovrebbe dare qualcosa del genere:

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

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

78

usando le informazioni fornite da altri poster, ho usato la seguente soluzione:

nel layout 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"/>

in 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);
}

e infine, in onResume ()

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

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

74

Prova clearFocus () invece di setSelected(false). Ogni vista in Android ha sia focalizzabilità che selezionabilità, e penso che tu voglia semplicemente chiarire il focus.


Sembra promettente, ma a che punto del ciclo di vita dell'Attività dovrebbe essere chiamato? Se lo chiamo in onCreate (), EditText ha ancora lo stato attivo. Dovrebbe essere chiamato in onResume () o in qualche altra posizione? Grazie!
Segna il

8
Ho combinato la risposta accettata con questa risposta. Ho chiamato myEditText.clearFocus(); myDummyLinearLayout.requestFocus();in onResumedell'attività. Ciò ha garantito che EditText non mantenesse lo stato attivo quando il telefono veniva ruotato.
Teedyay,

71

Quanto segue impedirà a edittext di focalizzarsi quando viene creato, ma lo afferri quando lo tocchi.

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

Quindi imposta focusable su false in xml, ma la chiave è in java, che aggiungi il seguente listener:

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

Poiché stai restituendo false, ovvero non stai consumando l'evento, il comportamento di messa a fuoco procederà come di consueto.


6
Ma questo non riuscirà mai a focalizzarsi in futuro, come fermare la messa a fuoco solo per l'iniziale (inizio attività) ??
Jayesh

1
OnTouchListener viene chiamato prima di altre azioni di tocco. Quindi, abilitando la messa a fuoco al tocco, la messa a fuoco standard avviene al primo tocco. La tastiera verrà fuori e tutto.
MinceMan

1
Penso che questo sia il modo migliore per farlo. Inoltre, il codice fittizio magico mumbo-jumbo xml sopra non ha funzionato per una serie complessa di testi di modifica ... Se funziona, voterò sicuramente.
Radu,

Ma se hai più testi di modifica, si focalizzerà sul prossimo testo di modifica e aprirà la tastiera, quindi è meglio aggiungere android: windowSoftInputMode = "stateAlwaysHidden" in manifest per una particolare attività.
Karan sharma,

Nota: su Android P il sistema non prenderà più un focus predefinito. Ciò significa che questo hack non è necessario a partire da P.
MinceMan

65

Avevo provato diverse risposte individualmente, ma il focus è ancora su EditText. Sono riuscito a risolverlo solo usando due delle seguenti soluzioni insieme.

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

(Riferimento da Silver https://stackoverflow.com/a/8639921/15695 )

e rimuovi

 <requestFocus />

a EditText

(Riferimento da floydaddict https://stackoverflow.com/a/9681809 )


1
Ho dovuto aggiungere edittext.clearFocus () in aggiunta a quanto sopra per farlo funzionare :)
Nav

57

Risposta tardiva ma più semplice, basta aggiungerla nel layout principale dell'XML.

android:focusable="true" 
android:focusableInTouchMode="true"

Valuta se ti ha aiutato! Happy Coding :)


2
ha funzionato perfettamente per me. un'altra cosa da notare è, non aggiungere queste righe per scorrere la vista. Non funzionerà nella vista a scorrimento. Ma ha funzionato perfettamente con il layout lineare.
Karthic Srinivasan,

46

Nessuna di queste soluzioni ha funzionato per me. Il modo in cui ho risolto l'autofocus è stato:

<activity android:name=".android.InviteFriendsActivity" android:windowSoftInputMode="adjustPan">
    <intent-filter >
    </intent-filter>
</activity>

2
android: windowSoftInputMode = "adjustPan" su qualsiasi attività nel Manifest Android
rallat

43

Soluzione semplice: in AndroidManifestin Activitytag utilizza

android:windowSoftInputMode="stateAlwaysHidden"

6
A rigor di termini, questo non risolve il problema. l'OP ha detto: "Non voglio alcun controllo per avere focus di input all'avvio". La tua soluzione nasconde solo la tastiera, c'è una differenza minore.
Katzenhut,

@katzenhut sì, questo è esattamente il mio problema con questa risposta. Concentrarsi sul mio edittext apre un'attività PlaceAutoComplete, quindi questa risposta è incompleta
Zach,

Questa risposta sarebbe completa se la domanda fosse: come posso garantire sempre che la mia attività non mostri mai una tastiera. Che non è.
Martin Marconcini,

37

Puoi semplicemente impostare "focalizzabile" e "attivabile in modalità touch" per dare valore vero al primo TextViewdei layout. In questo modo quando l'attività inizia la messa TextViewa fuoco sarà focalizzata ma, per sua natura, non vedrai nulla di focalizzato sullo schermo e, naturalmente, non verrà visualizzata alcuna tastiera ...


funziona perfettamente per me, solo che ho impostato il valore sul layout estremo della mia attività e non sulla prima visualizzazione di testo
Maverick1

36

Quanto segue ha funzionato per me Manifest. Scrivi ,

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

1
Ciò non disattiva il campo di testo: nasconde semplicemente la tastiera. Otterrai comunque un suggerimento che viene espulso dal campo e qualsiasi selettore dello stato colore mostrerà lo stato "focalizzato = vero".
A. Rager,

31

Avevo bisogno di cancellare la messa a fuoco da tutti i campi a livello di codice. Ho appena aggiunto le seguenti due affermazioni alla mia definizione di layout principale.

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

Questo è tutto. Risolto il mio problema all'istante. Grazie, Silver, per avermi indicato nella giusta direzione.


28

Aggiungi android:windowSoftInputMode="stateAlwaysHidden"il tag attività del Manifest.xmlfile.

fonte


1
Ciò non disattiva il campo di testo: nasconde semplicemente la tastiera. Otterrai comunque un suggerimento che viene espulso dal campo e qualsiasi selettore dello stato colore mostrerà lo stato "focalizzato = vero".
A. Rager,

25

Se hai un'altra visione della tua attività come una ListView, puoi anche fare:

ListView.requestFocus(); 

nel tuo onResume()per attirare l'attenzione dal editText.

So che a questa domanda è stata data una risposta, ma solo fornendo una soluzione alternativa che ha funzionato per me :)


22

Prova questo prima del tuo primo campo modificabile:

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

21

Aggiungi il seguente onCreatemetodo:

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

1
Ciò non disattiva il campo di testo: nasconde semplicemente la tastiera. Otterrai comunque un suggerimento che viene espulso dal campo e qualsiasi selettore dello stato colore mostrerà lo stato "focalizzato = vero".
A. Rager,

17

Essendo che non mi piace inquinare l'XML con qualcosa che è legato alla funzionalità, ho creato questo metodo che "in modo trasparente" ruba il focus dalla prima vista focalizzabile e quindi si assicura di rimuoverlo quando necessario!

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

15

In ritardo, ma forse utile. Creare un EditText manichino nella parte superiore del vostro layout quindi chiamare myDummyEditText.requestFocus()inonCreate()

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

Sembra che si comporti come mi aspetto. Non è necessario gestire le modifiche alla configurazione, ecc. Ne avevo bisogno per un'attività con un lungo TextView (istruzioni).


Perché non farlo solo con la vista radice stessa?
CJBS,


13

Sì, ho fatto la stessa cosa: ho creato un layout lineare "fittizio" che ha il focus iniziale. Inoltre, ho impostato gli ID di messa a fuoco "successivi" in modo che l'utente non possa più metterlo a fuoco dopo averlo fatto scorrere una volta:

<LinearLayout 'dummy'>
<EditText et>

dummy.setNextFocusDownId(et.getId());

dummy.setNextFocusUpId(et.getId());

et.setNextFocusUpId(et.getId());

molto lavoro solo per sbarazzarsi della messa a fuoco su una vista ..

Grazie


12

Per me, ciò che ha funzionato su tutti i dispositivi è questo:

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

Basta mettere questo come una vista prima della vista focalizzata problematica, e il gioco è fatto.


10

La cosa più semplice che ho fatto è concentrarmi su un'altra vista in onCreate:

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

Ciò ha impedito la comparsa della tastiera software e non era presente alcun cursore nell'EditText.


10

Questa è la soluzione perfetta e più semplice. La utilizzo sempre nella mia app.

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

Ciò non disattiva il campo di testo: nasconde semplicemente la tastiera. Otterrai comunque un suggerimento che viene espulso dal campo e qualsiasi selettore dello stato colore mostrerà lo stato "focalizzato = vero".
A. Rager,

9
<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"/>

8

Scrivi questo codice all'interno del Manifestfile nel punto in Activitycui non desideri aprire la tastiera.

android:windowSoftInputMode="stateHidden"

File manifest:

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

2
Ciò non disattiva il campo di testo: nasconde semplicemente la tastiera. Otterrai comunque un suggerimento che viene espulso dal campo e qualsiasi selettore dello stato colore mostrerà lo stato "focalizzato = vero".
A. Rager,

7

Alla onCreatetua attività, aggiungi solo l'uso clearFocus()sul tuo elemento EditText. Per esempio,

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

E se vuoi spostare l'attenzione su un altro elemento, usalo requestFocus(). Per esempio,

button = (Button) findViewById(R.id.button);
button.requestFocus();

6

Uso il seguente codice per impedire a un EditText di rubare lo stato attivo quando viene premuto il mio pulsante.

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

Fondamentalmente, nascondi il testo di modifica e poi mostralo di nuovo. Questo funziona per me come EditText non lo è in vista, quindi non importa se sta mostrando.

Potresti provare a nasconderlo e mostrarlo in successione per vedere se questo aiuta a perdere la concentrazione.

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.