Como parar o EditText de ganhar foco na inicialização da atividade no Android

2873

Eu tenho um Activityno Android, com dois elementos:

  1. EditText
  2. ListView

Quando Activityinicio, o EditTextfoco de entrada é imediatamente (cursor piscando). Não quero que nenhum controle tenha foco de entrada na inicialização. Eu tentei:

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

Sem sorte Como convencer a EditTextnão selecionar a si mesma quando Activityiniciar?

Marca
fonte

Respostas:

2593

Excelentes respostas de Luc e Mark, no entanto, está faltando um bom exemplo de código. Adicionar a tag android:focusableInTouchMode="true"e o android:focusable="true"layout pai (por exemplo, LinearLayoutou ConstraintLayout), como no exemplo a seguir, corrigirá o 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
fonte
711
Que tal definir o layout pai para android:focusableInTouchMode="true"!
Muhammad Babar 21/03
28
Perfeito! Obrigado ... Uma coisa a se notar é que o item fictício deve ser COLOCADO CERTO ANTES do elemento focalizável !!! Eu tinha um TextView entre o meu manequim e o EditText e o método não funcionou!
maddob
25
ajuste Android: focusableInTouchMode = "true" para o layout pai foi a abordagem boa graças @Muhammad Babar
sujith s
7
Ótimo código, me ajudou muito :) Para tentar melhorar, android:focusableInTouchMode="true"cobre android:focusable="true"+ um pouco mais, portanto, neste caso, android:focusable="true"é desnecessário e pode ser removido. Além disso, a visualização simulada pode ser uma visualização em vez de um LinearLayout. Isso economiza poder de processamento + evita alguns avisos. Assim, minha recomendação é substituir a exibição fictícia por<View android:focusableInTouchMode="true" android:layout_width="0px" android:layout_height="0px"/>
Jacob R
20
O @PietroRea Android possui comportamentos irritantes de foco automático, incorporados ao comportamento principal de sua estrutura de aplicativos. Se você disser que um texto de edição está liberando ou perdendo o foco, ele decide automaticamente para onde o foco vai. Sem um novo objeto para o qual o foco será transferido, ele seleciona o primeiro elemento que pode ser focalizado no layout, mesmo quando esse é o elemento que acabou de limpar o foco! É meio louco e frustrante, mas talvez haja uma razão válida para esse tipo de comportamento.
Wedding Weston
1676

O problema real é que você simplesmente não quer que ele tenha foco? Ou você não deseja que ele mostre o teclado virtual como resultado do foco no EditText? Realmente não vejo um problema com o EditTextfoco no início, mas é definitivamente um problema abrir a janela softInput quando o usuário não solicitou explicitamente o foco EditText(e, como resultado, abriu o teclado).

Se for o problema do teclado virtual, consulte a documentação do AndroidManifest.xml elemento <atividade> .

android:windowSoftInputMode="stateHidden" - sempre oculte ao entrar na atividade.

ou android:windowSoftInputMode="stateUnchanged"- não mude (por exemplo, não o mostre se ainda não estiver sendo exibido, mas se estava aberto ao entrar na atividade, deixe-o aberto).

Joe
fonte
24
ainda assim, o cursor está no primeiro EditText no layout - mesmo que o teclado não seja mostrado
martyglaubitz
39
@ Anderson: Nada na resposta implicava que isso impediria a EditTextobtenção de foco. Na verdade, afirma claramente que é assim que você impede que o IME do teclado do software seja aberto automaticamente no foco; porque é mais provável que a maior preocupação seja o teclado virtual aparecer inesperadamente, não o foco em si. Se seu problema é EditTextrealmente o foco, use a resposta de outra pessoa.
218 Joe Joe
1
configurá-lo de forma programática: stackoverflow.com/questions/6138330/...
Nick Franceschina
3
Não fazer isso em uma atividade com uma câmera - ele quebra o momento do flash (não me pergunte o porquê)
Daniel Wilson
1
@ Joe esta questão não é sobre como ocultar o teclado na inicialização. Essa pergunta foi feita aqui stackoverflow.com/questions/18977187/…
user924
1141

Existe uma solução mais simples. Defina estes atributos no seu layout pai:

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

E agora, quando a atividade iniciar, esse layout principal terá foco por padrão.

Além disso, podemos remover o foco das visualizações filho em tempo de execução (por exemplo, depois de terminar a edição filho), dando o foco ao layout principal novamente, desta forma:

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

Bom comentário de Guillaume Perrot :

android:descendantFocusability="beforeDescendants"parece ser o padrão (o valor inteiro é 0). Funciona apenas adicionando android:focusableInTouchMode="true".

Realmente, podemos ver que o beforeDescendantsconjunto é o padrão no ViewGroup.initViewGroup()método (Android 2.2.2). Mas não é igual a 0.ViewGroup.FOCUS_BEFORE_DESCENDANTS = 0x20000;

Graças a Guillaume.

Prata
fonte
1
É importante definir esses atributos para o pai direto da exibição, que ganha foco na criação de atividades, caso contrário, não funcionará.
9135 tomrozb
4
Apenas uma solução perfeita. Funciona para: 1. Desabilitar o foco automático e 2. Desabilitar a abertura automática do teclado virtual
Conheça o
Agradável. Não precisa ser um pai direto. Eu defini-lo no nível raiz do layout e parece funcionar bem.
precisa saber é o seguinte
@DanielWilson quando você deseja uma visualização de rolagem como pai direto de um edittext?
precisa saber é o seguinte
Você precisa trabalhar com a entrada suave da janela, como readyandroid.wordpress.com/…
Android pronto
427

A única solução que encontrei é:

  • Crie um LinearLayout (não sei se outros tipos de layout funcionarão)
  • Defina os atributos android:focusable="true"eandroid:focusableInTouchMode="true"

E EditTexteles não terão o foco depois de iniciar a atividade

Luc
fonte
Simples!! Inicialmente, adicionei essas propriedades à exibição pai, que falharam, depois as configurei para outro layout e funcionou bem. Obrigado!!
Rino
Também funciona com um ConstraintLayout.
Hawklike 26/08/19
86

O problema parece vir de uma propriedade que eu só posso ver no XML formlayout.

Certifique-se de remover esta linha no final da declaração dentro das EditTexttags XML:

<requestFocus />

Isso deve dar algo assim:

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

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

usando as informações fornecidas por outros pôsteres, usei a seguinte solução:

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

em 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, finalmente, em onResume ()

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

    //do not give the editbox focus automatically when activity starts
    mAutoCompleteTextView.clearFocus();
    mLinearLayout.requestFocus();
}
Alguém algum lugar
fonte
74

Tente clearFocus () em vez de setSelected(false). Todas as visualizações no Android têm foco e seleção, e acho que você deseja apenas clarear o foco.

Eric Mill
fonte
Isso parece promissor, mas em que ponto do ciclo de vida da atividade deve ser chamado? Se eu chamar onCreate (), o EditText ainda terá foco. Deve ser chamado onResume () ou algum outro local? Obrigado!
Mark
8
Combinei a resposta aceita com esta resposta. Liguei myEditText.clearFocus(); myDummyLinearLayout.requestFocus();para onResumea atividade. Isso garantiu que o EditText não mantivesse o foco quando o telefone fosse girado.
teedyay
71

O seguinte impedirá o edittext de focar quando criado, mas agarre-o quando você os tocar.

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

Portanto, você define focusable como false no xml, mas a chave está no java, à qual você adiciona o seguinte ouvinte:

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

Como você está retornando falso, ou seja, não está consumindo o evento, o comportamento de foco continuará como normal.

MinceMan
fonte
6
Mas isso nunca vai ganhar foco no futuro, como parar o foco apenas no início (início da atividade)?
Jayesh
1
O onTouchListener é chamado antes de outras ações de toque. Portanto, ao ativar o foco no toque, o foco padrão acontece no primeiro toque. O teclado aparecerá e tudo.
MinceMan
1
Eu acho que essa é a melhor maneira de fazer isso. Além disso, o código fictício mágico xml mumbo-jumbo acima NÃO funcionou para um conjunto complexo de textos de edição ... Se isso funcionar, votarei definitivamente.
Radu
Mas se você estiver tendo vários textos de edição, ele focará na próxima edição de texto e abrirá o teclado, por isso é melhor adicionar o android: windowSoftInputMode = "stateAlwaysHidden" no manifesto para uma atividade específica.
31418 Karan sharma
Nota: no Android P, o sistema não terá mais o foco padrão. Isso significa que esse hack não é necessário, começando com P. #
MinceMan
65

Eu tentei várias respostas individualmente, mas o foco ainda está no EditText. Só consegui resolvê-lo usando duas das soluções abaixo juntas.

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

(Referência da Silver https://stackoverflow.com/a/8639921/15695 )

e remova

 <requestFocus />

em EditText

(Referência de floydaddict https://stackoverflow.com/a/9681809 )

Lee Yi Hong
fonte
1
Eu tive que adicionar o edittext.clearFocus () além dos itens acima para fazê-lo funcionar :) #
9104 Nav Nav
57

Resposta tardia, porém mais simples, basta adicionar isso no layout pai do XML.

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

Voto a favor se isso ajudou! Happy Coding :)

Rishabh Saxena
fonte
2
funcionou perfeitamente para mim. mais uma coisa a observar é, não adicione essas linhas para rolar a exibição. Não funcionará na exibição de rolagem. Mas funcionou perfeitamente com layout linear.
Karthic Srinivasan
46

Nenhuma dessas soluções funcionou para mim. A maneira como corrigi o foco automático era:

<activity android:name=".android.InviteFriendsActivity" android:windowSoftInputMode="adjustPan">
    <intent-filter >
    </intent-filter>
</activity>
rallat
fonte
2
android: windowSoftInputMode = "adjustPan" em qualquer atividade no manifesto Android
rallat
43

Solução simples: uso de tags AndroidManifestinActivity

android:windowSoftInputMode="stateAlwaysHidden"
Sergey Sheleg
fonte
6
A rigor, isso não resolve o problema. o OP disse: "Não quero que nenhum controle tenha foco de entrada na inicialização". Sua solução apenas oculta o teclado, há uma diferença sublime.
katzenhut 4/09/14
@ katzenhut sim, esse é o meu problema com esta resposta exatamente. Concentrando-se na minha EditText abre uma atividade PlaceAutoComplete, assim que esta resposta é incompleta
Zach
Esta resposta seria completa se a pergunta fosse: Como garantir sempre que minha atividade nunca mostre um teclado. O que não é.
Martin Marconcini
37

Você pode apenas definir "focalizável" e "focalizável no modo de toque" para o valor verdadeiro no primeiro TextViewdo layout. Desta forma, quando a atividade começa a TextViewserá focada mas, devido à sua natureza, você vai ver nada focada na tela e, é claro, haverá nenhum teclado exibido ...

Zeus
fonte
funciona perfeitamente para mim, eu apenas definir o valor no layout outmost em minha atividade e não ao primeiro textview
Maverick1st
36

O seguinte funcionou para mim Manifest. Escreva ,

<activity
android:name=".MyActivity"
android:windowSoftInputMode="stateAlwaysHidden"/>
Babar Sanah
fonte
1
Isso não desfoca o campo de texto: apenas oculta o teclado. Você ainda receberá uma dica que é enviada para fora do campo, e qualquer seletor de estado de cor exibirá o estado "focus = true".
A. Rager
31

Eu precisava limpar o foco de todos os campos programaticamente. Acabei de adicionar as duas instruções a seguir à minha definição de layout principal.

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

É isso aí. Corrigido meu problema instantaneamente. Obrigado, Silver, por me apontar na direção certa.

jakeneff
fonte
28

Adicione android:windowSoftInputMode="stateAlwaysHidden"a tag de atividade do Manifest.xmlarquivo.

Fonte

prgmrDev
fonte
1
Isso não desfoca o campo de texto: apenas oculta o teclado. Você ainda receberá uma dica que é enviada para fora do campo, e qualquer seletor de estado de cor exibirá o estado "focus = true".
A. Rager
25

Se você tiver outra visão da sua atividade como a ListView, também poderá:

ListView.requestFocus(); 

no seu onResume()para agarrar o foco do editText.

Eu sei que esta pergunta foi respondida, mas apenas fornecendo uma solução alternativa que funcionou para mim :)

Sid
fonte
22

Tente isso antes do seu primeiro campo editável:

<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
fonte
21

Adicione o seguinte no onCreatemétodo:

this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Vishal Raj
fonte
1
Isso não desfoca o campo de texto: apenas oculta o teclado. Você ainda receberá uma dica que é enviada para fora do campo, e qualquer seletor de estado de cor exibirá o estado "focus = true".
A. Rager
17

Como não gosto de poluir o XML com algo relacionado à funcionalidade, criei esse método que "transparentemente" rouba o foco da primeira exibição focalizável e depois se remove quando necessário!

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
fonte
15

Tarde, mas talvez útil. Criar um EditText manequim no topo do seu layout em seguida, chamar myDummyEditText.requestFocus()nosonCreate()

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

Isso parece se comportar como eu esperava. Não há necessidade de lidar com alterações na configuração, etc. Eu precisava disso para uma Atividade com um TextView longo (instruções).

Jim
fonte
Por que não fazer isso apenas com a visualização raiz?
CJBS
14

Escreva esta linha no seu Layout pai ...

 android:focusableInTouchMode="true"
Vishal Vaishnav
fonte
resposta duplicada
Ricardo A.
13

Sim, eu fiz a mesma coisa - crie um layout linear 'fictício' que obtenha o foco inicial. Além disso, defino os 'próximos' IDs de foco para que o usuário não possa mais focá-lo depois de rolar uma vez:

<LinearLayout 'dummy'>
<EditText et>

dummy.setNextFocusDownId(et.getId());

dummy.setNextFocusUpId(et.getId());

et.setNextFocusUpId(et.getId());

muito trabalho apenas para se livrar do foco em uma exibição ..

obrigado

marca
fonte
12

Para mim, o que funcionou em todos os dispositivos é o seguinte:

    <!-- 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 colocar isso como uma visão antes da visão focada problemática, e é isso.

desenvolvedor android
fonte
10

A coisa mais simples que fiz foi focar em outra visualização no onCreate:

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

Isso interrompeu o teclado virtual e não havia cursor piscando no EditText.

Lumis
fonte
10

Esta é a solução perfeita e mais fácil. Sempre uso isso no meu aplicativo.

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

fonte
Isso não desfoca o campo de texto: apenas oculta o teclado. Você ainda receberá uma dica que é enviada para fora do campo, e qualquer seletor de estado de cor exibirá o 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
fonte
8

Escreva esse código dentro do Manifestarquivo em Activityque você não deseja abrir o teclado.

android:windowSoftInputMode="stateHidden"

Arquivo de manifesto:

 <?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>
Tarit Ray
fonte
2
Isso não desfoca o campo de texto: apenas oculta o teclado. Você ainda receberá uma dica que é enviada para fora do campo, e qualquer seletor de estado de cor exibirá o estado "focus = true".
Rager
7

Na onCreatesua Atividade, basta adicionar uso clearFocus()ao seu elemento EditText. Por exemplo,

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

E se você quiser desviar o foco para outro elemento, use requestFocus()isso. Por exemplo,

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

Eu uso o código a seguir para impedir que um EditText roube o foco quando meu botão é pressionado.

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

Basicamente, oculte o texto de edição e mostre-o novamente. Isso funciona para mim, pois o EditText não é em exibição, portanto, não importa se está sendo exibido.

Você pode tentar ocultar e mostrá-lo em sucessão para ver se isso ajuda a perder o foco.

drei01
fonte