Başka bir parça sorunu üzerinde parçalanma


271

Bir parçayı ( #77000000arka planla tam ekran olan ) başka bir parçanın üzerinde gösterdiğimde (buna ana diyelim), ana parçam yine de tıklamalara tepki veriyor (görmese bile bir düğmeyi tıklayabiliriz).

Soru : İlk (ana) parçaya tıklamalar nasıl önlenir?

DÜZENLE

Ne yazık ki, sadece ana parçayı gizleyemiyorum, çünkü ikinci parçada şeffaf arka plan kullanıyorum (böylece, kullanıcı neyin arkasında olduğunu görebilir).


Eğer çalışmak için bize ne verdi dayanarak, ayar denemelisiniz Visibilityaramalarınızdan main Fragmentiçin GONEbunu kullanmadığınız zamanlarda.
adneal

1
OnClicked yönteminizi nasıl uyguladığınızı görmeden, tıklandığında "false" değerini döndürdüğünüzü tahmin ediyorum.
DeeV

@DeeV, onClickyöntem hiçbir şey döndürmez. Ama bir fikir veriyorsun, teşekkürler (yakında cevap göndereceğim).
Dmitry Zaytsev

1
D'oh. Haklısın. onTouch döndürür. Keşke bir dokunma olayının neden bir parçadan geçtiğini anlamış olsaydım. Dokunma olayları yayınlamıyorsanız bunu yapmamalısınız.
DeeV

@DeeV, görünümünüz (örneğin diğerinin üzerinde) onTouch etkinliğini yakalamıyorsa, sistem aynı koordinatlara sahip diğer görünümleri aramaya devam eder.
Dmitry Zaytsev

Yanıtlar:


578

Set clickabletrue ikinci veridiliminin görünümünde özelliği. Görünüm olayı yakalar, böylece ana parçaya aktarılmaz. İkinci parçanın görünümü bir mizanpajsa, kod şöyle olur:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:clickable="true" />

4
Bu benim için çalıştı. @Dmitry Zaitsev'in yukarıda verdiği çözümden daha kolay görünüyor. Bunun kötü bir fikir olmasının bir nedeni var mı? Hiç düşünemiyorum ama sadece emin olmak istiyorum.
ariets

1
Bu benim için işe yaramadı. RelativeLayoutParçanın içinde bir tane var ve tüm görünümü clickeableözellik ile ayarlıyorum . @Dmitry'nin çözümü sorunumu çözdü.
4gus71n

3
Bu benim için çalıştı. Görünüşe göre Android'de "tıklanabilir" biraz iOS '"userInteractionEnabled" gibidir
mvds

17
Android neden bizi zorlu kodlama koşullarına tabi tutuyor ?!
Lo-Tan

1
ViewPager ile aynı sorunu yaşıyorum. İlk sayfaya kaydırdığımda, ikinci sayfaya da geçiyor ve bu çözüm benim için çalışmadı. Herhangi bir fikir?
Gökhan Arık

72

Çözüm oldukça basit. İkinci parçamızda (ana parçamızla örtüşen) sadece onToucholayı yakalamamız gerekir :

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

çözümünüz bunun için +1 çalıştı ancak bana bunu neden açıkça yapmamız gerektiğini söyleyebilir misiniz?
Hunt

@ Yapmak zorunda değilsin. Bunu yapmanın başka bir yolu budur (kabul edilen cevaba bakınız)
Dmitry Zaytsev

android: clickable = ikinci parçanızın xml ana düzeninde "true".
Rishabh Srivastava

Bu çözümle ilgili bir sorun var, erişilebilirlik görüşme moduna AÇIK duruma geldiğinizde, tek tek öğeleri okumaz, bunun yerine odak kök görünümüne geçer.
Amit Garg

Kotlin sürümü: root.setOnTouchListener {_, _ -> true}
Gal Rom

21

Sadece clickable="true"ve focusable="true"ana mizanpaja ekleyin

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

Kullanıyorsanız, bunu AndroidXdeneyin

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

Bu, kabul edilen cevaptan bir şekilde farklı mı? focuseablegerçekten gerekli değil.
Dmitry Zaytsev

2
Bence focusable="true"burada sadece Android Studio'da uyarı almaktan kaçınmak gerekiyor.
Artem M

9

Aynı kap görünümünde iki parça yerleştirilmişse, ikinci Parçayı gösterirken ilk parçayı gizlemelisiniz.

Fragment ile ilgili sorunların nasıl çözüleceği hakkında daha fazla soru öğrenmek istiyorsanız, kütüphanemi görebilirsiniz: https://github.com/JustKiddingBaby/FragmentRigger

FirstFragment firstfragment;
SecondFragment secondFragment;
FragmentManager fm;
FragmentTransaction ft=fm.beginTransaction();
ft.hide(firstfragment);
ft.show(secondFragment);
ft.commit();

1
Bu doğru cevap olmalı! Teşekkür ederim dostum. Bu soruyu başka bir projede çözdüm. Ama bunu nasıl çözdüm ve sonunda cevabını aldım. Teşekkür ederim.
Licat Julius

1
Bunun doğru çözüm olduğunu düşünmüyorum. Parçalar / Etkinlikler bir görünüm yığınında çalışır. Üst parça yığının dışına çıkarıldıktan sonra .show'u tekrar çağırmanız gerekir, bu da alt parçanın üstteki parçanın gittiğini bildirmesi gerektiği anlamına gelir. Sadece bakımı için ekstra mantık eklendi.
XY

4

Sen eklemeniz gerekir android:focusable="true"ileandroid:clickable="true"

Clickable bir işaretçi aygıtı tarafından tıklanabileceği veya bir dokunmatik aygıt tarafından dokunabileceği anlamına gelir.

Focusableklavye gibi bir giriş aygıtından odaklanabileceği anlamına gelir. Klavyeler gibi giriş aygıtları, giriş olaylarının kendilerine göre hangi olayların giriş olaylarını göndereceğine karar veremezler, böylece bunları odaklanan görünüme gönderirler.


2
ve yeni Android Studio'da bir uyarıyı önlemek için focusable = "true" gerekiyor
Hossam Hassan

2

Bazılarımız bu konuya katkıda bulunan birden fazla çözüm var ama aynı zamanda başka bir çözümden bahsetmek istiyorum. Tıklanabilir ve odaklanabilir koymaktan hoşlanmıyorsanız, XML gibi her mizanpajın kök ViewGroup'u için de geçerlidir. Aşağıdaki gibi bir tane varsa, üssünüze de koyabilirsiniz;

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
    }

Satır içi değişkeni de kullanabilirsiniz, ancak nedenlerim için tercih etmedim.

Umarım düzen XML'lerinden nefret edenler için yardımcı olur.


1

Kabul edilebilir cevap "çalışacaktır", ancak aynı zamanda alt kısımdaki parça hala çizildiği için performans maliyetine (geri çekilme, yön değiştirme üzerinde yeniden ölçüm) neden olacaktır. Belki parçayı etikete veya kimliğe göre bulmalı ve tekrar göstermeniz gerektiğinde görünürlüğü GONE veya VISIBLE olarak ayarlamalısınız.

Kotlin'de:

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

Bu çözüm, animasyonları kullanma alternatifine hide()ve show()yöntemlerine tercih edilir FragmentTransaction. Sadece onu aramak onTransitionStart()ve onTransitionEnd()bir Transition.TransitionListener.


1

Metod 1:

Tüm fragman düzenine ekleyebilirsiniz

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

Metod 2: (Programlı olarak)

Tüm parçayı FragmentBasevb. Genişletin . Ardından bu koduFragmentBase

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

0

Yapabileceğiniz şey, u ana parçanın üst düzenine onClick özelliğini kullanarak önceki parçanın düzenine Boş bir tıklama verebilir ve etkinlikte bir işlev oluşturabilir doNothing(View view)ve içine hiçbir şey yazamazsınız. Bu sizin için yapacak.


0

Bu DialogFragment için bir vaka gibi geliyor. Aksi takdirde, Fragment Manager ile birini gizlemek ve diğerini göstermek için taahhüt edin. Bu benim için çalıştı.


0

Eklemek android:clickable="true"benim için işe yaramadı. Bu çözüm, bir ana düzen olduğunda CoordinatorLayout'ta çalışmaz. Bu yüzden RelativeLayout'u üst düzen olarak yaptım, ekledim android:clickable="true"ve CoordinatorLayout'u bu RelativeLayout'a yerleştirdim.


0

Aynı xml ile birden fazla parça vardı.
Saatler geçirdikten sonra kaldırdım setPageTransformerve çalışmaya başladı

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

Korkutucu bir mantık vardı.

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