解决fragment点击穿透问题(当前fragment按到栈底fragment按钮触发事件的问题)

最近搞fragment,,情景如下:

当前的Afragment里有很多按钮,,当从这个Afragment跳转到下一个Bfragment时,Bfragment里边是空白区域,却能点击到Afragment的按钮!!!这真的很揪心!!烦了一宿加一上午,百度了一系列的相关问题,终于发现这是“点击穿透”问题。。


*************************下边是正文。*********************************

项目中采用Activity配合Fragment来完善整体布局框架,但是当多个Fragment添加进Fragment栈时,由于处于栈底的Fragment绑定了点击跟滑动监听事件,当新的Fragment添加进栈的时候,虽然上层的Fragment并没有实现任何监听事件,当时当用户触摸或者在屏幕上滑动的时候依然会触发位于栈底的Fragment上绑定的监听事件,其实这个问题看起来很奇葩,但是解决起来并不难,如果你对安卓里面的Touch事件比较熟,并且了解整个Touch事件的传递流程的话,相信解决办法的原理你肯定也很容易接受,其实就是一个事件拦截的问题,解决方案,大致分为三种,我全部拿出来跟大家分享下,上述阐述,说的不到位的还请勿喷!

1.在xml文件中解决
其实这个思想很简单,叠加在一起的Fragment栈顶的Fragment会响应底部的点击或者滑动事件,而且还会响应Activity中的事件,你只需在每个Fragm的布局的根节点上把clickable属性设为true即可解决

<LinearLayout xmlns:android=" http://schemas.android.com/apk/res/android "

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical"

    android:background="#fff"

    android:clickable="true"

    >

    <!--解决Fragment点击穿透,让布局文件的根节点clickable="true"阻止事件的传播-->

这里的解决问题的思想也是事件的截断,阻止当前事件的继续传播


2.在Fragment的onCreateView()方法中
第二种解决方法其实跟第一种解决方法一样,无非一个处理问题是在xml文件中,另一个是在java代码中,直接在Fragment的onCreateView方法中,把要返回的view对象的clickable属性设置为true

/**

* Created by 谢栋 on 2016/12/31.

*/

public class HeartShareItemFram extends Fragment {

  

    @Nullable

    @Override

    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        view = inflater.inflate(R.layout.heart_share_list_item,null);

        initView();

        view.setClickable(true);     //把View的click属性设为true,截断点击时间段扩散

        return view;

    }


3.在onCreateView()方法中给要返回的view对象添加OnTouchListener,并把OnTouchListener里面的onTouch方法的返回值设置为true

/**

* Created by 谢栋 on 2016/12/31.

*/

public class HeartShareItemFram extends Fragment{



    @Nullable

    @Override

    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        view = inflater.inflate(R.layout.heart_share_list_item,null);

        initView();

//        view.setClickable(true);     //把View的click属性设为true,截断点击时间段扩散

        view.setOnTouchListener(new View.OnTouchListener() {

            @Override

            public boolean onTouch(View v, MotionEvent event) {

                return true;     //截断事件的传递

            }

        });

        return view;

    }

这里对OnTouchListener的监听事件我是采用匿名内部类的形式,当然在实际项目开发中为了代码的整洁性,你完全可以让Fragment实现View.OnTouchListener接口,然后实现里面的方法即可。


三种方法总结起来无非就是一个事件传递拦截的问题,那所以看问题还是要看本质,当你把一个问题看透彻之后,解决问题的方法往往有很多,一句话,办法总比困难多!共勉




*************************以上是正文。*********************************

所以,我采用了第一种方法,即在xml文件中添加onclick属性为true,果真解决问题了!!

猜你喜欢

转载自blog.csdn.net/easy_purple/article/details/80950015
今日推荐