如题所示,我们在开发中,最常见的就是事件分发。 也是不可避免的,比如: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