Cómo evitar que EditText se enfoque en el inicio de Activity en Android

2873

Tengo un Activityen Android, con dos elementos:

  1. EditText
  2. ListView

Cuando Activitycomienza, EditTextinmediatamente tiene el foco de entrada (cursor intermitente). No quiero que ningún control tenga foco de entrada al inicio. Lo intenté:

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

Sin suerte. ¿Cómo puedo convencer EditTexta que no se seleccione cuando Activitycomienza?

marca
fuente

Respuestas:

2593

Excelentes respuestas de Luc y Mark, sin embargo, falta un buen ejemplo de código. Agregar la etiqueta android:focusableInTouchMode="true"y android:focusable="true"al diseño principal (p. Ej. LinearLayoutO ConstraintLayout) como en el siguiente ejemplo solucionará el 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"/>
Morgan Christiansson
fuente
711
¿Qué hay de establecer el diseño principal en android:focusableInTouchMode="true"!
Muhammad Babar
28
¡Perfecto! Gracias ... ¡Una cosa a tener en cuenta es que el elemento ficticio debe COLOCARSE JUSTO ANTES del elemento enfocable! ¡Tenía un TextView entre mi ficticio y EditText y el método no funcionó!
maddob
25
configurar android: focusableInTouchMode = "true" para el diseño principal fue el buen enfoque gracias @Muhammad Babar
sujith s
77
Gran código, me ayudó mucho :) Para intentar mejorarlo, android:focusableInTouchMode="true"cubre android:focusable="true"+ un poco más, por lo que en este caso android:focusable="true"es innecesario y puede eliminarse. Además, la vista ficticia puede ser una Vista en lugar de un Diseño lineal. Esto ahorra poder de procesamiento + lo salva de algunas advertencias. Por lo tanto, mi recomendación es reemplazar la vista ficticia con<View android:focusableInTouchMode="true" android:layout_width="0px" android:layout_height="0px"/>
Jacob R
20
@PietroRea Android tiene comportamientos molestos de autoenfoque integrados en el comportamiento central de la estructura de su aplicación. Si le dice que un texto de edición está liberando o perdiendo foco, automáticamente toma una decisión sobre dónde va el foco. Sin un nuevo objeto para que el foco se transfiera, ¡elige el primer elemento enfocable en el diseño incluso cuando ese elemento es el que acaba de borrar su foco! Es un poco loco y frustrante, pero tal vez haya una razón válida para este tipo de comportamiento.
Weston Wedding
1676

¿Es el problema real que simplemente no quieres que tenga foco en absoluto? ¿O no quieres que muestre el teclado virtual como resultado de enfocar el EditText? Realmente no veo un problema con EditTexttener el foco en el inicio, pero definitivamente es un problema tener abierta la ventana softInput cuando el usuario no solicitó explícitamente enfocarse en el EditText(y abrir el teclado como resultado).

Si es el problema del teclado virtual, consulte la documentación del AndroidManifest.xml elemento <actividad> .

android:windowSoftInputMode="stateHidden" - siempre lo oculta al ingresar a la actividad.

o android:windowSoftInputMode="stateUnchanged"- no lo cambie (p. ej., no lo muestre si aún no se muestra, pero si estaba abierto al ingresar a la actividad, déjelo abierto).

Joe
fuente
24
aún así el cursor está en el primer EditText en el diseño, a pesar de que el teclado no se muestra
martyglaubitz
39
@ Anderson: Nada acerca de la respuesta implicaba que impediría que se EditTextenfocara. En realidad, establece claramente que así es como evita que el teclado IME del software se abra automáticamente al enfocar; porque es más probable que la mayor preocupación sea el teclado suave que aparece inesperadamente, no el foco en sí. Si su problema es que EditTextrealmente se está enfocando, use la respuesta de otra persona.
Joe
1
configúrelo
Nick Franceschina
3
No hagas esto en una actividad con una cámara: rompe el tiempo del flash (no me preguntes por qué)
Daniel Wilson
1
@ Joe, esta pregunta no se trata de ocultar el teclado al inicio. Tal pregunta se hizo aquí stackoverflow.com/questions/18977187/…
user924
1141

Existe una solución más simple. Establezca estos atributos en su diseño principal:

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

Y ahora, cuando comienza la actividad, este diseño principal se enfocará de manera predeterminada.

Además, podemos eliminar el foco de las vistas secundarias en tiempo de ejecución (por ejemplo, después de terminar la edición secundaria) volviendo a enfocar el diseño principal, de esta manera:

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

Buen comentario de Guillaume Perrot :

android:descendantFocusability="beforeDescendants"parece ser el valor predeterminado (el valor entero es 0). Funciona solo agregando android:focusableInTouchMode="true".

Realmente, podemos ver que el beforeDescendantsconjunto está predeterminado en el ViewGroup.initViewGroup()método (Android 2.2.2). Pero no es igual a 0.ViewGroup.FOCUS_BEFORE_DESCENDANTS = 0x20000;

Gracias a Guillaume.

Plata
fuente
1
Es importante establecer estos atributos en el elemento primario directo de la vista, que se enfoca en la creación de actividades; de lo contrario, no funcionará.
tomrozb
44
Solo una solución perfecta. Funciona para ambos: 1. Desactivar el enfoque automático y 2. Desactivar la apertura automática del teclado virtual
Conoce el
Agradable. No necesita ser un padre directo. Lo configuré en el nivel raíz del diseño y parece funcionar bien.
Kurotsuki el
@DanielWilson, ¿cuándo desea una vista de desplazamiento como padre directo de un texto de edición?
Mark Buikema
Tienes que trabajar con la entrada suave de la ventana como readyandroid.wordpress.com/…
Listo para Android
427

La única solución que he encontrado es:

  • Crear un diseño lineal (no sé si funcionarán otros tipos de diseño)
  • Establecer los atributos android:focusable="true"yandroid:focusableInTouchMode="true"

Y EditTextno obtendrá el foco después de comenzar la actividad

Luc
fuente
¡¡Simple!! Inicialmente agregué estas propiedades a la vista principal, que falló, luego las configuré en otro diseño y funcioné bien. ¡¡Gracias!!
Rino
Funciona también con un RestraintLayout.
Hawklike
86

El problema parece provenir de una propiedad que solo puedo ver en XML formel diseño.

Asegúrese de eliminar esta línea al final de la declaración dentro de las EditTextetiquetas XML:

<requestFocus />

Eso debería dar algo así:

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

   //<requestFocus /> /* <-- without this line */
</EditText>
floydaddict
fuente
78

Utilizando la información proporcionada por otros carteles, utilicé la siguiente solución:

en el diseño 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"/>

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

y finalmente, en onResume ()

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

    //do not give the editbox focus automatically when activity starts
    mAutoCompleteTextView.clearFocus();
    mLinearLayout.requestFocus();
}
Alguien en alguna parte
fuente
74

Pruebe clearFocus () en lugar de setSelected(false). Cada vista en Android tiene enfocabilidad y capacidad de selección, y creo que solo quieres aclarar el enfoque.

Eric Mill
fuente
Eso suena prometedor, pero ¿en qué punto del ciclo de vida de la actividad debería llamarse? Si lo llamo en onCreate (), EditText todavía tiene el foco. ¿Debería llamarse en onResume () o en alguna otra ubicación? ¡Gracias!
Mark
8
Combiné la respuesta aceptada con esta respuesta. Llamé myEditText.clearFocus(); myDummyLinearLayout.requestFocus();a onResumela actividad. Esto aseguró que EditText no mantuviera el foco cuando se giraba el teléfono.
teedyay
71

Lo siguiente evitará que edittext se enfoque cuando se cree, pero tómalo cuando los toques.

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

Por lo tanto, establece focusable en false en el xml, pero la clave está en java, a la que agrega el siguiente oyente:

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

Debido a que está devolviendo falso, es decir, no está consumiendo el evento, el comportamiento de enfoque continuará como de costumbre.

MinceMan
fuente
66
Pero esto nunca se enfocará en el futuro, ¿cómo detener el enfoque solo para el inicio (inicio de la actividad)?
Jayesh
1
OnTouchListener se llama antes que otras acciones táctiles. Entonces, al habilitar el enfoque táctil, el enfoque estándar ocurre en el primer toque. Aparecerá el teclado y todo.
MinceMan
1
Creo que esta es la mejor manera de hacerlo. Además, el código ficticio mágico mumbo-jumbo xml anterior NO funcionó para un conjunto complejo de textos de edición ... Si esto funciona, definitivamente votaré.
Radu
Pero si tiene varios textos de edición, se centrará en el siguiente texto de edición y abrirá el teclado, por lo que es mejor agregar android: windowSoftInputMode = "stateAlwaysHidden" en manifiesto para una actividad particular.
Karan sharma
Nota: en Android P, el sistema ya no tomará un foco predeterminado. Esto significa que este truco no es necesario a partir de P.
MinceMan
65

Intenté varias respuestas individualmente, pero el foco todavía está en EditText. Solo logré resolverlo usando dos de las siguientes soluciones juntas.

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

(Referencia de Silver https://stackoverflow.com/a/8639921/15695 )

y quitar

 <requestFocus />

en EditText

(Referencia de floydaddict https://stackoverflow.com/a/9681809 )

Lee Yi Hong
fuente
1
Tuve que agregar edittext.clearFocus () además de lo anterior para que funcione :)
Nav
57

Respuesta tardía pero más simple, solo agregue esto en el diseño principal del XML.

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

¡Vota si te ayudó! Happy Coding :)

Rishabh Saxena
fuente
2
Funcionó perfectamente para mí. Una cosa más a tener en cuenta es que no agregue estas líneas a la vista de desplazamiento. No funcionará en la vista de desplazamiento. Pero funcionó perfectamente con diseño lineal.
Karthic Srinivasan
46

Ninguna de estas soluciones funcionó para mí. La forma en que solucioné el enfoque automático fue:

<activity android:name=".android.InviteFriendsActivity" android:windowSoftInputMode="adjustPan">
    <intent-filter >
    </intent-filter>
</activity>
rallat
fuente
2
android: windowSoftInputMode = "ajustarPan" en cualquier actividad en el Manifiesto de Android
rallat
43

Solución simple: AndroidManifesten el Activityuso de etiquetas

android:windowSoftInputMode="stateAlwaysHidden"
Sergey Sheleg
fuente
66
Estrictamente hablando, esto no resuelve el problema. el OP dijo: "No quiero que ningún control tenga foco de entrada al inicio". Su solución solo oculta el teclado, hay una diferencia sutil.
katzenhut
@katzenhut sí, ese es mi problema con esta respuesta exactamente. Centrarme en mi texto de edición abre una actividad PlaceAutoComplete, por lo que esta respuesta está incompleta
Zach
Esta respuesta estaría completa si la pregunta fuera: ¿Cómo me aseguro de que mi actividad nunca muestre un teclado? Lo cual no es.
Martin Marconcini
37

Puede configurar "enfocable" y "enfocable en modo táctil" para que sea verdadero en el primero TextViewde los layout. De esta manera, cuando comience la actividad TextView, se enfocará pero, debido a su naturaleza, no verá nada enfocado en la pantalla y, por supuesto, no se mostrará ningún teclado ...

Zeus
fuente
funciona perfectamente para mí, solo configuro el valor en el diseño más externo de mi actividad y no en la primera vista de texto
Maverick1st
36

Lo siguiente funcionó para mí en Manifest. Escribir ,

<activity
android:name=".MyActivity"
android:windowSoftInputMode="stateAlwaysHidden"/>
Babar Sanah
fuente
1
Esto no desenfoca el campo de texto: simplemente oculta el teclado. Todavía obtendrá una pista que se elimina del campo, y cualquier selector de estado de color mostrará el estado "focus = true".
A. Rager
31

Necesitaba despejar el foco de todos los campos mediante programación. Acabo de agregar las siguientes dos declaraciones a mi definición de diseño principal.

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

Eso es. Solucioné mi problema al instante. Gracias, Silver, por señalarme en la dirección correcta.

jakeneff
fuente
28

Agregue android:windowSoftInputMode="stateAlwaysHidden"la etiqueta de actividad del Manifest.xmlarchivo.

Fuente

prgmrDev
fuente
1
Esto no desenfoca el campo de texto: simplemente oculta el teclado. Todavía obtendrá una pista que se elimina del campo, y cualquier selector de estado de color mostrará el estado "focus = true".
A. Rager
25

Si tiene otra vista de su actividad como a ListView, también puede hacer:

ListView.requestFocus(); 

en su onResume()para captar el foco de la editText.

Sé que esta pregunta ha sido respondida, pero solo proporcioné una solución alternativa que me funcionó :)

Sid
fuente
22

Pruebe esto antes de su primer campo editable:

<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();
Jack Slater
fuente
21

Agregue lo siguiente en el onCreatemétodo:

this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Vishal Raj
fuente
1
Esto no desenfoca el campo de texto: simplemente oculta el teclado. Todavía obtendrá una pista que se elimina del campo, y cualquier selector de estado de color mostrará el estado "focus = true".
A. Rager
17

Siendo que no me gusta contaminar el XML con algo relacionado con la funcionalidad, creé este método que "transparentemente" roba el foco de la primera vista enfocable y luego se asegura de eliminarlo cuando sea necesario.

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;
}
Takhion
fuente
15

Tarde, pero tal vez útil. Crear un EditarTexto ficticia en la parte superior de su diseño a continuación, llamar myDummyEditText.requestFocus()enonCreate()

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

Eso parece comportarse como espero. No es necesario manejar cambios de configuración, etc. Necesitaba esto para una Actividad con un TextView largo (instrucciones).

Jim
fuente
¿Por qué no simplemente hacer esto con la vista raíz misma?
CJBS
14

Escriba esta línea en su Diseño para padres ...

 android:focusableInTouchMode="true"
Vishal Vaishnav
fuente
respuesta duplicada
Ricardo A.
13

Sí, hice lo mismo: crear un diseño lineal 'ficticio' que obtiene el foco inicial. Además, configuro las 'siguientes' ID de foco para que el usuario no pueda enfocarlo más después de desplazarse una vez:

<LinearLayout 'dummy'>
<EditText et>

dummy.setNextFocusDownId(et.getId());

dummy.setNextFocusUpId(et.getId());

et.setNextFocusUpId(et.getId());

mucho trabajo solo para deshacernos del foco en una vista ...

Gracias

marca
fuente
12

Para mí, lo que funcionó en todos los dispositivos es esto:

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

Simplemente ponga esto como una vista antes de la vista enfocada problemática, y eso es todo.

desarrollador de Android
fuente
10

Lo más simple que hice es establecer el foco en otra vista en onCreate:

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

Esto detuvo la aparición del teclado virtual y no hubo parpadeo del cursor en EditText.

Lumis
fuente
10

Esta es la solución más fácil y perfecta. Siempre uso esto en mi aplicación.

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

fuente
Esto no desenfoca el campo de texto: simplemente oculta el teclado. Todavía obtendrá una pista que se elimina del campo, y cualquier selector de estado de color mostrará el estado "focus = true".
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"/>
atul
fuente
8

Escriba este código dentro del Manifestarchivo en el Activityque no desea abrir el teclado.

android:windowSoftInputMode="stateHidden"

Archivo de manifiesto:

 <?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>
Rayo Tarit
fuente
2
Esto no desenfoca el campo de texto: simplemente oculta el teclado. Todavía obtendrá una pista que se elimina del campo, y cualquier selector de estado de color mostrará el estado "focus = true".
A. Rager
7

En onCreatesu Actividad, simplemente agregue uso clearFocus()en su elemento EditText. Por ejemplo,

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

Y si desea desviar el enfoque a otro elemento, úselo requestFocus(). Por ejemplo,

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

Uso el siguiente código para evitar que un EditText robe el foco cuando presiono mi botón.

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

Básicamente, oculta el texto de edición y luego muéstralo nuevamente. Esto funciona para mí ya que EditText no es a la vista, por lo que no importa si se muestra.

Podría intentar esconderse y mostrarlo sucesivamente para ver si eso lo ayuda a perder el foco.

drei01
fuente