在 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
}
});
我的最终目标是在特定位置停止滚动,让正在查看的对象完整显示,我想出的解决方案是在触摸释放时检查视图的 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
}
});