Closed junixapp closed 10 months ago
同问,TabLayout+ViewPager->Fragment->Banner,ViewPager页面间的滑动失效,同时单一页面内Banner的手势滑动只能响应一个方向,要么一直向左,要么一直向右,不能同时起作用
解决方案:继承Banner,核心代码如下: private var mStartX = 0f private var mTouchSlop = 0
init {
mTouchSlop = ViewConfiguration.get(context).scaledTouchSlop / 2
}
override fun onInterceptTouchEvent(event: MotionEvent?): Boolean {
event ?: return super.onInterceptTouchEvent(event)
LogUtil.i("===>", "onInterceptTouchEvent")
when (event.action) {
MotionEvent.ACTION_DOWN -> {
mStartX = event.x
}
MotionEvent.ACTION_MOVE -> {
val distanceX = event.x - mStartX
if (viewPager2.orientation == HORIZONTAL && distanceX.absoluteValue >= mTouchSlop) {
// 如果是在最后一条item,继续左滑,则把事件交还给父容器视图
if (isOnLastItem()) {
LogUtil.i("===>", "distanceX= ${distanceX}")
// 右滑,则重置事件拦截状态
return if (distanceX > 0) {
LogUtil.i("===>", "右滑")
setIntercept(true)
super.onInterceptTouchEvent(event)
}
// 左滑
else {
LogUtil.i("===>", "左滑")
parent.requestDisallowInterceptTouchEvent(false)
false
}
}
// 如果是在第一条item,继续右滑,则把事件交还给父容器视图
else if (isOnFirstItem()) {
// 右滑,则重置事件拦截状态
return if (distanceX > 0) {
LogUtil.i("===>", "右滑")
parent.requestDisallowInterceptTouchEvent(false)
false
}
//左滑,
else {
LogUtil.i("===>", "左滑")
setIntercept(true)
super.onInterceptTouchEvent(event)
}
}
}
}
MotionEvent.ACTION_UP,
MotionEvent.ACTION_CANCEL -> {
// 当前处于第一条或者是最后一条item时,把滑动主导权交还给父容器
if (isOnLastItem() || isOnFirstItem()) {
LogUtil.i("===>", "当前item: $currentItem ")
parent.requestDisallowInterceptTouchEvent(false)
setIntercept(false)
}
}
}
return super.onInterceptTouchEvent(event)
}
private fun isOnLastItem(): Boolean {
return adapter != null && currentItem == adapter.itemCount - 1
}
private fun isOnFirstItem(): Boolean {
return adapter != null && currentItem == 0
}
按照楼上的继承Banner解决方案,改成java版本,加入RTL,修复只有一个item的情况
public class MyBanner extends Banner {
private boolean isRTL = TextUtilsCompat.getLayoutDirectionFromLocale(Locale.getDefault()) == LayoutDirection.RTL;
private int mTouchSlop;
public MyBanner(Context context) {
super(context);
init(context);
}
public MyBanner(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public MyBanner(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop() / 2;
}
private float mStartX;
@SuppressLint("WrongConstant")
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mStartX = event.getX();
break;
case MotionEvent.ACTION_MOVE:
float distanceX = event.getX() - mStartX;
if (getViewPager2().getOrientation() == HORIZONTAL && Math.abs(distanceX) >= mTouchSlop) {
if (isOnOnlyItem()) {
getParent().requestDisallowInterceptTouchEvent(false);
return false;
} else if (isOnLastItem()) {// 如果是在最后一条item,继续左滑,则把事件交还给父容器视图
if (isRTL) {
if (distanceX > 0) {// 右滑
getParent().requestDisallowInterceptTouchEvent(false);
return false;
} else {// 左滑
setIntercept(true);
}
} else {
if (distanceX > 0) {// 右滑
setIntercept(true);
} else {// 左滑
getParent().requestDisallowInterceptTouchEvent(false);
return false;
}
}
} else if (isOnFirstItem()) { // 如果是在第一条item,继续右滑,则把事件交还给父容器视图
if (isRTL) {
if (distanceX > 0) {// 右滑
setIntercept(true);
} else {// 左滑
getParent().requestDisallowInterceptTouchEvent(false);
return false;
}
} else {
if (distanceX > 0) {// 右滑
getParent().requestDisallowInterceptTouchEvent(false);
return false;
} else {// 左滑
setIntercept(true);
}
}
}
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
// 当前处于第一条或者是最后一条item时,把滑动主导权交还给父容器
if (isOnLastItem() || isOnFirstItem()) {
getParent().requestDisallowInterceptTouchEvent(false);
setIntercept(false);
}
break;
}
return super.onInterceptTouchEvent(event);
}
private boolean isOnLastItem() {
return getAdapter() != null && getCurrentItem() == getAdapter().getItemCount() - 1;
}
private boolean isOnFirstItem() {
return getAdapter() != null && getCurrentItem() == 0;
}
private boolean isOnOnlyItem() {
return getItemCount() == 0 || getItemCount() == 1;
}
}
场景是:ViewPager2->Fragment->Banner
问题:Banner滑动到底后无法滑动ViewPager2,希望能继续滑动外层的ViewPager2。