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?

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

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).


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


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.


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


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

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

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.


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.


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 )


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 :)


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>

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"

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


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

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.


28

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

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ó :)


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

21

Agregue lo siguiente en el onCreatemétodo:

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

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

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).


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


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


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.


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.


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

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

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>

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

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.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.