ViewPager禁止滑动以及它与内层滑动控件水平方向上事件冲突的解决方法

一、上图

二、场景描写叙述

    最近在做项目的时候。遇到一个怪异的需求,描写叙述例如以下:

    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




原文地址:https://www.cnblogs.com/mengfanrong/p/5245383.html