我想只允许用户在ViewPager
中从右向左滑动。因此,一旦他通过了一个页面,他就不能再回到那个页面。如何做到这一点?
我尝试过解决方案:
public class CustomViewPager extends ViewPager {
float lastX = 0;
boolean lockScroll = false;
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomViewPager(Context context) {
super(context);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
lastX = ev.getX();
lockScroll = false;
return super.onTouchEvent(ev);
case MotionEvent.ACTION_MOVE:
if (lastX > ev.getX()) {
lockScroll = false;
} else {
lockScroll = true;
}
lastX = ev.getX();
break;
}
lastX = ev.getX();
if(lockScroll) {
return false;
} else {
return super.onTouchEvent(ev);
}
}
}
但它仍然允许我在另一个方向上刷得很差。
发布于 2015-12-04 05:37:39
您还会错过另一个事件: onInterceptTouchEvent。它必须包含与onTouchEvent相同的逻辑。
我的完整解决方案是基于this answer。它将允许您在需要的任何时间启用/禁用任何方向的分页。
枚举1.创建枚举
public enum SwipeDirection {
ALL, LEFT, RIGHT, NONE ;
}
Java2.扩展ViewPager (在中)
public class CustomViewPager extends ViewPager {
private float initialXValue;
private SwipeDirection direction;
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
this.direction = SwipeDirection.ALL;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (this.isSwipeAllowed(event)) {
return super.onTouchEvent(event);
}
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (this.isSwipeAllowed(event)) {
return super.onInterceptTouchEvent(event);
}
return false;
}
private boolean isSwipeAllowed(MotionEvent event) {
if(this.direction == SwipeDirection.ALL) return true;
if(direction == SwipeDirection.NONE )//disable any swipe
return false;
if(event.getAction()==MotionEvent.ACTION_DOWN) {
initialXValue = event.getX();
return true;
}
if (event.action === MotionEvent.ACTION_MOVE) {
val diffX = event.x - initialXValue
if (diffX > 0 && direction === SwipeDirection.RIGHT) {
// swipe from left to right detected
return false
} else if (diffX < 0 && direction === SwipeDirection.LEFT) {
// swipe from right to left detected
return false
}
}
return true;
}
public void setAllowedSwipeDirection(SwipeDirection direction) {
this.direction = direction;
}
}
2.扩展ViewPager (in )
enum class SwipeDirection {
ALL, LEFT, RIGHT, NONE
}
class SingleDirectionViewPager @JvmOverloads constructor(
context: Context,
attrs: AttributeSet?
) : ViewPager(context, attrs) {
private var initialXValue = 0f
private var direction: SwipeDirection = SwipeDirection.ALL
override fun onTouchEvent(event: MotionEvent): Boolean =
if (isSwipeAllowed(event)) {
super.onTouchEvent(event)
} else {
false
}
override fun onInterceptTouchEvent(event: MotionEvent): Boolean =
if (isSwipeAllowed(event)) {
super.onInterceptTouchEvent(event)
} else {
false
}
private fun isSwipeAllowed(event: MotionEvent): Boolean {
if (direction == SwipeDirection.ALL) {
return true
}
if (direction == SwipeDirection.NONE) {
return false
}
if (event.action == MotionEvent.ACTION_DOWN) {
initialXValue = event.x
return true
}
if (event.action == MotionEvent.ACTION_MOVE) {
val diffX = event.x - initialXValue
if (diffX > 0 && direction === SwipeDirection.RIGHT) {
// swipe from left to right detected
return false
} else if (diffX < 0 && direction === SwipeDirection.LEFT) {
// swipe from right to left detected
return false
}
}
return true
}
fun setAllowedSwipeDirection(direction: SwipeDirection) {
this.direction = direction
}
}
3.在布局中使用viewPager
<package_name.customviewpager
android:id="@+id/customViewPager"
android:layout_height="match_parent"
android:layout_width="match_parent" />
4.在代码中启用任何滑动方向。默认值为all (右和左)
mViewPager.setAllowedSwipeDirection(SwipeDirection.RIGHT);
发布于 2017-07-29 11:58:38
package com.contacts_app.jamison.contacts__proprivacy4;
import android.content.Context;
import android.content.res.Resources;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
public class ViewPager_Settings extends ViewPager
{
private final String TAG = ViewPager_Settings.class.getSimpleName();
public float startX;
public ViewPager_Settings(Context context, AttributeSet attrs) {
super(context, attrs);
}
////////////////////////////////////////////////////////////////////////////////////////////////
public static int dpTOpx(double dp)
{
return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}
public static int pxTOdp(double px)
{
return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}
////////////////////////////////////////////////////////////////////////////////////////////////
/*****DispatchTouchEvent for the View Pager to intercept and block swipes Right*****/
@Override
public boolean dispatchTouchEvent(MotionEvent ev)
{
final int actionMasked = ev.getActionMasked() & MotionEvent.ACTION_MASK;
//int movement_limit = pxTOdp(50);
switch (actionMasked)
{
case (MotionEvent.ACTION_DOWN):
{
startX = ev.getX();
Log.i(TAG, "startX: " + startX);
/*Should always be this below*/
return super.dispatchTouchEvent(ev);
}
case (MotionEvent.ACTION_MOVE):
{
Log.i(TAG, "ev.getX() - startX:" + (ev.getX() - startX));
/*Switching directional changes would be a matter of flipping the "<" sign in the line below.*/
if (ev.getX() - startX > 0)
{
/*The result is that the ViewPager will not swipe from left*/
ev.setAction(MotionEvent.ACTION_CANCEL);;
}
/*Should always be this below*/
super.dispatchTouchEvent(ev);
}
/**The ACTION_UP case statement is only needed if you don't want to pass down the touch event
* to buttons that may receive the click after the swipe is blocked.*/
/*case (MotionEvent.ACTION_UP):
{
//Log.i(TAG, "movement_limit: " + movement_limit);
//(-50) may need to be changed to something more broader in scope to accompany all screen densities
if ( (ev.getX() - startX) < (-50) )
{
ev.setAction(MotionEvent.ACTION_CANCEL);
}
//Should always be this below
super.dispatchTouchEvent(ev);
}*/
}
/*Should always be this below*/
return super.dispatchTouchEvent(ev);
}
////////////////////////////////////////////////////////////////////////////////////////////////
}/*****END OF FILE*****/
不要忘记更改顶部的行,以放置您的应用程序的包名。此外,即使不是全部,也是大多数评论都提供了代码正在做什么的洞察力,以防您决定要修补一些东西。
发布于 2014-12-14 09:05:51
如下定义您的适配器
public class MyFragmentStatePagerAdapter extends FragmentStatePagerAdapter {
private final int totalPages = 10;
private int currentPage = 0;
public MyFragmentStatePagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
// Use whatever logic you want here to
// to select a fragment based on
// currentPage instead of position
if (currentPage % 2 == 0) {
return new Fragment1();
} else {
return new Fragment2();
}
}
@Override
public int getCount() {
return currentPage == totalPages ? 1 : 2;
}
@Override
public int getItemPosition(Object object){
return PagerAdapter.POSITION_NONE;
}
public void nextPage() {
currentPage++;
notifyDataSetChanged();
}
}
在使用视图分页程序的片段中,执行以下操作
@Override
public void onPageSelected(int arg0) {
if (arg0 > 0) {
pagerAdapter.nextPage();
pager.setCurrentItem(0, false);
}
}
https://stackoverflow.com/questions/19602369
复制相似问题