Fragmen atas masalah fragmen lain

271

Ketika saya menunjukkan satu fragmen (yang layar penuh dengan #77000000latar belakang) di atas fragmen lain (sebut saja utama), fragmen utama saya masih bereaksi terhadap klik (kita dapat mengklik tombol meskipun kita tidak melihatnya).

Pertanyaan : bagaimana mencegah klik pada fragmen pertama (utama)?

EDIT

Sayangnya, saya tidak bisa menyembunyikan fragmen utama, karena saya menggunakan latar belakang transparan pada fragmen kedua (jadi, pengguna dapat melihat apa yang ada di belakang).

Dmitry Zaytsev
sumber
Berdasarkan apa yang Anda memberi kami bekerja dengan, Anda harus mencoba pengaturan Visibilitydari Anda main Fragmentuntuk GONEketika Anda tidak menggunakannya.
adneal
1
Tanpa melihat bagaimana Anda menerapkan metode onClicked Anda, saya kira Anda mengembalikan "false" ketika diklik.
DeeV
@DeeV, onClickmetode tidak mengembalikan apa pun. Tapi Anda memberikan ide, terima kasih (saya akan segera mengirim jawaban).
Dmitry Zaytsev
1
Doh. Kamu benar. onTouch mengembalikannya. Saya hanya berharap saya mengerti mengapa acara sentuhan jatuh melalui sebuah fragmen. Seharusnya tidak melakukan itu jika Anda tidak mengeluarkan acara sentuh.
DeeV
@DeeV, sepertinya jika tampilan Anda (itu, misalnya di atas yang lain) tidak menangkap peristiwa onTouch, maka sistem terus mencari tampilan lain dengan koordinat yang sama.
Dmitry Zaytsev

Jawaban:

578

Setel clickableproperti pada tampilan fragmen kedua menjadi true. Tampilan akan menangkap acara sehingga tidak akan diteruskan ke fragmen utama. Jadi jika tampilan fragmen kedua adalah tata letak, ini akan menjadi kode:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:clickable="true" />
Jure Vizjak
sumber
4
Ini berhasil untuk saya. Tampaknya lebih mudah daripada solusi yang diberikan @Dmitry Zaitsev di atas. Apakah ada alasan mengapa ini merupakan ide yang buruk? Saya sepertinya tidak bisa memikirkan apa pun, tetapi saya hanya ingin memastikan.
ariets
1
Ini tidak berhasil untuk saya. Saya memiliki bagian RelativeLayoutdalam fragmen, dan saya mengatur seluruh tampilan dengan clickeableproperti. Solusi dari @Dmitry menyelesaikan masalah saya.
4gus71n
3
Ini berhasil untuk saya. "Dapat diklik" di Android tampaknya agak seperti iOS '"userInteractionEnabled"
mvds
17
Mengapa Android membuat kami dalam kondisi pengkodean yang keras ?!
Lo-Tan
1
Saya mengalami masalah yang sama dengan ViewPager. Ketika saya gulir di halaman pertama, itu berpindah ke halaman kedua juga, dan solusi ini tidak berhasil untuk saya. Ada ide?
Gokhan Arik
72

Solusinya cukup sederhana. Dalam fragmen kedua kami (yang tumpang tindih dengan fragmen utama kami), kami hanya perlu menangkap onTouchperistiwa:

@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstance){
    View root = somehowCreateView();

    /*here is an implementation*/

    root.setOnTouchListener(new View.OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {
            return true;
        }
    });
    return root;
}
Dmitry Zaytsev
sumber
solusi Anda bekerja +1 untuk itu tetapi dapatkah Anda memberi tahu saya mengapa kami perlu melakukan ini secara eksplisit?
Berburu
@Hal Anda tidak perlu. Itu hanyalah cara lain untuk melakukannya (lihat jawaban yang diterima)
Dmitry Zaytsev
android: clickable = "true" pada tata letak utama xml fragmen Anda yang kedua.
Rishabh Srivastava
Ada masalah dengan solusi ini, ketika Anda masuk dalam mode aksesibilitas komentar balik AKTIF, itu tidak akan membaca elemen individu sebagai gantinya mendapatkan fokus ke tampilan root.
Amit Garg
Versi Kotlin: root.setOnTouchListener {_, _ -> true}
Gal Rom
21

Cukup tambahkan clickable="true"dan focusable="true"ke tata letak induk

 <android.support.constraint.ConstraintLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:clickable="true"
      android:focusable="true">

      <!--Your views-->

 </android.support.constraint.ConstraintLayout>

Jika Anda menggunakan AndroidX, coba ini

 <androidx.constraintlayout.widget.ConstraintLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:clickable="true"
      android:focusable="true">

          <!--Your views-->

 </androidx.constraintlayout.widget.ConstraintLayout>
Miravzal
sumber
Apakah ini berbeda dari jawaban yang diterima? focuseablesebenarnya tidak perlu.
Dmitry Zaytsev
2
Saya pikir di focusable="true"sini hanya untuk menghindari peringatan di Android Studio.
Artem M
9

Anda harus menyembunyikan fragmen pertama saat Anda menunjukkan Fragmen kedua jika dua fragmen ditempatkan dalam tampilan wadah yang sama.

Jika Anda ingin tahu lebih banyak pertanyaan tentang cara mengatasi masalah tentang Fragmen, Anda dapat melihat perpustakaan saya: https://github.com/JustKiddingBaby/FragmentRigger

FirstFragment firstfragment;
SecondFragment secondFragment;
FragmentManager fm;
FragmentTransaction ft=fm.beginTransaction();
ft.hide(firstfragment);
ft.show(secondFragment);
ft.commit();
JingYeoh
sumber
1
Ini harus menjadi jawaban yang tepat! Terima kasih kawan Saya telah memecahkan pertanyaan ini di proyek lain. Tapi saya sudah lupa Bagaimana saya menyelesaikannya dan Akhirnya, saya mendapat jawaban Anda. Terima kasih.
Licat Julius
1
Saya rasa ini bukan solusi yang tepat. Fragmen / Kegiatan bekerja di tumpukan tampilan. Anda harus memanggil .show lagi setelah fragmen atas dikeluarkan dari tumpukan, yang berarti fragmen bawah harus diberi tahu bahwa fragmen atas hilang. Itu hanya ditambahkan logika ekstra untuk mempertahankan.
XY
4

Anda perlu menambahkan android:focusable="true"denganandroid:clickable="true"

Clickable berarti dapat diklik oleh perangkat penunjuk atau disadap oleh perangkat sentuh.

Focusableberarti dapat memperoleh fokus dari perangkat input seperti keyboard. Perangkat input seperti keyboard tidak dapat memutuskan tampilan mana yang akan dikirimi aktivitas input berdasarkan input itu sendiri, sehingga mereka mengirimnya ke tampilan yang memiliki fokus.

Hossam Hassan
sumber
2
dan focusable = "true" diperlukan untuk menghindari peringatan di Android Studio baru
Hossam Hassan
2

Ada lebih dari satu solusi yang sebagian dari kita berkontribusi pada utas ini tetapi juga saya ingin menyebutkan satu solusi lain. Jika Anda tidak suka meletakkan yang dapat diklik dan fokus sama dengan benar untuk setiap tata letak ViewGroup dalam XML seperti saya. Anda juga dapat meletakkannya di pangkalan Anda jika Anda memiliki satu seperti di bawah ini;

override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ) : View? {
        super.onCreateView(inflater, container, savedInstanceState)

        val rootView = inflater.inflate(layout, container, false).apply {
            isClickable = true
            isFocusable = true
        }

        return rootView
    }

Anda juga dapat menggunakan variabel sebaris tetapi saya tidak memilihnya karena alasan saya.

Saya harap ini membantu bagi mereka yang membenci tata letak XML.

Yekta Sarıoğlu
sumber
1

Jawaban yang dapat diterima akan "bekerja", tetapi juga akan menyebabkan biaya kinerja (penarikan berlebih, pengukuran ulang pada perubahan orientasi) karena fragmen di bagian bawah masih ditarik. Mungkin Anda harus menemukan fragmen dengan tag atau ID dan mengatur visibilitas ke GONE atau VISIBLE ketika Anda perlu menampilkannya lagi.

Di Kotlin:

fragmentManager.findFragmentByTag(BottomFragment.TAG).view.visibility = GONE

Solusi ini lebih disukai daripada alternatif hide()dan show()metode FragmentTransactionketika Anda menggunakan animasi. Anda cukup menyebutnya dari onTransitionStart()dan onTransitionEnd()dari Transition.TransitionListener.

Allan Veloso
sumber
1

Metod 1:

Anda dapat menambahkan ke semua tata letak fragmen

android:clickable="true"
android:focusable="true"
android:background="@color/windowBackground"

Metod 2: (Secara terprogram)

Perpanjang semua fragmen dari FragmentBasedll. Kemudian tambahkan kode ini keFragmentBase

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    getView().setBackgroundColor(getResources().getColor(R.color.windowBackground));
    getView().setClickable(true);
    getView().setFocusable(true);
}
Orang Mars
sumber
0

Apa yang dapat Anda lakukan adalah Anda dapat memberikan klik Kosong ke tata letak fragmen sebelumnya dengan menggunakan properti onClick ke tata letak induk dari fragmen utama dan dalam aktivitas Anda dapat membuat fungsi doNothing(View view)dan tidak menulis apa pun di dalamnya. Ini akan melakukannya untuk Anda.

Satish Silveri
sumber
0

Ini terdengar seperti kasing untuk DialogFragment. Kalau tidak, dengan Fragment Manager, komit satu untuk disembunyikan dan yang lain untuk ditampilkan. Itu berhasil bagi saya.

Juan Mendez
sumber
0

Penambahan android:clickable="true"tidak berfungsi untuk saya. Solusi ini tidak berfungsi di CoordinatorLayout saat itu adalah tata letak induk. Karena itulah saya menjadikan RelativeLayout sebagai tata letak induk, ditambahkan android:clickable="true"padanya dan menempatkan CoordinatorLayout pada RelativeLayout ini.

Zhebzhik Babich
sumber
0

Saya memiliki beberapa fragmen dengan xml yang sama.
Setelah menghabiskan berjam-jam, saya melepas setPageTransformerdan mulai bekerja

   //  viewpager.setPageTransformer(false, new BackgPageTransformer())

Saya memiliki logika scalling.

public class BackgPageTransformer extends BaseTransformer {

    private static final float MIN_SCALE = 0.75f;

    @Override
    protected void onTransform(View view, float position) {
        //view.setScaleX Y
    }

    @Override
    protected boolean isPagingEnabled() {
        return true;
    }
}
AskQ
sumber