关闭

关于Fragment叠加点击穿透的解决方案

标签: Fragment事件Touch
1199人阅读 评论(0) 收藏 举报

项目中采用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接口,然后实现里面的方法即可。


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



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:82702次
    • 积分:1799
    • 等级:
    • 排名:千里之外
    • 原创:100篇
    • 转载:2篇
    • 译文:0篇
    • 评论:9条
    文章分类
    最新评论