一、上图
二、场景描述
近期在做项目的时候,遇到一个怪异的需求,描述如下:
1、ViewPager中嵌套3个View,当从View1滑动到View2时禁止ViewPager的滑动事件。
2、通过View2底部改变页面的布局实现滑动到View1和View3.
3、View2内嵌的View中还存在一个可以左右滑动的View,在其上添加了手势,即支持左右滑动,这里存在事件冲突,需要通过事件分发来进行处理。
三、问题解决思路
1、禁止ViewPager滑动,主要是不让ViewPager执行scrollTo(int x,int y)这个方法,这个参考了网上的做法,即自定义一个ViewPager,通过设置一个开关标志位,来决定是否执行scrollTo方法。代码如下:
package com.example.viewpagerscrollconflict.views; import android.content.Context; import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; public class CustomViewPager extends ViewPager { private static final String TAG = "CustomViewPager"; private boolean isCanScroll = true; public CustomViewPager(Context context) { super(context); } public CustomViewPager(Context context, AttributeSet attrs) { super(context, attrs); } public void setScanScroll(boolean isCanScroll) { this.isCanScroll = isCanScroll; } public boolean isCanScroll() { return isCanScroll; } @Override public void scrollTo(int x, int y) { if (isCanScroll) { super.scrollTo(x, y); } } /** * 事件分发 */ @Override public boolean dispatchTouchEvent(MotionEvent ev) { Log.i(TAG, "====dispatchTouchEvent====事件分发"); if(getCurrentItem() == 1){ isCanScroll = false; this.requestDisallowInterceptTouchEvent(true); } return super.dispatchTouchEvent(ev); } /** * 事件拦截 */ @Override public boolean onInterceptTouchEvent(MotionEvent ev) { Log.i(TAG, "====onInterceptTouchEvent====事件拦截"); return super.onInterceptTouchEvent(ev); } /** * 事件响应 */ @Override public boolean onTouchEvent(MotionEvent event) { Log.i(TAG, "====onTouchEvent====事件响应"); return super.onTouchEvent(event); } }
2、要实现View2底部改变页面的布局滑动到View1和View3
这里主要是为改变页面的布局添加滑动手势来进行滑动切换的。(稍后给出源码)
3、ViewPager与其内嵌的View水平滑动事件冲突解决思路(上主要代码)
(1)当处在View2页面时,首先让ViewPager禁止滑动。
(2)将事件分发给View2内嵌的View让其根据用户的手势进行滑动。
/** * 事件分发 */ @Override public boolean dispatchTouchEvent(MotionEvent ev) { Log.i(TAG, "====dispatchTouchEvent====事件分发"); if(getCurrentItem() == 1){ isCanScroll = false; //告诉ViewPager不要拦截子View中的各种事件 this.requestDisallowInterceptTouchEvent(true); } return super.dispatchTouchEvent(ev); }
三、Activity中的代码
package com.example.viewpagerscrollconflict; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.os.Bundle; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.util.Log; import android.view.GestureDetector; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import com.example.viewpagerscrollconflict.adapters.ViewPagerAdapter; import com.example.viewpagerscrollconflict.gestures.ViewPagerGestureListener; import com.example.viewpagerscrollconflict.views.CustomViewPager; import com.example.viewpagerscrollconflict.views.ScrollLinearLayout; public class MainActivity extends Activity{ private static final String TAG = "MainActivity"; private GestureDetector mDetector; /**布局加载器**/ private LayoutInflater inflater; private CustomViewPager mVpViewPager; private ViewPagerAdapter vpAdapter; private View v1, v2, v3; private List<View> viewList; private ScrollLinearLayout sllChangePage; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mVpViewPager = (CustomViewPager) findViewById(R.id.vp_view_pager); inflater = LayoutInflater.from(this); v1 = inflater.inflate(R.layout.layout_1, null); v2 = inflater.inflate(R.layout.layout_2, null); v3 = inflater.inflate(R.layout.layout_3, null); mDetector = new GestureDetector(this, new ViewPagerGestureListener(mVpViewPager)); sllChangePage = (ScrollLinearLayout) findViewById(R.id.sll_change_page); sllChangePage.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { mDetector.onTouchEvent(event); return true; } }); viewList = new ArrayList<View>(); viewList.add(v1); viewList.add(v2); viewList.add(v3); vpAdapter = new ViewPagerAdapter(viewList); mVpViewPager.setAdapter(vpAdapter); mVpViewPager.setOnPageChangeListener(new MyPageChangeListener()); } class MyPageChangeListener implements OnPageChangeListener { @Override public void onPageScrollStateChanged(int arg0) { } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageSelected(int arg0) { switch (arg0) { case 0: Log.i(TAG, "=======page=======" + arg0); break; case 1: Log.i(TAG, "=======page=======" + arg0); if (!mVpViewPager.isCanScroll()) {//如果不可以滑动 Log.i(TAG, "在页面1中,不可以滑动"); mVpViewPager.setCurrentItem(1); } break; case 2: Log.i(TAG, "=======page=======" + arg0); if (!mVpViewPager.isCanScroll()) {//如果不可以滑动 Log.i(TAG, "在页面2中,不可以滑动"); mVpViewPager.setCurrentItem(1); } break; } } } }
四、项目源码下载链接
http://download.csdn.net/detail/xiogjie_67/8897119
版权声明:本文为博主原创文章,未经博主允许不得转载。
ViewPager禁止滑动以及它与内层滑动控件水平方向上事件冲突的解决方法
原文地址:http://blog.csdn.net/qinyunying/article/details/46872761