1.解决 ViewPager2 添加 android:overScrollMode="never" 属性无效问题

  • 查阅源码得知 ViewPager2 既没有重写 setOverScrollMode() 方法也没有用到 View 的 getOverScrollMode() 方法
  • ViewPager2 会展示出 RecyclerView 的特点是因为其继承于 ViewGroup 并填充了 (protected声明的) RecyclerView 对象导致
  • ViewPage2 是 final 类

由上述分析可知,最简单的使 overScrollMode 属性生效的办法就是直接去设置 ViewPager2 中 RecyclerView 的 overScrollMode 属性,但 ViewPage2 并未暴露 RecyclerView 对象,且 ViewPager2 是 final 类无法重写。所以选择使用反射获取 RecyclerView 对象并设置 overScrollMode 属性。

    ViewPager2 mVpMain;    private void init() {        RecyclerView recyclerView = (RecyclerView) getPrivateValue(mVpMain, "mRecyclerView");        if (recyclerView != null) {            recyclerView.setOverScrollMode(View.OVER_SCROLL_NEVER);        }    }    /**     * 通过反射获取私有的成员变量     *     * @param object     * @return     */    private Object getPrivateValue(Object object, String fieldName) {        try {            Field field = object.getClass().getDeclaredField(fieldName);            // 参数值为true,打开禁用访问控制检查            //setAccessible(true) 并不是将方法的访问权限改成了public,而是取消java的权限控制检查。            //所以即使是public方法,其accessible 属相默认也是false            field.setAccessible(true);            return field.get(object);        } catch (Exception e) {            Log.e("Test", "e.getMessage() = " + e.getMessage());            return null;        }    }

 

2. ViewPager2 嵌套 RecyclerView 滑动冲突问题解决(两 View 滚动方向均为竖直滚动)

  • Android 滑动冲突解决办法常用两种:外部拦截法和内部拦截法
  • ViewPager2 是 final 类

外部拦截:父 View 根据需要对事件进行拦截,逻辑处理放在父 View 的 onInterceptTouchEvent 方法中。需要重写父 View 的 onInterceptTouchEvent 方法,并根据逻辑需要做相应的拦截

内部拦截:父 View 不拦截任何事件,所有事件都传递给子 View ,子 View 根据需要决定是自己消费事件还是给父 View 处理。子 View 需要重写 dispatchTouchEvent 方法,并根据逻辑需要通过 requestDisallowInterceptTouchEvent 方法拦截事件

因为 ViewPager2 为 final 类无法重写,所以选择内部拦截法来处理滑动冲突,重写 RecyclerView 。

/** * Author : Ziwen Lan * Date : 2019/10/30 * Time : 13:53 * Introduction : 处理与纵向滚动的父View的滑动冲突 */public class NestedRecyclerView extends RecyclerView {    private float mStartY;    public NestedRecyclerView(@NonNull Context context) {        super(context);    }    public NestedRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {        super(context, attrs);    }    public NestedRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    @Override    public boolean dispatchTouchEvent(MotionEvent ev) {        switch (ev.getAction()) {            case MotionEvent.ACTION_DOWN:                getParent().requestDisallowInterceptTouchEvent(true);                mStartY = ev.getY();                break;            case MotionEvent.ACTION_MOVE:                float endY = ev.getY();                if (endY > mStartY) {                    //向上滑动                    if (canScrollVertically(-1)) {                        getParent().requestDisallowInterceptTouchEvent(true);                    } else {                        getParent().requestDisallowInterceptTouchEvent(false);                    }                } else {                    //向下滑动                    if ((canScrollVertically(1))) {                        getParent().requestDisallowInterceptTouchEvent(true);                    } else {                        getParent().requestDisallowInterceptTouchEvent(false);                    }                }                break;            default:                break;        }        return super.dispatchTouchEvent(ev);    }}

 

更多相关文章

  1. android集成sharesdk遇到的坑无法返回app等
  2. Android(安卓)Audio常用音频工具和分析方法
  3. Android(安卓)同一个Service已经启动再多调用startService
  4. 解决API<8时引发的AlerDialog is not created – java.lan...
  5. Android按键事件——上层与驱动的映射
  6. (转)Android中通过Intent 调用图片、视频、音频、录音、拍照
  7. Android登录Web以及登录保持和cookie的使用方法
  8. Android(安卓)BroadCastReceiver的基本使用
  9. Android异步更新UI的方式之使用runOnUiThread(action)方法

随机推荐

  1. android 关于程序升级问题
  2. android背景选择器selector用法汇总
  3. Android里面用XML定义菜单资源
  4. Android(安卓)软键盘盖住输入框的问题
  5. csr8811蓝牙芯片porting总结
  6. Android常用控件之悬浮窗(Service实现)
  7. EditText 的常用属性与解释
  8. Android(安卓)2.2兼容性移植
  9. android通用文件操作
  10. Android开机广播和关机广播