package com.eeepay.eeepay_v2.ui.view;
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.widget.OverScroller;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.widget.NestedScrollView;
import java.lang.reflect.Field;
/*
* ================================================
* 描述:NestedScrollView嵌套recyclerview, 列表第一次点击事件失效问题;
原文链接:https://blog.csdn.net/weixin_37459943/article/details/109195926
* 作者:zhuangzeqin
* 时间: 2024/10/16 20:25
* 邮箱:zzq@eeepay.cn
* 备注:
* ----------------------------------------------------------------
* You never know what you can do until you try !
* _ _ _ _ ____ _ _ _
* / \ _ __ __| |_ __ ___ (_) __| | / ___|| |_ _ _ __| (_) ___
* / _ \ | '_ \ / _` | '__/ _ | |/ _` | ___ | __| | | |/ _` | |/ _ \
* / ___ | | | | (_| | | | (_) | | (_| | ___) | |_| |_| | (_| | | (_) |
* /_/ __| |_|__,_|_| ___/|_|__,_| |____/ __|__,_|__,_|_|___/
*
* 签名:最痛苦的事不是我失败了,而是我本可以.--zzq
* ----------------------------------------------------------------
* ================================================
*/
public class MyNestedScrollView extends NestedScrollView {
private final Handler handler = new Handler();
// private int downY; // 记录下拉开始位置的 Y 坐标
// private int mTouchSlop; // 记录下拉开始位置的 Y 坐标
// private ScrollInterface scrollInterface; // 自定义的滚动监听器接口
public MyNestedScrollView(Context context) {
super(context);
// mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); // 获取触摸阈值
}
public MyNestedScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
// mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); // 获取触摸阈值
}
public MyNestedScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); // 获取触摸阈值
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
boolean result = super.onTouchEvent(ev); // 调用父类的 onTouchEvent 方法
// 当触摸事件为 ACTION_CANCEL 或 ACTION_UP 时,调用 requestEndScroll() 方法
if (ev != null && (ev.getAction() == MotionEvent.ACTION_CANCEL || ev.getAction() == MotionEvent.ACTION_UP)) {
requestEndScroll();
}
return result;
}
// 解决 ScrollView 滚动结束但是 scroll 仍然没有 finish 导致的无法点击的问题
private void requestEndScroll() {
handler.postDelayed(new Runnable() {
@Override
public void run() {
try {
// 获取 NestedScrollView 的私有成员变量 mScroller
Field scrollerField = NestedScrollView.class.getDeclaredField("mScroller");
scrollerField.setAccessible(true);
// 获取 mScroller 对象
OverScroller scroller = (OverScroller) scrollerField.get(MyNestedScrollView.this);
scrollerField.setAccessible(false);
// 如果滚动动画尚未结束,就强制取消滚动动画
if (!scroller.isFinished()) {
scroller.abortAnimation();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}, 240); // 延迟 240 毫秒后执行
}
// @Override // 重写 interceptTouchEvent 方法
// public boolean onInterceptTouchEvent(MotionEvent e) {
// int action = e.getAction();
// switch (action) {
// case MotionEvent.ACTION_DOWN:
// downY = (int) e.getRawY(); // 记录下拉开始位置的 Y 坐标
// break;
// case MotionEvent.ACTION_MOVE:
// int moveY = (int) e.getRawY();
// if (Math.abs(moveY - downY) > mTouchSlop) { // 判断滑动距离大于触摸阈值
// return true; // 返回 true 表示拦截触摸事件
// }
// }
// return super.onInterceptTouchEvent(e); // 将事件传递给父类处理
// }
//
// // 定义滚动监听器接口
// public interface ScrollInterface {
// void onScrollChange(int scrollX, int scrollY, int oldScrollX, int oldScrollY);
// }
//
// @Override // 重写 onScrollChanged 方法
// protected void onScrollChanged(int l, int t, int oldl, int oldt) {
// if (scrollInterface != null) {
// scrollInterface.onScrollChange(l, t, oldl, oldt); // 调用监听器方法
// }
// super.onScrollChanged(l, t, oldl, oldt);
// }
//
// public void setOnScrollChangeListener(ScrollInterface t) {
// this.scrollInterface = t; // 设置滚动监听器
// }
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:minHeight="630dp"
android:orientation="vertical">
<!-- 头部按钮测试 -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="@dimen/size_60"
android:layout_gravity="center_horizontal"
android:background="@color/white"
android:gravity="center"
android:minHeight="@dimen/size_60">
<TextView
android:id="@+id/tvClose"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:gravity="center"
android:paddingLeft="@dimen/size_20"
android:paddingRight="@dimen/size_20"
android:text="取消"
android:textColor="@color/color_999999"
android:textSize="@dimen/text_size_14" />
<TextView
android:id="@+id/tvSubmit"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:gravity="center"
android:paddingLeft="@dimen/size_20"
android:paddingRight="@dimen/size_20"
android:text="确定"
android:textColor="@color/color_BA8B40"
android:textSize="@dimen/text_size_14" />
</RelativeLayout>
<com.eeepay.eeepay_v2.ui.view.MyNestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:overScrollMode="never">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!--1级菜单-->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvMccTypeList"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:overScrollMode="never"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:itemCount="10"
tools:listitem="@layout/item_mcctype" />
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
>
<!--2级菜单 如果没有三级菜单则不显示箭头-->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvSubMccTypeTwoList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/size_20"
android:nestedScrollingEnabled="false"
android:overScrollMode="never"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:itemCount="5"
tools:listitem="@layout/item_submcctype" />
</RelativeLayout>
</LinearLayout>
</com.eeepay.eeepay_v2.ui.view.MyNestedScrollView>
</LinearLayout>