Bagaimana cara menghentikan EditText untuk mendapatkan fokus saat Startup aktivitas di Android


2873

Saya punya Activitydi Android, dengan dua elemen:

  1. EditText
  2. ListView

Ketika saya Activitymulai, EditTextsegera memiliki fokus input (kursor berkedip). Saya tidak ingin kontrol memiliki fokus input saat startup. Saya mencoba:

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

Tidak berhasil Bagaimana saya bisa meyakinkan EditTextuntuk tidak memilih sendiri ketika Activitymulai?

Jawaban:


2593

Jawaban yang sangat baik dari Luc dan Mark namun sampel kode yang baik tidak ada. Menambahkan tag android:focusableInTouchMode="true"dan android:focusable="true"tata letak induk (misalnya LinearLayoutatau ConstraintLayout) seperti contoh berikut akan memperbaiki masalah.

<!-- 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
Bagaimana dengan mengatur tata letak indukandroid:focusableInTouchMode="true" !
Muhammad Babar

28
Sempurna! Terima kasih ... Satu hal yang perlu diperhatikan adalah bahwa item dummy harus DITEMPATKAN SEBELUM elemen fokus !!! Saya memiliki TextView antara boneka saya dan EditText dan metode ini tidak berfungsi!
maddob

25
pengaturan android: focusableInTouchMode = "true" untuk tata letak induk adalah pendekatan yang baik terima kasih @Muhammad Babar
sujith s

7
Kode hebat, banyak membantu saya :) Untuk mencoba memperbaikinya, android:focusableInTouchMode="true"mencakup android:focusable="true"+ beberapa lagi, jadi dalam hal android:focusable="true"ini tidak perlu, dan dapat dihapus. Selain itu tampilan dummy dapat berupa Tampilan alih-alih LinearLayout. Ini menghemat daya pemrosesan + menyelamatkan Anda dari beberapa Peringatan. Dengan demikian, rekomendasi saya mengganti pandangan dummy dengan<View android:focusableInTouchMode="true" android:layout_width="0px" android:layout_height="0px"/>
Jacob R

20
@PietroRea Android memiliki perilaku fokus otomatis yang menjengkelkan yang dibangun ke dalam perilaku inti dari struktur aplikasinya. Jika Anda memberi tahu bahwa teks edit melepaskan atau kehilangan fokus, secara otomatis membuat keputusan tentang ke mana fokusnya. Tanpa objek baru untuk ditransfer fokus, ia mengambil elemen yang dapat difokus pertama dalam tata letak bahkan ketika elemen itu adalah salah satu yang baru saja membersihkan fokusnya! Agak gila dan membuat frustrasi, tapi mungkin ada alasan yang valid untuk jenis perilaku ini.
Pernikahan Weston

1676

Apakah masalah sebenarnya yang tidak Anda inginkan adalah fokus sama sekali? Atau Anda tidak ingin menampilkan keyboard virtual sebagai hasil pemfokusan EditText? Saya tidak benar-benar melihat masalah dengan EditTextmemiliki fokus pada memulai, tetapi jelas merupakan masalah untuk membuka jendela softInput ketika pengguna tidak secara eksplisit meminta untuk fokus pada EditText(dan membuka keyboard sebagai hasilnya).

Jika itu masalah keyboard virtual, lihat dokumentasi AndroidManifest.xml elemen <activity> .

android:windowSoftInputMode="stateHidden" - selalu sembunyikan ketika memasuki aktivitas.

atau android:windowSoftInputMode="stateUnchanged"- jangan mengubahnya (mis. jangan perlihatkan jika belum ditampilkan, tetapi jika terbuka saat memasukkan aktivitas, biarkan terbuka).


24
namun kursor masih dalam EditText pertama dalam tata letak - meskipun keyboard tidak ditampilkan
martyglaubitz

39
@Anderson: Tidak ada jawaban yang menyiratkan bahwa itu akan mencegah EditTextdari mendapatkan fokus. Ini sebenarnya jelas menyatakan bahwa ini adalah bagaimana Anda mencegah IME keyboard perangkat lunak dari membuka secara otomatis pada fokus; karena itu lebih cenderung bahwa kekhawatiran yang lebih besar adalah keyboard lunak muncul tiba-tiba, bukan fokus itu sendiri. Jika masalah Anda terkait dengan EditTextfokus sebenarnya, gunakan jawaban orang lain.
Joe


3
Jangan lakukan ini pada aktivitas dengan kamera - itu merusak waktu flash (jangan tanya kenapa)
Daniel Wilson

1
@Jo, pertanyaan ini bukan tentang menyembunyikan keyboard saat startup. Pertanyaan semacam itu ditanyakan di sini stackoverflow.com/questions/18977187/…
user924

1141

Ada solusi yang lebih sederhana. Setel atribut ini di tata letak induk Anda:

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

Dan sekarang, ketika aktivitas dimulai, tata letak utama ini akan mendapatkan fokus secara default.

Selain itu, kami dapat menghapus fokus dari tampilan anak saat runtime (mis., Setelah menyelesaikan pengeditan anak) dengan memberikan fokus ke tata letak utama lagi, seperti ini:

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

Komentar bagus dari Guillaume Perrot :

android:descendantFocusability="beforeDescendants"tampaknya menjadi default (nilai integer adalah 0). Ini bekerja hanya dengan menambahkan android:focusableInTouchMode="true".

Sungguh, kita dapat melihat bahwa beforeDescendantsset sebagai default dalam ViewGroup.initViewGroup()metode (Android 2.2.2). Tapi tidak sama dengan 0.ViewGroup.FOCUS_BEFORE_DESCENDANTS = 0x20000;

Terima kasih untuk Guillaume.


1
Sangat penting untuk mengatur atribut ini ke induk langsung dari pandangan yang mendapatkan fokus pada pembuatan aktivitas, jika tidak maka tidak akan berhasil.
tomrozb

4
Solusi yang sempurna. Berfungsi untuk keduanya: 1.Mengaktifkan autofokus, dan 2. Nonaktifkan pembukaan otomatis keyboard lunak
Temui

Bagus. Tidak perlu menjadi orang tua langsung. Saya mengaturnya di tingkat root tata letak dan tampaknya berfungsi dengan baik.
Kurotsuki

@DanielWilson kapan Anda ingin scrollview sebagai induk langsung dari edittext?
Mark Buikema

Anda harus bekerja dengan input lunak jendela seperti readyandroid.wordpress.com/…
Ready Android

427

Satu-satunya solusi yang saya temukan adalah:

  • Buat LinearLayout (Saya tidak tahu apakah Layout lain akan berfungsi)
  • Atur atribut android:focusable="true"danandroid:focusableInTouchMode="true"

Dan EditTexttidak akan mendapatkan fokus setelah memulai aktivitas


Sederhana!! Saya awalnya menambahkan properti ini ke tampilan induk, yang gagal, lalu saya atur ini ke tata letak lain dan bekerja dengan baik. Terima kasih!!
Rino

Ini berfungsi dengan ConstraintLayout juga.
Hawklike

86

Masalahnya tampaknya berasal dari properti yang hanya bisa saya lihat di XML formtata letak.

Pastikan untuk menghapus baris ini di akhir deklarasi dalam EditTexttag XML:

<requestFocus />

Itu harus memberikan sesuatu seperti itu:

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

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

78

menggunakan informasi yang disediakan oleh poster lain, saya menggunakan solusi berikut:

dalam tata letak 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"/>

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

dan akhirnya, di onResume ()

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

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

74

Coba clearFocus () alih-alih setSelected(false). Setiap tampilan di Android memiliki kemampuan fokus dan kemampuan memilih, dan saya pikir Anda hanya ingin menghapus fokus.


Itu kedengarannya menjanjikan, tetapi pada titik mana dalam siklus hidup Aktivitas harus disebut? Jika saya menyebutnya di onCreate (), EditText masih memiliki fokus. Haruskah itu dipanggil di onResume () atau lokasi lain? Terima kasih!
Tandai

8
Saya menggabungkan jawaban yang diterima dengan jawaban ini. Saya memanggil myEditText.clearFocus(); myDummyLinearLayout.requestFocus();dalam onResumeKegiatan. Ini memastikan EditText tidak mempertahankan fokus ketika ponsel diputar.
teedyay

71

Berikut ini akan menghentikan edittext dari mengambil fokus saat dibuat, tetapi ambil saat Anda menyentuhnya.

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

Jadi Anda mengatur fokus ke false di xml, tetapi kuncinya adalah di java, yang Anda tambahkan pendengar berikut:

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

Karena Anda kembali salah, yaitu tidak mengkonsumsi acara, perilaku fokus akan berjalan seperti biasa.


6
Tapi ini tidak akan pernah mendapatkan fokus di masa depan, bagaimana menghentikan fokus hanya untuk awal (aktivitas dimulai) ??
Jayesh

1
OnTouchListener dipanggil sebelum tindakan sentuh lainnya. Jadi dengan mengaktifkan fokus pada sentuhan, fokus standar terjadi pada sentuhan pertama. Keyboard akan muncul dan semuanya.
MinceMan

1
Saya pikir ini adalah cara terbaik untuk melakukannya. Juga, kode dummy mumbo-jumbo xml magic di atas TIDAK bekerja untuk satu set teks edit yang kompleks ... Jika ini berhasil, saya pasti akan memberikan suara.
Radu

Tetapi jika Anda memiliki banyak teks edit, itu akan mendapatkan fokus pada teks edit berikutnya dan membuka keyboard sehingga lebih baik menambahkan android: windowSoftInputMode = "stateAlwaysHidden" dalam manifes untuk aktivitas tertentu.
Karan sharma

Catatan: pada Android P sistem tidak akan lagi mengambil fokus default. Ini berarti bahwa peretasan ini tidak perlu dimulai dengan P.
MinceMan

65

Saya telah mencoba beberapa jawaban secara individual tetapi fokusnya masih pada EditText. Saya hanya berhasil menyelesaikannya dengan menggunakan dua solusi di bawah ini bersama-sama.

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

(Referensi dari Silver https://stackoverflow.com/a/8639921/15695 )

dan hapus

 <requestFocus />

di EditText

(Referensi dari floydaddict https://stackoverflow.com/a/9681809 )


1
Saya harus menambahkan edittext.clearFocus () selain yang di atas untuk membuatnya bekerja :)
Nav

57

Terlambat tetapi jawaban paling sederhana, tambahkan saja ini di tata letak induk XML.

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

Suara positif jika itu membantu Anda! Selamat Coding :)


2
bekerja dengan baik untuk saya. satu hal lagi yang perlu diperhatikan adalah, jangan tambahkan baris ini ke tampilan gulir. Ini tidak akan berfungsi dalam tampilan gulir. Tetapi bekerja dengan sempurna dengan tata letak linier.
Karthic Srinivasan

46

Tidak ada solusi ini yang berfungsi untuk saya. Cara saya memperbaiki fokus otomatis adalah:

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

2
android: windowSoftInputMode = "AdjustPan" pada setiap aktivitas di Android Manifest
rallat

43

Solusi sederhana: Penggunaan tag AndroidManifestinActivity

android:windowSoftInputMode="stateAlwaysHidden"

6
Sebenarnya, ini tidak menyelesaikan masalah. OP mengatakan: "Saya tidak ingin kontrol memiliki fokus input saat startup." Solusi Anda hanya menyembunyikan keyboard, ada perbedaan kecil.
katzenhut

@katzenhut ya, itulah masalah saya dengan jawaban ini persis. Berfokus pada edittext saya membuka aktivitas PlaceAutoComplete, jadi jawaban ini tidak lengkap
Zach

Jawaban ini akan lengkap jika pertanyaannya adalah: Bagaimana saya selalu memastikan aktivitas saya tidak pernah menampilkan keyboard. Yang mana bukan.
Martin Marconcini

37

Anda hanya dapat mengatur "focusable" dan "focusable dalam mode touch" untuk menghargai benar pada pertama TextViewdari layout. Dengan cara ini ketika aktivitas dimulai TextViewakan difokuskan tetapi, karena sifatnya, Anda tidak akan melihat apa pun yang terfokus pada layar dan, tentu saja, tidak akan ada keyboard yang ditampilkan ...


berfungsi dengan baik untuk saya, hanya saya menetapkan nilai pada tata letak terluar dalam aktivitas saya dan tidak ke tampilan teks pertama
Maverick1st

36

Berikut ini bekerja untuk saya Manifest. Menulis ,

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

1
Ini tidak membatalkan fokus bidang teks: itu hanya menyembunyikan keyboard. Anda masih akan mendapatkan petunjuk yang didorong keluar dari bidang, dan pemilih status warna apa pun akan menampilkan status "terfokus = benar".
A. Rager

31

Saya perlu menghapus fokus dari semua bidang secara terprogram. Saya baru saja menambahkan dua pernyataan berikut ke definisi tata letak utama saya.

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

Itu dia. Atasi masalah saya secara instan. Terima kasih, Silver, karena mengarahkan saya ke arah yang benar.


28

Tambahkan android:windowSoftInputMode="stateAlwaysHidden"tag aktivitas Manifest.xmlfile.

Sumber


1
Ini tidak membatalkan fokus bidang teks: itu hanya menyembunyikan keyboard. Anda masih akan mendapatkan petunjuk yang didorong keluar dari bidang, dan pemilih status warna apa pun akan menampilkan status "terfokus = benar".
A. Rager

25

Jika Anda memiliki pandangan lain tentang aktivitas Anda seperti ListView, Anda juga dapat melakukan:

ListView.requestFocus(); 

di Anda onResume()untuk mengambil fokus dari editText.

Saya tahu pertanyaan ini telah dijawab tetapi hanya memberikan solusi alternatif yang bekerja untuk saya :)


22

Coba ini sebelum bidang pertama yang dapat diedit:

<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

Tambahkan onCreatemetode berikut :

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

1
Ini tidak membatalkan fokus bidang teks: itu hanya menyembunyikan keyboard. Anda masih akan mendapatkan petunjuk yang didorong keluar dari bidang, dan pemilih status warna apa pun akan menampilkan status "terfokus = benar".
A. Rager

17

Karena saya tidak suka mencemari XML dengan sesuatu yang terkait dengan fungsionalitas, saya membuat metode ini yang "secara transparan" mencuri fokus dari tampilan yang dapat difokuskan pertama dan kemudian memastikan untuk menghapusnya sendiri jika diperlukan!

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

Terlambat, tapi mungkin bermanfaat. Buat EditText boneka di bagian atas tata letak Anda kemudian memanggil myDummyEditText.requestFocus()dionCreate()

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

Itu tampaknya berperilaku seperti yang saya harapkan. Tidak perlu menangani perubahan konfigurasi, dll. Saya membutuhkan ini untuk Aktivitas dengan TextView yang panjang (instruksi).


Mengapa tidak hanya melakukan ini dengan tampilan root itu sendiri?
CJBS


13

Ya saya melakukan hal yang sama - membuat tata letak linear 'dummy' yang mendapat fokus awal. Selanjutnya, saya menetapkan ID fokus 'berikutnya' sehingga pengguna tidak dapat lagi memfokuskannya setelah menggulir sekali:

<LinearLayout 'dummy'>
<EditText et>

dummy.setNextFocusDownId(et.getId());

dummy.setNextFocusUpId(et.getId());

et.setNextFocusUpId(et.getId());

banyak pekerjaan hanya untuk menghilangkan fokus pada tampilan ..

Terima kasih


12

Bagi saya, yang berfungsi pada semua perangkat adalah ini:

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

Letakkan ini sebagai tampilan sebelum tampilan fokus bermasalah, dan hanya itu.


10

Hal paling sederhana yang saya lakukan adalah mengatur fokus pada tampilan lain di onCreate:

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

Ini menghentikan keyboard lunak yang muncul dan tidak ada kursor berkedip di EditText.


10

Ini adalah solusi sempurna dan termudah. ​​Saya selalu menggunakan ini di aplikasi saya.

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

Ini tidak membatalkan fokus bidang teks: itu hanya menyembunyikan keyboard. Anda masih akan mendapatkan petunjuk yang didorong keluar dari bidang, dan pemilih status warna apa pun akan menampilkan status "terfokus = benar".
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

Tulis kode ini di dalam Manifestfile di Activitymana Anda tidak ingin membuka keyboard.

android:windowSoftInputMode="stateHidden"

File manifes:

 <?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
Ini tidak membatalkan fokus bidang teks: itu hanya menyembunyikan keyboard. Anda masih akan mendapatkan petunjuk yang didorong keluar dari bidang, dan pemilih status warna apa pun akan menampilkan status "terfokus = benar".
A. Rager

7

Di onCreateAktivitas Anda, tambahkan saja penggunaan clearFocus()pada elemen EditText Anda. Sebagai contoh,

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

Dan jika Anda ingin mengalihkan fokus ke elemen lain, gunakan requestFocus()itu. Sebagai contoh,

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

6

Saya menggunakan kode berikut untuk menghentikan EditText dari mencuri fokus ketika tombol saya ditekan.

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

Pada dasarnya, sembunyikan teks edit lalu tampilkan lagi. Ini berfungsi untuk saya karena EditText tidak dalam tampilan sehingga tidak masalah apakah itu ditampilkan.

Anda bisa mencoba bersembunyi dan menunjukkannya secara berurutan untuk melihat apakah itu membantu kehilangan fokus.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.