【问题标题】:Disable scrolling on specific area in ViewPager禁用 ViewPager 中特定区域的滚动
【发布时间】:2021-07-20 11:11:56
【问题描述】:

我有一个 ViewPager,所以在这个视图寻呼机中我有不同的片段,所以在第一个片段中我有一个包含 360 度可旋转图像的 TouchImageView。当我为 Touchimageview 向左或向右滑动时,返回 viewpager 事件也触发意味着 viewpager 正在滚动,所以我想禁用此 imageview 区域的 viewpager 触摸事件。

例如:ViewPager -> Fragment -> TouchImageView

我已经根据需要浏览了几个关于禁用 onInterceptTouchEvent() 和 onTouchEvent() 的答案,但它禁用了片段的完整视图。

任何帮助将不胜感激!

ViewPager.java

public class MyCardViewPager extends ViewPager {

private boolean isScrollingEnabled = true;

public MyCardViewPager(@Nonnull Context context, @Nonnull AttributeSet attrs) {
    super(context, attrs);
}

public MyCardViewPager(@NonNull Context context) {
    super(context);
}

@Override
protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
    return false;
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    if (isScrollingEnabled) {
        return super.onInterceptTouchEvent(ev);
    }

    return false;
}

@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (isScrollingEnabled) {
        return super.onTouchEvent(ev);
    }
    return false;
}

public void enableScroll(boolean enable) {
    isScrollingEnabled = enable;
}

}

片段.java

@Override
        public View onCreateView(@Nonnull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    myCardViewPager = new MyCardViewPager(context);
    myCardViewPager.enableScroll(false);
    imageViewSwipeListener();
    }

    private void imageViewSwipeListener() {
        position = 18;
        objectList();
        imageview.setOnTouchListener(new OnSwipeTouchListener(getActivity()) {
            @Override
            public void onSwipeRight() {
                super.onSwipeRight();
                position += 1;
                if (position == 36) {
                    position = 0;
                }
                imageview.setImageResource(objectList.get(position));
            }

            @Override
            public void onSwipeLeft() {
                super.onSwipeLeft();
                position -= 1;
                if (position == -1) {
                    position = 35;
                }
                imageview.setImageResource(objectList.get(position));
              }
        });
    }

OnSwipeTouchListener 类

open class OnSwipeTouchListener(ctx: Context) : View.OnTouchListener {

private val gestureDetector: GestureDetector

companion object {

    private val SWIPE_THRESHOLD = 100
    private val SWIPE_VELOCITY_THRESHOLD = 100
}

init {
    gestureDetector = GestureDetector(ctx, GestureListener())
}

override fun onTouch(v: View, event: MotionEvent): Boolean {
    return gestureDetector.onTouchEvent(event)
}

private inner class GestureListener : GestureDetector.SimpleOnGestureListener() {


    override fun onDown(e: MotionEvent): Boolean {
        return true
    }

    override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
        var result = false
        try {
            val diffY = e2.y - e1.y
            val diffX = e2.x - e1.x
            if (Math.abs(diffX) > Math.abs(diffY)) {
                if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffX > 0) {
                        onSwipeRight()
                    } else {
                        onSwipeLeft()
                    }
                    result = true
                }
            } else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                if (diffY > 0) {
                    onSwipeBottom()
                } else {
                    onSwipeTop()
                }
                result = true
            }
        } catch (exception: Exception) {
            exception.printStackTrace()
        }
        return result
    }
}

open fun onSwipeRight() {}

open fun onSwipeLeft() {}

open fun onSwipeTop() {}

open fun onSwipeBottom() {}

}

【问题讨论】:

  • 显示你到目前为止所尝试的方法,提到的方法是很好的线索,但可能实施不当。发现现有代码中的错误比从头开始编写整个功能更容易
  • 确定@snachmsm 我会添加我的代码
  • @snachmsm 我已经更新了我的问题

标签: android android-viewpager swipe gesturedetector touchimageview


【解决方案1】:
swipeTouch = new OnSwipeTouchListener(getActivity()) {...};
imageview.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        swipeTouch.onTouchEvent(motionEvent);
        imageview.onTouchEvent(motionEvent);
        return true;
    }
});

此方法的第一行只是将每个MotionEvent motionEvent 传递给相同的View,这是没有设置自定义触摸侦听器的默认行为。但是onTouchEvent 方法returns boolean 表示这个View 消耗了通过事件。如果默认onTouchEvent 返回false,则相同的事件将传递给views 父级,如果它也不会消耗它,则再次在层次结构中向上传递,直到一些育儿Views (ViewGroups)将return true 确认它可以处理此事件。

你的imageview 可能是一些自定义/lib 类,它偶尔(总是?)return false 允许将触摸事件按层次结构向上调度到ViewPager,它可以处理这种触摸和return true。这就是为什么在上面的 sn-p onTouch 方法总是在imageview 上发生触摸时返回true - 这种触摸仍然传递给这个View,但即使它没有被处理return true 也会阻止调度由父母决定的事件

【讨论】:

  • 我已经自定义了添加到图像视图中的 OnSwipeTouchListener 类
  • 如何在我的 OnSwipeTouchListener 类中做到这一点?
  • 你只能有一个触摸监听器,但你仍然可以有一个监听器分组并调用另一个监听器。我已经编辑了我的答案,请查看
  • 尝试了同样的方法,现在我的 imageview touchevent 不见了 ....touchevent 仅适用于视图寻呼机
  • 也许您的自定义OnSwipeTouchListener 吞下MotionEvent 并且您应该首先致电imageview.onTouchEvent(motionEvent)?现在我不知道你想要实现什么行为,没有更多想法......也许发布imageview类代码+尝试使用你当前的代码(如问题),但return trueonTouch(v: View, event: MotionEvent) ,之前还是打电话给gestureDetector.onTouchEvent(event)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多