我正在使用一个使用多个页面进行滑动的应用程序,但在某些页面上,我希望能够阻止滚动到下一页,直到他们选择了某些内容。
目前我已经扩展了ViewPager:
/* (non-Javadoc)
* @see android.support.v4.view.ViewPager#onInterceptTouchEvent(android.view.MotionEvent)
*/
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (this.canGoLeft || this.canGoRight) {
return super.onInterceptTouchEvent(event);
}
return false;
}
/* (non-Javadoc)
* @see android.support.v4.view.ViewPager#onTouchEvent(android.view.MotionEvent)
*/
@Override
public boolean onTouchEvent(MotionEvent ev) {
boolean lockScroll = false;
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
lastX = ev.getX();
lockScroll = false;
return super.onTouchEvent(ev);
case MotionEvent.ACTION_MOVE:
if (canGoLeft && lastX < ev.getX()) {
lockScroll = false;
} else if (canGoRight && lastX > ev.getX()) {
lockScroll = false;
} else {
lockScroll = true;
}
lastX = ev.getX();
break;
}
lastX = ev.getX();
if (lockScroll) {
//make callback to prevent movement
if (mOnPreventCallback != null) {
mOnPreventCallback.onPreventMovement();
}
return false;
} else {
return super.onTouchEvent(ev);
}
}
注意:我已尝试实施防止滑动到之前,但您仍然可以滑动到上一页,但您需要从最左侧滑动并向右滑动一下。它很有气质但不能完全阻止滑动。
我想在这里做三件事:
答案 0 :(得分:4)
当我遇到类似的问题时,我使用gestureDetector制作了自己的Listener,并且根本没有响应滑动,你可以轻松调整它以便在某些条件下不响应向右滑动。这应该回答你的数字1和2。
这是听众:
public class OnSwipeTouchListener implements OnTouchListener {
@SuppressWarnings("deprecation")
private final GestureDetector gestureDetector = new GestureDetector(new GestureListener());
public boolean onTouch(final View v, final MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
private final class GestureListener extends SimpleOnGestureListener {
private static final int SWIPE_THRESHOLD = 100;
private static final int SWIPE_VELOCITY_THRESHOLD = 100;
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
onTouch(e);
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
boolean result = false;
try {
float diffY = e2.getY() - e1.getY();
float diffX = e2.getX() - e1.getX();
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();
}
}
} else {
// onTouch(e);
}
} catch (Exception exception) {
exception.printStackTrace();
}
return result;
}
}
public void onTouch(MotionEvent e) {
}
public void onSwipeRight() {
//call this only if your condition was set
}
public void onSwipeLeft() {
//nothing, this means,swipes to left will be ignored
}
public void onSwipeTop() {
}
public void onSwipeBottom() {
}
}
这是一个使用示例:
viewPager.setOnTouchListener(new OnSwipeTouchListener() {
public void onSwipeRight() {
if(your conditionIsMet){
// move your pager view to the right
}
}
});
可能有一个更简单,更优雅的解决方案,但这对我来说效果很好。
答案 1 :(得分:2)
我一直在谷歌搜索高低,以解决这个问题... 我试图改写ontouchevent等......
我认为这对我来说是最好的解决方案(而且不那么笨拙) 只是为了实现最大或最小跟踪器并将其设置为当前页面
maxPageToScroll = viewPager.getCurrentItem();
minPageToScroll = viewPager.getCurrentItem();
然后添加到“onPageSelected”方法:
public void onPageSelected(int position) {
if (position < minPageToScroll) {
viewPager.setCurrentItem(maxPageToScroll);
}
else if (position > maxPageToScroll) {
viewPager.setCurrentItem(maxPageToScroll);
// you can alert here that user needs to do certain actions before proceeding
}
else {
// enter normal commands here
}
因此,当满足条件时,您只需将maxpage增加一个..
maxPageToScroll = viewPager.getCurrentItem() + 1;
请注意,这不会阻止用户表单滚动...它只会阻止视图寻呼机更改页面。
答案 2 :(得分:1)
我认为不需要扩展ViewPager。您需要做的是修改提供给PagerAdapter的页面列表。这意味着,您检查某个页面是否标记为“已完成”,然后才将下一页添加到列表中。这就是ViewPager的工作方式。
看看Roman Nurik's wizard-pager implementation。在MainActivity中有一个名为recalculateCutOffPage的方法,它完成了我所说的。
答案 3 :(得分:1)
您可以使用自定义视图寻呼机
public class CustomViewPager extends ViewPager
{
float mStartDragX;
OnSwipeOutListener mListener;
Context context;
public static boolean enabled;
public CustomViewPager(Context context, AttributeSet attrs)
{
super(context, attrs);
this.context = context;
enabled = true;
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
if (enabled) //view pager scrolling enable if true
{
return super.onTouchEvent(event);
}
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev)
{
if (enabled)enter code here
{
return super.onInterceptTouchEvent(ev);
}
else // view pager disable scrolling
{
float x = ev.getX();
switch (ev.getAction())
{
case MotionEvent.ACTION_DOWN:
mStartDragX = x;
break;
case MotionEvent.ACTION_MOVE:
if (mStartDragX < x - 100)//100 value velocity
{
//Left scroll
//return super.onInterceptTouchEvent(ev);
}
else
if (mStartDragX > x + 100)
{
//Right scroll
//return super.onInterceptTouchEvent(ev);
}
break;
}
}
return false;
}
public void setOnSwipeOutListener(OnSwipeOutListener listener)
{
mListener = listener;
}
public interface OnSwipeOutListener
{
public void onSwipeOutAtStart();
public void onSwipeOutAtEnd();
}
}
答案 4 :(得分:-1)
我为一个具有最大页面的向导实施了viewpager,用户无法通过该页面。
最后解决方案在适配器中。 我更改了PagerAdapter的计数,这样就阻止了用户传递最大页面:
@Override
public int getCount() {
return mProgress; //max page + 1
}
当用户进入下一页时:
private void setWizardProgress(int progress) {
if(progress > mProgress) {
mProgress = progress;
mWizardPagerAdapter.notifyDataSetChanged();
}
}
这样,当用户处于最大页面时,他无法向右滚动,直到更新进度。