在 Android 的特定位置停止滚动视图

Stopping a scroll view on specific locations on Android

我的最终目标是在特定位置停止滚动,让正在查看的对象完整显示,我想出的解决方案是在触摸释放时检查视图的 scrollX 位置。我确实遇到了动量问题,因为在捕获触摸事件后,由于滚动速度,滚动仍然可以继续,我使用 MotionEvent.ACTION_CANCEL 解决了这个问题,我对此并不满意,因为 scrollTo 在视觉上令人愉悦,但是MotionEvent.ACTION_CANCEL 杀死它的效果。

我的问题是,有没有更优雅的方法来做到这一点?理想情况下,如果我可以简单地指示我的 ScrollView 不要有 momentum/velocity.

    myView.setOnTouchListener(new HorizontalScrollView.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_UP) {
                event.setAction(MotionEvent.ACTION_CANCEL);
                int x = myView.getScrollX();
                if (x < 150)
                    myView.scrollTo(0,0);
                else if (x<450)
                    myView.scrollTo(300,0);
                else
                    myView.scrollTo(600,0);
            }
            return false;
        }
    });

如果您想精确滚动以显示特定视图,this answer 应该可以帮到您。您要做的是在 UI 线程上调用 myView.scrollTo(0, view.getBottom())myView.smoothScrollTo(0, view.getBottom())。这样,view对象就会完整显示。


编辑:在我看来,您在这里尝试实现的目标与 ViewPager 所做的非常接近:您的意图是使用 swipe/fling 手势在视图之间移动,从而提供对分页浏览内容。

如果您使用 ViewPager,您的代码可能是这样的:

viewPager.setAdapter(new PagerAdapter() {

            @Override
            public boolean isViewFromObject(View view, Object object) {
                return view == object;
            }

            @Override
            public int getCount() {
                return getViewCount();
            }

            @Override
            public Object instantiateItem(ViewGroup container, int position) {
                View view = getViewAtPosition(position);
                container.addView(view);
                return view;
            }

            @Override
            public void destroyItem(ViewGroup container, int position, Object view) {
                container.removeView((View) view);
            }
        });

其中 getViewCount()getViewAtPosition() 方法必须根据您想要显示的视图数量及其实例化方式来实现。

如果你想在 scrollView 滚动时获得当前位置,你应该使用 onScrollListener

scrollView.getViewTreeObserver().addOnScrollChangedListener(new OnScrollChangedListener() {

    @Override
    public void onScrollChanged() {

        int scrollX = rootScrollView.getScrollX(); //for horizontalScrollView
        int scrollY = rootScrollView.getScrollY(); //for verticalScrollView
        //DO SOMETHING WITH THE SCROLL COORDINATES

    }
});