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?

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

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


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


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.


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


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>

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

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


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.


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 )


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


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>

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"

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


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

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.


28

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

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


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

21

Dodaj następującą onCreatemetodę:

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

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

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


Dlaczego nie zrobić tego z samym widokiem głównym?
CJBS


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


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.


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.


10

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

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

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

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>

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

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.