Android 在ViewPager中区分用户滚动和编程页面更改
我的应用程序中有一个Android 在ViewPager中区分用户滚动和编程页面更改,android,android-viewpager,Android,Android Viewpager,我的应用程序中有一个android.support.v4.view.ViewPager,我想区分编程启动的平滑滚动和用户启动的触摸滚动 我已经看过了ViewPager.OnPageChangeListener,我相信答案可能就在那里,但我只是不确定如何回答。好的,所以结果证明我对ViewPager.OnPageChangeListener中的答案是正确的。具体来说,它在于使用onPageScrollStateChanged(int-state)。基本上,ViewPager中的页面可以处于三种状态
android.support.v4.view.ViewPager
,我想区分编程启动的平滑滚动和用户启动的触摸滚动
我已经看过了
ViewPager.OnPageChangeListener
,我相信答案可能就在那里,但我只是不确定如何回答。好的,所以结果证明我对ViewPager.OnPageChangeListener
中的答案是正确的。具体来说,它在于使用onPageScrollStateChanged(int-state)
。基本上,ViewPager
中的页面可以处于三种状态:
onPageSelected(int位置)
方法。因此,为了确定页面更改是否由用户滚动引起,只需检查前一个状态是否为“拖动”,当前状态是否为“设置”。然后,您可以保留一个boolean
变量来跟踪页面更改是否由用户发起,并在onPageSelected(int位置)
方法中进行检查
这是我的onPageScrollStateChanged
方法
public void onPageScrollStateChanged(int state)
{
if (previousState == ViewPager.SCROLL_STATE_DRAGGING
&& state == ViewPager.SCROLL_STATE_SETTLING)
userScrollChange = true;
else if (previousState == ViewPager.SCROLL_STATE_SETTLING
&& state == ViewPager.SCROLL_STATE_IDLE)
userScrollChange = false;
previousState = state;
}
if
和else-if
语句不必如此明确,但我这样做是为了清晰明了。关于使用ViewPager.OnPageChangeListener,您是对的。:
@Override
public void onPageSelected(int arg0) {
// programmatically-initiated
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
// user-initiated touch scroll
}
@Override
public void onPageSelected(int arg0) {
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
if (progChange) {
// programmatically-initiated
} else {
// user-initiated touch scroll
}
// Set progChange to false;
progChange = false;
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
或者,您可以使用布尔标志来区分以编程方式启动的平滑滚动和用户启动的触摸滚动。例如,如果使用setCurrentItem(int item)
以编程方式更改页面,请尝试:
boolean progChange = false;
....
....
....
progChange = true;
setCurrentItem(somePageId); // Set progChange = true every time
....
....
....
在您的ViewPager.OnPageChangeListener中
:
@Override
public void onPageSelected(int arg0) {
// programmatically-initiated
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
// user-initiated touch scroll
}
@Override
public void onPageSelected(int arg0) {
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
if (progChange) {
// programmatically-initiated
} else {
// user-initiated touch scroll
}
// Set progChange to false;
progChange = false;
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
我的答案是正确的,在下面的评论中
首先,我分析完整侦听器的行为:
USER
onPageScrollStateChanged: 1 SCROLL_STATE_DRAGGING
onPageScrollStateChanged: 2 SCROLL_STATE_SETTLING
onPageSelected: SELECTION
onPageScrollStateChanged: 0 SCROLL_STATE_IDLE
PROGRAMATIC
onPageScrollStateChanged: 2 SCROLL_STATE_SETTLING
onPageSelected: SELECTION
onPageScrollStateChanged: 0 SCROLL_STATE_IDLE
调查结果:
- 如您所见,在这两种情况下,当
onPageScrollStateChanged
移动到SCROLL\u STATE\u IDLE
时,事件结束,这意味着IDLE是周期的结束
- 用户事件是
SCROLL\u STATE\u drawing
然后SCROLL\u STATE\u SETTLING
,这是编程事件的两种状态
不同于只有一种状态
onPageSelected
发生在周期结束之前,但在我们能够确定更改是由用户触发还是以编程方式触发之后,因此之前发生的任何事情都会在这一点上告诉我们是否是用户
解决方案:
因此,我使用了一个列表
,它在每次循环结束时都会重置,为了能够知道用户是否在onPageSelected
方法中触发了事件,我检查了列表
的大小如果大小为2,则表示用户滚动寻呼机。
abstract class PagerListenerActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener {
private static final int USER_SCROLL = 2;
private List<Integer> validator = new ArrayList<>();
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
if (validator.size() == USER_SCROLL) {
userScroll(position);
}
}
@Override
public void onPageScrollStateChanged(int state) {
validator.add(state);
if (ViewPager.SCROLL_STATE_IDLE == state) {
validator.clear();
}
}
protected abstract void userScroll(int position);
}
抽象类PagerListener活动扩展了AppCompatActivity实现了ViewPager.OnPageChangeListener{
私有静态最终int用户_SCROLL=2;
私有列表验证程序=新的ArrayList();
@凌驾
已滚动页面上的公共无效(int-position、float-positionOffset、int-positionOffsetPixels){
}
@凌驾
已选择页面上的公共无效(内部位置){
if(validator.size()=用户\u滚动){
用户滚动(位置);
}
}
@凌驾
公共无效onPageScrollStateChanged(int状态){
添加(状态);
如果(ViewPager.SCROLL\u STATE\u IDLE==STATE){
validator.clear();
}
}
受保护的抽象空用户滚动(int位置);
}
现在,这个类可以方便地被另一个需要它的人继承。在2016年仍然是一个很好的答案。事实上,我将使用一个wasUserScroll()
方法将其制作成一个抽象基类,供所有人使用。:)我应该为previousState
变量设置什么初始值?如果用户正在拖动并以编程方式调用setCurrentItem,userScrollChange
将为true。