一,问题描述:
当页面是由导航栏TabLayout,ViewPage2 ,列表RecycleView 组成的时候,RecycleView上下滑动,总是不经意的带动了ViewPage2的左右滑动,ViewPage2太灵敏。
解决问题方法核心:分发事件。 (其实看了一遍并没什么思路)
思路:从布局开始:ViewPage2+Tablayout+Fragment
而我们RecycleView是在Fragment中,Fragment又在ViewPage2中。也就是说ViewPage2是RecycleViewd的父布局。
然而,看了一下ViewPage2并不能被继承。 那我们可以做的就是,在RecycleView 滑动的时候,去影响ViewPage2 ,怎么去影响他呢?这是个问题。
先看下 子控件 的拦截方法都有啥
自定义View 继承 RecycleView 实现这个方法
这是RecycleView的事件分发方法,我们的操作就要在这个里面。
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {when (ev!!.action) {//按下MotionEvent.ACTION_DOWN -> {//此时,得到手指坐标 X,Y}//移动MotionEvent.ACTION_MOVE -> {//移动的距离}//这里 抬起手指,和取消动作。MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {}}return super.dispatchTouchEvent(ev)}
怎么操作父布局
下面这个接口→视图父类。
Defines the responsibilities for a class that will be a parent of a View.
This is the API that a view sees when it wants to interact with its parent.
解释:大概意思是,使用这个类,可以得到当前布局(使用这个方法的布局)的父布局。并与之交互。
public interface ViewParent { //其他方法略
.../*** 这个方法:如果父元素存在,返回父元素;或者null。*/public ViewParent getParent();/*** 还有这个:当子View不希望被父View调用时使用,意思就是我自己来,不让父布局管。* true:拦截,false:不拦截*/public void requestDisallowInterceptTouchEvent(boolean disallowIntercept);...
}
以上就是关键的方法,下面,直接看完整代码
t.Context
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.ViewConfiguration
lerview.widget.RecyclerView
import kotlin.math.abs
/*** author : ChenWenJie* email : 1181620038@qq* date : 2020/7/29* desc : 滑动冲突。斜着往上滑的时候,会滑动viewpage*/
class MyRecyclerView(context: Context, attrs: AttributeSet?) : RecyclerView(context, attrs) {private var mTouchSlop = 0var startX = 0 //手指碰到屏幕时的 X坐标var startY = 0 //手机碰到屏幕时的 Y坐标init {val vc = (context)mTouchSlop = vc.scaledTouchSlop}override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {when (ev!!.action) {MotionEvent.ACTION_DOWN -> {//当手指按下时,得到了X,Y,startX = ev!!.x.toInt()startY = ev!!.y.toInt()// questDisallowInterceptTouchEvent(true)}MotionEvent.ACTION_MOVE -> {//抬起手后得到的坐标,val endX = ev!!.x.toInt()val endY = ev!!.y.toInt()//得到绝对值 。val disX = abs(endX - startX) val disY = abs(endY - startY)//如果X轴 大于Y 轴,说明实在左右移动 为什么?// 屏幕坐标,X,Y从左上角开始。0,0if (disX > disY) {Log.e("ACTIONdisX > disY:", "$disX")//这个地方,判断了左右滑动的灵敏度,只有当左右滑动距离110 此时父布局才有作用,不拦截。if (disX > 110) { //结束的时候大于//当滑动的距离大于100的时候,才不拦截parent的事件 父控件才会有用。questDisallowInterceptTouchEvent(false)} } else {// 说明是上下滑动 //canScrollVertically 检查此视图是否可以按某个方向垂直滚动。 负数表示上下滚动。正数表示左右滚动//return true如果视图可以按指定的方向滚动,否则为false。//既然是上下滑动,此时,父控件就不能有 事件 true停止questDisallowInterceptTouchEvent(true)}}MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> questDisallowInterceptTouchEvent(false)}return super.dispatchTouchEvent(ev)}
}
看下效果图:在这里插入图片描述
本文发布于:2024-01-31 00:25:11,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170663191423913.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |