如果 ViewPager 滚动到最后一页之外如何显示警报
How to show Alert If ViewPager is scrolled beyond the last page
我有一个包含 3 个片段的 viewpager。如果我在视图寻呼机中滚动到最后一页之后,我需要显示祝酒词或警告“没有更多可用页面”。
我已经尝试了很多,但没有任何帮助。
非常感谢任何帮助。
我已经添加了代码片段,请仔细阅读
ViewPager.OnPageChangeListener viewPagerPageChangeListener = new ViewPager.OnPageChangeListener() {
boolean callHappened;
int selectedIndex;
boolean mPageEnd;
@Override
public void onPageSelected(int position) {
selectedIndex = position;
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
if( mPageEnd && arg0 == myViewPagerAdapter.getCount()-1 && !callHappened){
Log.d(getClass().getName(), "Okay");
mPageEnd = false;//To avoid multiple calls.
callHappened = true;
}else{
mPageEnd = false;
}
}
@Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
if(selectedIndex == myViewPagerAdapter.getCount() - 1)
{
mPageEnd = true;
}
}
};
您应该尝试为视图寻呼机
制作自定义视图寻呼机 class
public class CustomViewPagerEndSwipe extends ViewPager {
public CustomViewPagerEndSwipe(Context context, AttributeSet attrs) {
super(context, attrs);
}
float mStartDragX;
OnSwipeOutListener mListener;
public void setOnSwipeOutListener(OnSwipeOutListener listener) {
mListener = listener;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
float x = ev.getX();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mStartDragX = x;
break;
case MotionEvent.ACTION_MOVE:
if (mStartDragX < x && getCurrentItem() == 0) {
mListener.onSwipeOutAtStart();
} else if (mStartDragX > x && getCurrentItem() == getAdapter().getCount() - 1) {
mListener.onSwipeOutAtEnd();
}
break;
}
return super.onInterceptTouchEvent(ev);
}
public interface OnSwipeOutListener {
public void onSwipeOutAtStart();
public void onSwipeOutAtEnd();
}
}
在您的布局中使用此 class xml
<com.utils.customview.CustomViewPagerEndSwipe
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
从您的 activity 和片段实施侦听器,您将从界面
获取最后一页 toast
viewPager.setOnSwipeOutListener(this);
您可以使用 viewpager.canScrollHorizontally(View.SCROLL_AXIS_HORIZONTAL)
方法检查,如果它 returns 为假,那么您在查看寻呼机的最后一项。
使用了您的原始代码和@Mohit Suthar 的一些代码,但是,如果用户尝试在第一页之前滑动,@Mohit Suthar 的答案将提供大量警报(原因是因为它没有使用提问者的代码 "callHappened" 变量来避免多次调用)
如果用户在片段的上部区域向左滑动,则以下代码无法提供完美的工作。等待修改
而且我建议对您的滑动操作使用枚举,因为如果您有其他自定义逻辑,它会很灵活。
public class CustomViewPagerEndSwipe extends ViewPager {
public CustomViewPagerEndSwipe(Context context, AttributeSet attrs) {
super(context, attrs);
}
float mStartDragX;
SwipeAction mSwipeAction;
OnSwipeOutListener mListener;
boolean callHappened = false;
public void setOnSwipeOutListener(OnSwipeOutListener listener) {
mListener = listener;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
float x = ev.getX();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mStartDragX = x;
callHappened = false;
break;
case MotionEvent.ACTION_MOVE:
if (!callHappened) {
if (mStartDragX < x && getCurrentItem() == 0) {
mSwipeAction = SwipeAction.BEFORE_START_PAGE;
mListener.onSwipe(mSwipeAction);
callHappened = true;
} else if (mStartDragX > x && getCurrentItem() == getAdapter().getCount() - 1) {
mSwipeAction = SwipeAction.AFTER_LAST_PAGE;
mListener.onSwipe(mSwipeAction);
callHappened = true;
}
}
break;
}
return super.onInterceptTouchEvent(ev);
}
public enum SwipeAction {
BEFORE_START_PAGE, AFTER_LAST_PAGE
}
public interface OnSwipeOutListener {
void onSwipe(SwipeAction pSwipeAction);
}
}
您在 activity/fragment
中调用的代码
viewPager.setOnSwipeOutListener(new CustomViewPagerEndSwipe.OnSwipeOutListener() {
@Override
public void onSwipe(CustomViewPagerEndSwipe.SwipeAction pSwipeAction) {
switch (pSwipeAction) {
case BEFORE_START_PAGE:
new AlertDialog.Builder(getActivity()).setMessage("Swipe out start").create().show();
break;
case AFTER_LAST_PAGE:
new AlertDialog.Builder(getActivity()).setMessage("Swipe out end").create().show();
break;
}
}
});
更新自 @Mohit Suthar 的回答。在我的情况下,我使用吐司,我希望不那么敏感,并且希望发生的事情少一些。
private final static long TIME_MS = 2000;
private final static long THRESHOLD = 50;
OnSwipeOutListener mListener;
float mStartDragX;
private boolean activated = false;
private Timer mTimer;
private TimerTask mTimerTask;
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
float x = ev.getX();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mStartDragX = x;
break;
case MotionEvent.ACTION_MOVE:
Log.JSC("TEST", "1 : " + (mStartDragX < x - 20 && getCurrentItem() == 0));
Log.JSC("TEST", "2 : " + (activated));
Log.JSC("TEST", "3 : " + mStartDragX);
Log.JSC("TEST", "4 : " + x);
Log.JSC("TEST", "5 : " + (x - 20));
if (mStartDragX < x - THRESHOLD && getCurrentItem() == 0) {
if (!activated) {
activated = true;
prepareTimer();
mTimer.schedule(mTimerTask, TIME_MS);
if (mListener != null) {
mListener.onSwipeOutAtStart();
}
}
} else if (mStartDragX - THRESHOLD > x && getCurrentItem() == getAdapter().getCount() - 1) {
if (!activated) {
activated = true;
prepareTimer();
mTimer.schedule(mTimerTask, TIME_MS);
if (mListener != null) {
mListener.onSwipeOutAtEnd();
}
}
}
break;
}
try {
return super.onInterceptTouchEvent(ev);
} catch (IllegalArgumentException e) {
return false;
}
}
private void prepareTimer() {
mTimer = new Timer();
mTimerTask = new TimerTask() {
@Override
public void run() {
activated = false;
}
};
}
我有一个包含 3 个片段的 viewpager。如果我在视图寻呼机中滚动到最后一页之后,我需要显示祝酒词或警告“没有更多可用页面”。
我已经尝试了很多,但没有任何帮助。
非常感谢任何帮助。
我已经添加了代码片段,请仔细阅读
ViewPager.OnPageChangeListener viewPagerPageChangeListener = new ViewPager.OnPageChangeListener() {
boolean callHappened;
int selectedIndex;
boolean mPageEnd;
@Override
public void onPageSelected(int position) {
selectedIndex = position;
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
if( mPageEnd && arg0 == myViewPagerAdapter.getCount()-1 && !callHappened){
Log.d(getClass().getName(), "Okay");
mPageEnd = false;//To avoid multiple calls.
callHappened = true;
}else{
mPageEnd = false;
}
}
@Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
if(selectedIndex == myViewPagerAdapter.getCount() - 1)
{
mPageEnd = true;
}
}
};
您应该尝试为视图寻呼机
制作自定义视图寻呼机 class public class CustomViewPagerEndSwipe extends ViewPager {
public CustomViewPagerEndSwipe(Context context, AttributeSet attrs) {
super(context, attrs);
}
float mStartDragX;
OnSwipeOutListener mListener;
public void setOnSwipeOutListener(OnSwipeOutListener listener) {
mListener = listener;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
float x = ev.getX();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mStartDragX = x;
break;
case MotionEvent.ACTION_MOVE:
if (mStartDragX < x && getCurrentItem() == 0) {
mListener.onSwipeOutAtStart();
} else if (mStartDragX > x && getCurrentItem() == getAdapter().getCount() - 1) {
mListener.onSwipeOutAtEnd();
}
break;
}
return super.onInterceptTouchEvent(ev);
}
public interface OnSwipeOutListener {
public void onSwipeOutAtStart();
public void onSwipeOutAtEnd();
}
}
在您的布局中使用此 class xml
<com.utils.customview.CustomViewPagerEndSwipe
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
从您的 activity 和片段实施侦听器,您将从界面
获取最后一页 toastviewPager.setOnSwipeOutListener(this);
您可以使用 viewpager.canScrollHorizontally(View.SCROLL_AXIS_HORIZONTAL)
方法检查,如果它 returns 为假,那么您在查看寻呼机的最后一项。
使用了您的原始代码和@Mohit Suthar 的一些代码,但是,如果用户尝试在第一页之前滑动,@Mohit Suthar 的答案将提供大量警报(原因是因为它没有使用提问者的代码 "callHappened" 变量来避免多次调用)
如果用户在片段的上部区域向左滑动,则以下代码无法提供完美的工作。等待修改
而且我建议对您的滑动操作使用枚举,因为如果您有其他自定义逻辑,它会很灵活。
public class CustomViewPagerEndSwipe extends ViewPager {
public CustomViewPagerEndSwipe(Context context, AttributeSet attrs) {
super(context, attrs);
}
float mStartDragX;
SwipeAction mSwipeAction;
OnSwipeOutListener mListener;
boolean callHappened = false;
public void setOnSwipeOutListener(OnSwipeOutListener listener) {
mListener = listener;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
float x = ev.getX();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mStartDragX = x;
callHappened = false;
break;
case MotionEvent.ACTION_MOVE:
if (!callHappened) {
if (mStartDragX < x && getCurrentItem() == 0) {
mSwipeAction = SwipeAction.BEFORE_START_PAGE;
mListener.onSwipe(mSwipeAction);
callHappened = true;
} else if (mStartDragX > x && getCurrentItem() == getAdapter().getCount() - 1) {
mSwipeAction = SwipeAction.AFTER_LAST_PAGE;
mListener.onSwipe(mSwipeAction);
callHappened = true;
}
}
break;
}
return super.onInterceptTouchEvent(ev);
}
public enum SwipeAction {
BEFORE_START_PAGE, AFTER_LAST_PAGE
}
public interface OnSwipeOutListener {
void onSwipe(SwipeAction pSwipeAction);
}
}
您在 activity/fragment
中调用的代码viewPager.setOnSwipeOutListener(new CustomViewPagerEndSwipe.OnSwipeOutListener() {
@Override
public void onSwipe(CustomViewPagerEndSwipe.SwipeAction pSwipeAction) {
switch (pSwipeAction) {
case BEFORE_START_PAGE:
new AlertDialog.Builder(getActivity()).setMessage("Swipe out start").create().show();
break;
case AFTER_LAST_PAGE:
new AlertDialog.Builder(getActivity()).setMessage("Swipe out end").create().show();
break;
}
}
});
更新自 @Mohit Suthar 的回答。在我的情况下,我使用吐司,我希望不那么敏感,并且希望发生的事情少一些。
private final static long TIME_MS = 2000;
private final static long THRESHOLD = 50;
OnSwipeOutListener mListener;
float mStartDragX;
private boolean activated = false;
private Timer mTimer;
private TimerTask mTimerTask;
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
float x = ev.getX();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mStartDragX = x;
break;
case MotionEvent.ACTION_MOVE:
Log.JSC("TEST", "1 : " + (mStartDragX < x - 20 && getCurrentItem() == 0));
Log.JSC("TEST", "2 : " + (activated));
Log.JSC("TEST", "3 : " + mStartDragX);
Log.JSC("TEST", "4 : " + x);
Log.JSC("TEST", "5 : " + (x - 20));
if (mStartDragX < x - THRESHOLD && getCurrentItem() == 0) {
if (!activated) {
activated = true;
prepareTimer();
mTimer.schedule(mTimerTask, TIME_MS);
if (mListener != null) {
mListener.onSwipeOutAtStart();
}
}
} else if (mStartDragX - THRESHOLD > x && getCurrentItem() == getAdapter().getCount() - 1) {
if (!activated) {
activated = true;
prepareTimer();
mTimer.schedule(mTimerTask, TIME_MS);
if (mListener != null) {
mListener.onSwipeOutAtEnd();
}
}
}
break;
}
try {
return super.onInterceptTouchEvent(ev);
} catch (IllegalArgumentException e) {
return false;
}
}
private void prepareTimer() {
mTimer = new Timer();
mTimerTask = new TimerTask() {
@Override
public void run() {
activated = false;
}
};
}