Android'de Etkinlik başlangıcında EditText'in odaklanmasını engelleme


2872

Bir var Activityiki unsurlarla, Android'de:

  1. EditText
  2. ListView

Başladığımda Activity, EditTexthemen giriş odağı var (yanıp sönen imleç). Hiçbir denetimin başlangıçta giriş odağı olmasını istemiyorum. Denedim:

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

Şanssız. Başlangıçta EditTextkendisini seçmemeye nasıl ikna edebilirim Activity?

Yanıtlar:


2593

Luc ve Mark'dan gelen mükemmel cevaplar, ancak iyi bir kod örneği eksik. Etiketi android:focusableInTouchMode="true"ve aşağıdaki örnekteki gibi android:focusable="true"üst düzene (örn. LinearLayoutVeya ConstraintLayout) eklemek sorunu çözecektir.

<!-- 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
Üst düzeni ayarlamaya ne dersiniz android:focusableInTouchMode="true"?
Muhammed Babar

28
Mükemmel! Teşekkürler ... Dikkat edilmesi gereken bir şey, kukla öğenin odaklanabilir öğeden ÖNCE SAĞLANMASI gerektiğidir !!! Benim kukla ve EditText arasında bir TextView vardı ve yöntem işe yaramadı!
maddob

25
android ayarlamak: focusableInTouchMode = Üst düzene doğru "true" iyi bir yaklaşım oldu teşekkürler @Muhammad Babar
s

7
Büyük kod, bana çok yardımcı oldu :) Üzerine geliştirmeye çalışmak için, + biraz daha android:focusableInTouchMode="true"kapsar android:focusable="true", bu durumda android:focusable="true"gereksizdir ve kaldırılabilir. Ayrıca kukla görünüm, LinearLayout yerine bir Görünüm olabilir. Bu işlem gücünü azaltır + sizi bazı Uyarılardan kurtarır. Böylece, benim tavsiyem kukla görüş yerine<View android:focusableInTouchMode="true" android:layout_width="0px" android:layout_height="0px"/>
Jacob R ile

20
@PietroRea Android, uygulama yapısının temel davranışına yerleştirilmiş sinir bozucu otomatik odaklama davranışlarına sahiptir. Bir düzenleme metninin odağı serbest bıraktığını veya kaybettiğini söylerseniz, odağın nereye gittiğine otomatik olarak karar verir. Odak için aktarılacak yeni bir nesne olmadan, o öğe odağını temizleyen öğe olsa bile mizanpajdaki ilk odaklanabilir öğeyi seçer! Biraz fındık ve sinir bozucu, ama belki de bu tür davranışların geçerli bir nedeni var.
Weston Wedding

1676

Asıl sorun sadece odaklanmasını istemiyor mu? Veya odaklanmanın bir sonucu olarak sanal klavyeyi göstermesini istemiyor EditTextmusunuz? Gerçekten EditTextbaşlangıç ​​odaklanma ile ilgili bir sorun görmüyorum , ancak kullanıcı açıkça odaklanmak istemediğinde EditText(ve sonuç olarak klavyeyi açmak) softInput penceresini açmak kesinlikle bir sorun .

Sanal klavyenin sorunu varsa, AndroidManifest.xml <aktivite> öğesi belgelerine bakın.

android:windowSoftInputMode="stateHidden" - aktiviteye girerken daima saklayın.

ya android:windowSoftInputMode="stateUnchanged"- (örn yok değiştirmemesi göstermek zaten gösterilmez ise bunu ancak faaliyeti girerken Açık olsaydı, o açık bırakın).


24
yine de imleç düzende ilk EditText'te - klavye gösterilmemesine rağmen
martyglaubitz

39
@Anderson: Cevabı hakkında hiçbir şey, EditTextodaklanmayı engelleyeceğini ima etmiyordu . Aslında, yazılım klavyesi IME'sinin odakta otomatik olarak açılmasını nasıl önlediğinizi açıkça belirtir ; çünkü daha büyük endişe, odaklanmanın kendisi değil , beklenmedik bir şekilde ortaya çıkan yumuşak klavyedir . Sorununuz EditTextaslında hiç odaklanma ile ilgiliyse, başka birinin cevabını kullanın.
Joe


3
Bunu bir kamerayla yapılan bir etkinlik için yapma - flaşın zamanlamasını bozuyor (bana nedenini sorma)
Daniel Wilson

1
@ Bu soru klavyeyi başlangıçta gizlemekle ilgili değil. Böyle bir soru burada soruldu stackoverflow.com/questions/18977187/…
user924

1141

Daha basit bir çözüm var. Bu özellikleri üst düzeninizde ayarlayın:

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

Ve şimdi, etkinlik başladığında bu ana düzen varsayılan olarak odaklanacaktır.

Ayrıca, odağı ana düzenine tekrar aşağıdaki gibi vererek, çalışma zamanında çocuk görünümlerinden (örneğin, çocuk düzenlemesini bitirdikten sonra) kaldırabiliriz:

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

İyi yorum dan Guillaume Perrot :

android:descendantFocusability="beforeDescendants"varsayılan gibi görünüyor (tamsayı değeri 0'dır). Sadece ekleyerek çalışır android:focusableInTouchMode="true".

Gerçekten, beforeDescendantssetin ViewGroup.initViewGroup()yöntemde varsayılan olduğunu görebiliriz (Android 2.2.2). Ama 0'a eşit değil.ViewGroup.FOCUS_BEFORE_DESCENDANTS = 0x20000;

Guillaume'ye teşekkürler.


1
Bu nitelikleri , etkinlik oluşturmaya odaklanan görünümün doğrudan üst öğesine ayarlamak önemlidir , aksi takdirde çalışmaz.
tomrozb

4
Mükemmel bir çözüm. Her ikisi için de çalışır: 1.Otomatik odaklamayı devre dışı bırakma ve 2. Yumuşak klavyenin otomatik açılmasını devre dışı bırakma
tanışın

Güzel. Doğrudan ebeveyn olması gerekmez. Düzeni kök düzeyinde ayarladım ve iyi çalışıyor gibi görünüyor.
Kurotsuki

@DanielWilson bir düzenleme metninin doğrudan üst öğesi olarak ne zaman bir kaydırma görünümü istersiniz?
Mark Buikema


427

Bulduğum tek çözüm:

  • LinearLayout oluşturun (diğer Layout türlerinin çalışıp çalışmadığını bilmiyorum)
  • Özellikleri ayarlayın android:focusable="true"veandroid:focusableInTouchMode="true"

Ve EditTextfaaliyete başladıktan sonra odaklanmayacak


Basit!! Başlangıçta bu özellikleri üst görünümüne ekledim, bu da başarısız oldu, sonra bunları başka bir düzene ayarladım ve iyi çalıştım. Teşekkürler!!
Rino

Bir ConstraintLayout ile de çalışır.
Hawklike

86

Sorun, sadece XML formdüzeninde görebildiğim bir özellikten geliyor gibi görünüyor .

EditTextXML etiketlerindeki bildirimin sonunda bu satırı kaldırdığınızdan emin olun :

<requestFocus />

Bu böyle bir şey vermelidir:

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

   //<requestFocus /> /* <-- without this line */
</EditText>

78

diğer posterler tarafından sağlanan bilgileri kullanarak, aşağıdaki çözümü kullandım:

XML düzeninde

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

onCreate () içinde

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

ve son olarak, onResume () içinde

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

    //do not give the editbox focus automatically when activity starts
    mAutoCompleteTextView.clearFocus();
    mLinearLayout.requestFocus();
}

74

Bunun yerine clearFocus () yöntemini deneyin setSelected(false). Android'deki her görünümün hem odaklanabilirlik hem de seçilebilirliği vardır ve bence odağı netleştirmek istiyorsunuz.


Kulağa umut verici geliyor, ancak Etkinlik yaşam döngüsünün hangi noktasına çağrılmalı? Ben onCreate () içinde çağırırsanız, EditText hala odak vardır. OnResume () veya başka bir yerde mi çağrılmalı? Teşekkürler!
Mark

8
Kabul edilen cevabı bu cevapla birleştirdim. Aradım myEditText.clearFocus(); myDummyLinearLayout.requestFocus();içinde onResumeFaaliyet. Bu, telefon döndürüldüğünde EditText'in odağı korumamasını sağladı.
teedyay

71

Aşağıdakiler, düzenleme metninin oluşturulduğunda odaklanmasını durdurur, ancak dokunduğunuzda onu yakalar.

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

Böylece xml'de odaklanabilir değerini false olarak ayarlarsınız, ancak anahtar java'dadır ve aşağıdaki dinleyiciyi eklersiniz:

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

False döndürdüğünüz için, yani etkinliği tüketmediğiniz için, odaklama davranışı normal gibi devam eder.


6
Ama bu gelecekte asla odaklanmayacak, sadece başlangıç ​​için (faaliyet başlangıcı) odak nasıl durdurulur ??
Jayesh

1
OnTouchListener, diğer dokunma eylemlerinden önce çağrılır. Böylece dokunmaya odaklanmayı etkinleştirerek standart odak ilk dokunuşta gerçekleşir. Klavye çıkacak ve her şey gelecek.
MinceMan

1
Bence bunu yapmanın en iyi yolu bu. Ayrıca, yukarıdaki mumbo-jumbo xml sihirli kukla kodu düzenleme metinleri karmaşık bir dizi için işe yaramadı ... Bu işe yarar, ben kesinlikle oy.
Radu

Ancak birden fazla düzenleme metniniz varsa, bir sonraki düzenleme metnine odaklanacak ve klavyeyi açacak, böylece belirli bir etkinlik için manifest'te android: windowSoftInputMode = "stateAlwaysHidden" eklemek daha iyi olacaktır .
Karan sharma

Not: Android P'de sistem artık varsayılan bir odaklamayacaktır. Bu, P ile başlayan bu
hackin

65

Ayrı ayrı birkaç cevap denedim ama odak hala EditText. Bunu sadece aşağıdaki çözümlerden ikisini birlikte kullanarak çözmeyi başardım.

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

(Silver referansı https://stackoverflow.com/a/8639921/15695 )

ve kaldır

 <requestFocus />

EditText'te

(Floydaddict https://stackoverflow.com/a/9681809 referansı )


1
Çalıştırmak için yukarıdakilere ek olarak edittext.clearFocus () eklemek zorunda kaldım :)
Nav

57

Geç ama en basit cevap, bunu XML'in üst düzenine eklemeniz yeterlidir.

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

Size yardımcı olduysa oy verin! Mutlu Kodlama :)


2
benim için mükemmel çalıştı. not edilmesi gereken bir şey daha, görünümü kaydırmak için bu satırları eklemeyin. Kaydırma görünümünde çalışmaz. Ama doğrusal düzen ile mükemmel çalıştı.
Karthic Srinivasan

46

Bu çözümlerin hiçbiri benim için işe yaramadı. Otomatik odaklamayı düzeltmenin yolu şuydu:

<activity android:name=".android.InviteFriendsActivity" android:windowSoftInputMode="adjustPan">
    <intent-filter >
    </intent-filter>
</activity>

2
android: windowSoftInputMode = Android Manifest'teki herhangi bir etkinlikte "adjustPan"
rallat

43

Basit çözüm: In AndroidManifestiçinde Activityetiketinin kullanıma

android:windowSoftInputMode="stateAlwaysHidden"

6
Açıkçası, bu sorunu çözmez. OP şöyle dedi: "Başlangıçta herhangi bir kontrolün giriş odağı olmasını istemiyorum." Çözümünüz sadece klavyeyi gizler, bir sublte farkı vardır.
katzenhut

@katzenhut evet, tam olarak bu cevapla ilgili sorunum bu. Düzenleme metnime odaklanmak bir PlaceAutoComplete etkinliği açıyor, bu yüzden bu cevap eksik
Zach

Soru şu olsaydı bu cevap tamamlanmış olurdu: Aktivitemin asla bir klavye göstermediğinden nasıl emin olabilirim. Hangisi değil.
Martin Marconcini

37

Sadece ayarlayabilirsiniz "odaklanabilir" ve "dokunmatik modunda odaklanabilir" ilk true değerine TextViewait layout. Bu şekilde etkinlik başladığında TextViewodaklanılır, ancak doğası gereği ekrana odaklanmış hiçbir şey görmezsiniz ve elbette hiçbir klavye görüntülenmez ...


benim için mükemmel çalışıyor, sadece ilk metin görünümüne değil, aktivitemizin en dış düzeninde değeri ayarladım
Maverick1st

36

Aşağıdaki benim için çalıştı Manifest. Yazmak ,

<activity
android:name=".MyActivity"
android:windowSoftInputMode="stateAlwaysHidden"/>

1
Bu, metin alanının odaklamasını kaldırmaz: yalnızca klavyeyi gizler. Hala alanın dışına itilen bir ipucu alırsınız ve tüm renk durumu seçicileri "odaklanmış = doğru" durumunu görüntüler.
A.Rager

31

Odaklanmayı programsal olarak tüm alanlardan temizlemem gerekiyordu. Ana düzen tanımıma aşağıdaki iki ifadeyi ekledim.

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

Bu kadar. Sorunumu anında çözdüm. Beni doğru yöne yönlendirdiğin için teşekkürler Silver.


28

Dosyanın android:windowSoftInputMode="stateAlwaysHidden"etkinlik etiketine ekleyin Manifest.xml.

Kaynak


1
Bu, metin alanının odaklamasını kaldırmaz: yalnızca klavyeyi gizler. Hala alanın dışına itilen bir ipucu alırsınız ve tüm renk durumu seçicileri "odaklanmış = doğru" durumunu görüntüler.
A.Rager

25

Etkinlikleriniz hakkında a gibi başka bir görünümünüz ListViewvarsa şunları da yapabilirsiniz:

ListView.requestFocus(); 

Gözlerinde farklı onResume()odak kapmak için editText.

Bu sorunun cevaplandığını biliyorum, ama sadece benim için çalışan alternatif bir çözüm sağladım :)


22

İlk düzenlenebilir alanınızdan önce bunu deneyin:

<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

Aşağıdaki onCreateyöntemi ekleyin :

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

1
Bu, metin alanının odaklamasını kaldırmaz: yalnızca klavyeyi gizler. Hala alanın dışına itilen bir ipucu alırsınız ve tüm renk durumu seçicileri "odaklanmış = doğru" durumunu görüntüler.
A.Rager

17

XML'i işlevsellik ile ilgili bir şeyle kirletmek istemediğim için, "şeffaf bir şekilde" ilk odaklanabilir görünümden odağı çalan ve sonra gerektiğinde kendini kaldırmayı sağlayan bu yöntemi oluşturdum!

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

Geç, ama belki de yararlı. Sonra diyoruz Düzeninize üstünde bir kukla EditText oluşturun myDummyEditText.requestFocus()içindeonCreate()

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

Beklediğim gibi görünüyor. Yapılandırma değişiklikleri, vb işlemek gerek yok Ben uzun bir TextView (talimatlar) ile bir Etkinlik için bu gerekli.


Neden bunu sadece kök görünümün kendisi ile yapmıyoruz?
CJBS


13

Evet aynı şeyi yaptım - ilk odak noktasını alan 'kukla' doğrusal bir düzen yaratın. Ayrıca, 'sonraki' odak kimliklerini ayarladım, böylece kullanıcı bir kez kaydırdıktan sonra odaklanamaz:

<LinearLayout 'dummy'>
<EditText et>

dummy.setNextFocusDownId(et.getId());

dummy.setNextFocusUpId(et.getId());

et.setNextFocusUpId(et.getId());

sadece bir manzaraya odaklanmak için çok fazla iş ..

Teşekkürler


12

Benim için, tüm cihazlarda çalışan şey şudur:

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

Sorunlu odaklı görüşten önce bunu bir görünüm olarak koyun ve hepsi bu.


10

Yaptığım en basit şey onCreate'daki başka bir görünüme odaklanmak.

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

Bu, yumuşak klavyenin çıkmasını durdurdu ve EditText'te yanıp sönen bir imleç yoktu.


10

Bu mükemmel ve en kolay çözümdür.Ben her zaman benim app kullanın.

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

Bu, metin alanının odaklamasını kaldırmaz: yalnızca klavyeyi gizler. Hala alanın dışına itilen bir ipucu alırsınız ve tüm renk durumu seçicileri "odaklanmış = doğru" durumunu görüntüler.
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

Bu kodu klavyeyi açmak istemediğiniz Manifestdosyanın içine yazın Activity.

android:windowSoftInputMode="stateHidden"

Bildirim dosyası:

 <?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
Bu, metin alanının odaklamasını kaldırmaz: yalnızca klavyeyi gizler. Hala alanın dışına itilen bir ipucu alırsınız ve tüm renk durumu seçicileri "odaklanmış = doğru" durumunu görüntüler.
A. Rager

7

At onCreatesenin Faaliyet, sadece kullanımını eklemek clearFocus()için EditText elemanı üzerinde. Örneğin,

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

Ve odağı başka bir öğeye yönlendirmek istiyorsanız, bunu kullanın requestFocus(). Örneğin,

button = (Button) findViewById(R.id.button);
button.requestFocus();

6

Düğmeye basıldığında bir EditText odak odak çalmasını durdurmak için aşağıdaki kodu kullanın.

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

Temel olarak, düzenleme metnini gizleyin ve tekrar gösterin. EditText olmadığı için bu benim için çalışıyor görünümünde bu yüzden gösterilip gösterilmemesi önemli değil.

Odağı kaybetmesine yardımcı olup olmadığını görmek için gizlemeyi ve art arda göstermeyi deneyebilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.