解决SorollView中和其他控件的事件分发机制-例如嵌套地图

如题所示,我们在开发中,最常见的就是事件分发。 也是不可避免的,比如:Viewpager 和 Banner  的 冲突,Viewpager 和 SwipeRefreshLayout 的冲突,因为我觉得其他的下拉还好,SwipeRefreshLayout 比较容易触发,事件冲突也非常容易导致。


网上原理也一大堆,虽然说 解决问题要究其根本,但是现在技术越来越成熟,封装的越来越完善。这问题放到2年前 可以吹一把,现在,要懂得先解决问题,然后 在以后工作中自然就懂了。下面我就贴出代码,其实很简单。拦截SorollView 触发事件就行。

果然如我所说!(然后 在以后工作中自然就懂了),今天是2018年03月07,我重新来编辑我之前的博客了,我懂了这个原理了,其实是一开始误导我了,我一直以为所有事件分发都是有三个dispatchTouchEvent,onInterceptTouchEvent,onTouchEvent,其实不是,只有viewGroup拥有这三个属性,而view 是 dispatchTouchEvent,onTouchEvent。而dispatchTouchEvent仅仅是作为事件分发,传递事件的。在view中 当dispatchTouchEvent 为false ,传递给onTouchEvent,true 就直接被消费结束了。而在viewGroup 经过dispatchTouchEvent之后还要被onInterceptTouchEvent拦截,这是viewGroup独有,独有的!如我下面的代码MapContainer  继承了 RelativeLayout ,而RelativeLayout  正是继承了viewGroup ,这时候就可以重写onInterceptTouchEvent,在当事件分发到这一层的时候,通过判断是否是down还是up,就可以对事件进行消费。onInterceptTouchEvent中 false 表示不拦截,继续传递,true表示直接消费。确实是基础太浅薄,之前看过事件分发的机制,可就是不明白,看了几遍索性就不看了。如今在回头看看之前自己不懂的,瞬间恍然。

XML: 常见的布局我 

<ScrollView
        android:id="@+id/home_scrollview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="none">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <include layout="@layout/flight_record_nologin_layout" />

            <include layout="@layout/flight_record_thd_layout" />

            <include layout="@layout/flight_record_map_layout" />

        </LinearLayout>
    </ScrollView>
XML:自定义的 一个  RelativeLayout 布局,FrameLayout 是 将要 引用的 地图 View  自定义的RelativeLayout 方便 易用,适用很多场景,不需要去做一个一个事件的拦截和分析 ,【简单粗暴】

 <!--事件 触摸冲突-->
    <com.guide.uav.flightrecord.helper.MapContainer
        android:id="@+id/map_container"
        android:layout_width="match_parent"
        android:layout_height="@dimen/pf_ui_size_535"
        android:visibility="gone">

        <FrameLayout
            android:id="@+id/record_fragment_map"
            android:layout_width="match_parent"
            android:layout_height="@dimen/pf_ui_size_535" />
 </com.guide.uav.flightrecord.helper.MapContainer>
自定义View: 在代码中只要 调用 setScrollView 就行 
/**
 * Created by shangbeibei on 2017/2/27.
 * 地图和ScrollView事件分发的处理
 */

public class MapContainer extends RelativeLayout {

    private ScrollView scrollView;

    public MapContainer(Context context) {
        super(context);
    }

    public MapContainer(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void setScrollView(ScrollView scrollView) {
        this.scrollView = scrollView;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_UP){
            scrollView.requestDisallowInterceptTouchEvent(false);
        }else{
            scrollView.requestDisallowInterceptTouchEvent(true);
        }
        return false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return true;
    }
java 中调用:

  //处理事件分发处理事件
        ScrollView scrollview = ((ScrollView) bodyView.findViewById(R.id.home_scrollview));
        MapContainer  map_Container = ((MapContainer) bodyView.findViewById(R.id.map_container));
        map_Container.setScrollView(scrollview);

参考文章:https://www.jianshu.com/p/38015afcdb58



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值