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

论坛 期权论坛 脚本     
匿名技术用户   2020-12-30 19:09   32   0

一、上图

二、场景描述

近期在做项目的时候,遇到一个怪异的需求,描述如下:

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


分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP