Jak powstrzymać EditText przed skupieniem się na starcie Activity w Androidzie

2871

Mam Activityw Androidzie, z dwoma elementami:

  1. EditText
  2. ListView

Kiedy mój Activityzaczyna, EditTextnatychmiast ma fokus wejściowy (migający kursor). Nie chcę, aby jakakolwiek kontrola skupiała się na wejściu podczas uruchamiania. Próbowałem:

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

Brak szczęścia. Jak mogę przekonać, EditTextaby nie wybierać się po uruchomieniu Activity?

znak
źródło

Odpowiedzi:

2591

Doskonałe odpowiedzi od Luca i Marka, jednak brakuje dobrej próbki kodu. Dodanie tagu android:focusableInTouchMode="true"i android:focusable="true"układu nadrzędnego (np. LinearLayoutLub ConstraintLayout) jak w poniższym przykładzie naprawi problem.

<!-- 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
źródło
711
Co z ustawieniem układu nadrzędnego na android:focusableInTouchMode="true"!
Muhammad Babar
28
Doskonały! Dzięki ... Jedną z rzeczy, na które należy zwrócić uwagę, jest to, że manekin musi być UMIESZCZONY PRAWO PRZED elementem skupialnym !!! Miałem TextView między moim manekina a EditText i metoda nie działała!
maddob,
25
ustawienie Androida: focusableInTouchMode = "true" w układzie nadrzędnym było dobrym podejściem dzięki @Muhammad Babar
sujith s
7
Świetny kod, bardzo mi pomógł :) Aby spróbować go ulepszyć, android:focusableInTouchMode="true"cover android:focusable="true"+ trochę więcej, więc w tym przypadku android:focusable="true"jest niepotrzebny i można go usunąć. Dodatkowo widok fikcyjny może być Widok zamiast LinearLayout. Oszczędza to moc przetwarzania + oszczędza od niektórych ostrzeżeń. Tak więc, moim zaleceniem jest zastąpienie widoku manekina<View android:focusableInTouchMode="true" android:layout_width="0px" android:layout_height="0px"/>
Jacob R
20
@PietroRea Android ma irytujące zachowania auto-focus, które są wbudowane w podstawowe zachowanie jego struktury aplikacji. Jeśli powiesz mu, że tekst edycji uwalnia lub traci fokus, automatycznie podejmuje decyzję o tym, gdzie fokus się znajduje. Bez nowego obiektu, na który ma zostać przeniesione fokus, wybiera pierwszy element z możliwością aktywacji w układzie, nawet jeśli ten element właśnie wyczyścił fokus! To trochę szalone i frustrujące, ale może istnieje uzasadniony powód takiego zachowania.
Weston Wedding
1674

Czy faktyczny problem polega na tym, że po prostu nie chcesz, żeby się skupiał? A może nie chcesz, aby pokazywała wirtualną klawiaturę w wyniku skupienia EditText? Naprawdę nie widzę problemu z EditTextskupieniem się na starcie, ale zdecydowanie jest problem z otwarciem okna softInput, gdy użytkownik nie poprosił wyraźnie o skupienie się na EditText(i w rezultacie otwórz klawiaturę).

Jeśli jest to problem z klawiaturą wirtualną, zobacz dokumentację AndroidManifest.xml elementu <activity> .

android:windowSoftInputMode="stateHidden" - zawsze chowaj to, wchodząc w działanie.

lub android:windowSoftInputMode="stateUnchanged"- nie zmieniaj go (np. nie pokazuj go, jeśli nie jest jeszcze pokazany, ale jeśli był otwarty podczas wchodzenia w działanie, pozostaw to otwarte).

Joe
źródło
24
mimo to kursor znajduje się w pierwszym edytorze tekstu w układzie - mimo że klawiatura nie jest wyświetlana
martyglaubitz
39
@Anderson: Nic w odpowiedzi nie sugeruje, że uniemożliwiłoby to EditTextskupienie się. W rzeczywistości wyraźnie stwierdza, że ​​w ten sposób zapobiega się automatycznemu otwieraniu edytora IME klawiatury programowej ; ponieważ bardziej prawdopodobne jest, że większym problemem będzie nieoczekiwanie wyskakująca miękka klawiatura, a nie sama ostrość. Jeśli twój problem w EditTextogóle się koncentruje, skorzystaj z odpowiedzi innej osoby.
Joe
1
ustaw programowo: stackoverflow.com/questions/6138330/...
Nick Franceschina,
3
Nie rób tego podczas aktywności z aparatem - psuje to czas lampy błyskowej (nie pytaj mnie dlaczego)
Daniel Wilson
1
@Joe to pytanie nie dotyczy ukrywania klawiatury podczas uruchamiania. Takie pytanie zostało zadane
user924
1140

Istnieje prostsze rozwiązanie. Ustaw następujące atrybuty w układzie nadrzędnym:

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

A teraz, gdy aktywność się zacznie, ten główny układ zostanie domyślnie ustawiony na fokus.

Możemy również usunąć fokus z widoków podrzędnych w czasie wykonywania (np. Po zakończeniu edycji podrzędnej), ponownie nadając fokus układowi głównemu:

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

Dobry komentarz od Guillaume Perrot :

android:descendantFocusability="beforeDescendants"wydaje się być wartością domyślną (wartość całkowita wynosi 0). Działa tylko poprzez dodanie android:focusableInTouchMode="true".

Naprawdę możemy zobaczyć, że beforeDescendantszestaw jest domyślny w ViewGroup.initViewGroup()metodzie (Android 2.2.2). Ale nie równa 0.ViewGroup.FOCUS_BEFORE_DESCENDANTS = 0x20000;

Dzięki Guillaume.

Srebro
źródło
1
Ważne jest, aby ustawić te atrybuty na bezpośredni element nadrzędny widoku, który skupia się na tworzeniu aktywności, w przeciwnym razie nie zadziała.
tomrozb
4
Po prostu idealne rozwiązanie. Działa zarówno: 1. Wyłączanie autofokusa, jak i 2. Wyłącz automatyczne otwieranie miękkiej klawiatury
poznaj
Miły. Nie musi być bezpośrednim rodzicem. Ustawiłem go na poziomie układu głównego i wydaje się, że działa dobrze.
Kurotsuki
@DanielWilson, kiedy chcesz przewijać widok jako bezpośredni rodzic edytowanego tekstu?
Mark Buikema
Musisz pracować z miękkimi danymi
Ready Android
426

Jedyne znalezione przeze mnie rozwiązanie to:

  • Utwórz układ liniowy (nie wiem, czy działają inne układy )
  • Ustaw atrybuty android:focusable="true"iandroid:focusableInTouchMode="true"

I EditTextnie skupi się po rozpoczęciu aktywności

Luc
źródło
Prosty!! Początkowo dodałem te właściwości do widoku nadrzędnego, co nie powiodło się, następnie ustawiłem je na inny układ i działałem dobrze. Dzięki!!
Rino
Działa również z ConstraintLayout.
Hawklike
85

Problem wydaje się wynikać z właściwości, którą widzę tylko w XML formukładzie.

Pamiętaj o usunięciu tego wiersza na końcu deklaracji w EditTexttagach XML:

<requestFocus />

To powinno dać coś takiego:

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

   //<requestFocus /> /* <-- without this line */
</EditText>
Floydaddict
źródło
77

korzystając z informacji dostarczonych przez inne plakaty, zastosowałem następujące rozwiązanie:

w układzie 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"/>

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

i wreszcie w onResume ()

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

    //do not give the editbox focus automatically when activity starts
    mAutoCompleteTextView.clearFocus();
    mLinearLayout.requestFocus();
}
Ktoś gdzieś
źródło
73

Spróbuj clearFocus () zamiast setSelected(false). Każdy widok w Androidzie ma zarówno możliwość ustawiania ostrości, jak i wybierania, i myślę, że chcesz po prostu wyczyścić ostrość.

Eric Mill
źródło
Brzmi obiecująco, ale w którym punkcie cyklu życia działania należy to nazwać? Jeśli wywołam to w funkcji onCreate (), obiekt EditText nadal będzie aktywny. Czy należy go wywołać w onResume () czy w innej lokalizacji? Dzięki!
Mark
8
Połączyłem zaakceptowaną odpowiedź z tą odpowiedzią. Zadzwoniłem myEditText.clearFocus(); myDummyLinearLayout.requestFocus();w onResumeramach działania. Dzięki temu EditText nie utrzymywał ostrości, gdy telefon był obrócony.
teedyay
71

Poniższe spowoduje, że edytowany tekst nie będzie się skupiał po utworzeniu, ale złapie go, gdy go dotkniesz.

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

Więc ustawiłeś focus na false w xml, ale klucz znajduje się w Javie, do której dodajesz następujący detektor:

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

Ponieważ zwracasz wartość false, tzn. Nie konsumujesz zdarzenia, zachowanie skupienia będzie przebiegać normalnie.

MinceMan
źródło
6
Ale to nigdy nie zyska koncentracji w przyszłości, jak po prostu przestać koncentrować się tylko na początku (rozpoczęcie działalności)?
Jayesh
1
OnTouchListener jest wywoływany przed innymi akcjami dotykowymi. Dzięki włączeniu funkcji ustawiania ostrości za pomocą dotyku standardowe ustawianie ostrości odbywa się za pierwszym razem. Klawiatura się pojawi i wszystko.
MinceMan
1
Myślę, że to najlepszy sposób, aby to zrobić. Ponadto powyższy kod magicznego manekina xml mumbo-jumbo NIE działał dla złożonego zestawu edytowanych tekstów ... Jeśli to zadziała, na pewno zagłosuję.
Radu,
Ale jeśli masz wiele tekstów edycji, skupi się na następnym tekście edycji i otworzy klawiaturę, więc lepiej jest dodać Androida: windowSoftInputMode = "stateAlwaysHidden" w manifestie dla określonej aktywności.
Karan sharma
Uwaga: w Androidzie P system nie będzie już domyślnie ustawiony. Oznacza to, że ten hack nie jest konieczny, zaczynając od P.
MinceMan
65

Próbowałem kilka odpowiedzi osobno, ale fokus jest nadal edytowany. Udało mi się to rozwiązać tylko przy użyciu dwóch poniższych rozwiązań.

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

(Referencje od Silver https://stackoverflow.com/a/8639921/15695 )

i usuń

 <requestFocus />

w EditText

(Odwołanie od floydaddict https://stackoverflow.com/a/9681809 )

Lee Yi Hong
źródło
1
Musiałem dodać edittext.clearFocus () oprócz powyższego, aby działało :)
Nav
57

Późna, ale najprostsza odpowiedź, po prostu dodaj to w nadrzędnym układzie XML.

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

Głosuj, jeśli ci to pomogło! Happy Coding :)

Rishabh Saxena
źródło
2
działało dla mnie idealnie. jeszcze jedna rzecz, na którą należy zwrócić uwagę, nie dodawaj tych linii do przewijania widoku. Nie działa w widoku przewijania. Ale działał idealnie z układem liniowym.
Karthic Srinivasan
46

Żadne z tych rozwiązań nie działało dla mnie. Sposób, w jaki naprawiłem autofocus, to:

<activity android:name=".android.InviteFriendsActivity" android:windowSoftInputMode="adjustPan">
    <intent-filter >
    </intent-filter>
</activity>
rallat
źródło
2
android: windowSoftInputMode = "adjustPan" na dowolnej aktywności w Manifeście na Androida
rallat
43

Proste rozwiązanie: AndroidManifestw Activityużyciu tagu

android:windowSoftInputMode="stateAlwaysHidden"
Sergey Sheleg
źródło
6
Ściśle mówiąc, to nie rozwiązuje problemu. OP powiedział: „Nie chcę, aby jakakolwiek kontrola koncentrowała się na danych wejściowych podczas uruchamiania”. Twoje rozwiązanie ukrywa tylko klawiaturę, istnieje subtelna różnica.
katzenhut
@katzenhut tak, to właśnie mój problem z tą odpowiedzią. Skupienie się na moim tekście edycyjnym otwiera działanie PlaceAutoComplete, więc odpowiedź jest niepełna
Zach.
Odpowiedź byłaby kompletna, gdyby pytanie brzmiało: jak zawsze upewnić się, że moja aktywność nigdy nie pokazuje klawiatury. Który nie jest.
Martin Marconcini
37

Możesz po prostu ustawić ustawialne i „ustawialne w trybie dotykowym”, aby wartość true była ustawiona na pierwszym TextViewz layout. W ten sposób, po uruchomieniu działalności za TextViewskupi się jednak, ze względu na swój charakter, widać nic koncentruje się na ekranie i, oczywiście, nie będzie bez klawiatury wyświetlane ...

Zeus
źródło
działa idealnie dla mnie, tylko ustawiłem wartość na najbardziej zewnętrznym układzie w mojej działalności, a nie na pierwszy podgląd tekstu
Maverick1st
36

Poniższe działało dla mnie w Manifest. Pisać ,

<activity
android:name=".MyActivity"
android:windowSoftInputMode="stateAlwaysHidden"/>
Babar Sana
źródło
1
Nie usuwa to ostrości pola tekstowego: jedynie ukrywa klawiaturę. Nadal dostaniesz wskazówkę wypchniętą z pola, a wszelkie selektory stanów kolorów wyświetlą stan „skoncentrowany = prawda”.
A. Rager
31

Musiałem programowo usunąć skupienie ze wszystkich dziedzin. Właśnie dodałem następujące dwie instrukcje do mojej głównej definicji układu.

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

Otóż ​​to. Natychmiast naprawiłem mój problem. Dzięki, Silver, za wskazanie mi właściwego kierunku.

jakeneff
źródło
28

Dodaj android:windowSoftInputMode="stateAlwaysHidden"znacznik aktywności Manifest.xmlpliku.

Źródło

prgmrDev
źródło
1
Nie usuwa to ostrości pola tekstowego: jedynie ukrywa klawiaturę. Nadal dostaniesz wskazówkę wypchniętą z pola, a wszelkie selektory stanów kolorów wyświetlą stan „skoncentrowany = prawda”.
A. Rager
25

Jeśli masz inny pogląd na swoją aktywność, np. ListView, Możesz również:

ListView.requestFocus(); 

w twoim onResume()celu skupienia się na editText.

Wiem, że udzielono odpowiedzi na to pytanie, ale po prostu zapewniłem alternatywne rozwiązanie, które zadziałało :)

Sid
źródło
22

Wypróbuj to przed pierwszym edytowalnym polem:

<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
źródło
21

Dodaj następującą onCreatemetodę:

this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Vishal Raj
źródło
1
Nie usuwa to ostrości pola tekstowego: jedynie ukrywa klawiaturę. Nadal dostaniesz wskazówkę wypchniętą z pola, a wszelkie selektory stanów kolorów wyświetlą stan „skoncentrowany = prawda”.
A. Rager
17

Ponieważ nie lubię zanieczyszczać XML-a czymś, co jest związane z funkcjonalnością, stworzyłem tę metodę, która „transparentnie” kradnie fokus od pierwszego widoku, na którym można ustawić fokus, a następnie usuwa się w razie potrzeby!

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
źródło
15

Spóźniony, ale może pomocny. Tworzenie EditText manekina w górnej części układu następnie wywołać myDummyEditText.requestFocus()wonCreate()

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

To wydaje się zachowywać tak, jak się spodziewam. Nie trzeba obsługiwać zmian konfiguracji itp. Potrzebowałem tego do działania z długim TextView (instrukcje).

Jim
źródło
Dlaczego nie zrobić tego z samym widokiem głównym?
CJBS
14

Napisz ten wiersz w układzie nadrzędnym ...

 android:focusableInTouchMode="true"
Vishal Vaishnav
źródło
zduplikowana odpowiedź
Ricardo A.
13

Tak, zrobiłem to samo - stworzyłem „obojętny” układ liniowy, który początkowo się skupia. Ponadto ustawiam identyfikatory „następnego” fokusa, aby użytkownik nie mógł już ustawić ostrości po przewinięciu:

<LinearLayout 'dummy'>
<EditText et>

dummy.setNextFocusDownId(et.getId());

dummy.setNextFocusUpId(et.getId());

et.setNextFocusUpId(et.getId());

dużo pracy, żeby się nie skupić na widoku ...

Dzięki

znak
źródło
12

Dla mnie to, co działało na wszystkich urządzeniach, to:

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

Po prostu umieść to jako widok przed problematycznym widokiem skoncentrowanym i to wszystko.

programista Androida
źródło
10

Najprostszą rzeczą, jaką zrobiłem, jest skupienie się na innym widoku w programie onCreate:

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

To zatrzymało zbliżanie się miękkiej klawiatury i nie było migania kursora w EditText.

Lumis
źródło
10

To idealne i najłatwiejsze rozwiązanie. Zawsze używam tego w mojej aplikacji.

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

źródło
Nie usuwa to ostrości pola tekstowego: jedynie ukrywa klawiaturę. Nadal dostaniesz wskazówkę wypchniętą z pola, a wszelkie selektory stanów kolorów wyświetlą stan „skoncentrowany = prawda”.
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
źródło
8

Wpisz ten kod w Manifestpliku, w Activityktórym nie chcesz otwierać klawiatury.

android:windowSoftInputMode="stateHidden"

Plik manifestu:

 <?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
źródło
2
Nie usuwa to ostrości pola tekstowego: jedynie ukrywa klawiaturę. Nadal dostaniesz wskazówkę wypchniętą z pola, a wszelkie selektory stanów kolorów wyświetlą stan „skoncentrowany = prawda”.
A. Rager
7

W onCreateswojej działalności po prostu dodaj użycie clearFocus()elementu EditText. Na przykład,

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

A jeśli chcesz zmienić fokus na inny element, użyj requestFocus()tego. Na przykład,

button = (Button) findViewById(R.id.button);
button.requestFocus();
Compaq LE2202x
źródło
6

Używam następującego kodu, aby zatrzymać kradzież fokusu EditText po naciśnięciu mojego przycisku.

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

Zasadniczo ukryj edytowany tekst, a następnie pokaż go ponownie. To działa dla mnie, ponieważ EditText nie jest widoczny, więc nie ma znaczenia, czy się wyświetla.

Możesz spróbować ukryć i pokazywać go kolejno, aby sprawdzić, czy to pomoże mu stracić koncentrację.

drei01
źródło