我正在使用由 6 个页面组成的 ViewPager 来显示一些数据。我希望能够在用户位于位置 0 并尝试向右滑动(向后)或在位置 5 并尝试向左滑动(向前)时调用方法,即使这些页面不存在方向。有什么办法可以听这些场景吗?
5 回答
扩展 ViewPager 并onInterceptTouchEvent()
像这样覆盖:
public class CustomViewPager extends ViewPager {
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();
}
}
Flávio Faria 的回答对我不起作用。我在 onInterceptTouchEvent() 中得到的唯一事件是 ACTION_DOWN 事件。所以我重写了 onTouchEvent() 方法来让它工作。
这是代码。请注意,我在侦听器中只有 onSwipeOutAtEnd() 。您可以添加代码以支持在第一个 vier 上向左滑动。
public class CustomViewPager extends ViewPager {
float mStartDragX;
OnSwipeOutListener mListener;
public void setOnSwipeOutListener(OnSwipeOutListener listener) {
mListener = listener;
}
@Override
public boolean onTouchEvent(MotionEvent ev){
if(getCurrentItem()==getAdapter().getCount()-1){
final int action = ev.getAction();
float x = ev.getX();
switch(action & MotionEventCompat.ACTION_MASK){
case MotionEvent.ACTION_DOWN:
mStartDragX = x;
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
if (x<mStartDragX){
mListener.onSwipeOutAtEnd();
}else{
mStartDragX = 0;
}
break;
}
}else{
mStartDragX=0;
}
return super.onTouchEvent(ev);
}
public interface OnSwipeOutListener {
public void onSwipeOutAtEnd();
}
非常感谢@Flavio,虽然我不得不对他的代码进行一些更改,因为回调方法被触发了两次,我还添加了代码来检查是否有任何注册的监听器,以避免在没有注册监听器时应用程序崩溃。这是我用来使它工作的代码,包括 onSwipeOutAtStart 和 onSwipeOutAtEnd:
public class CustomViewPager extends android.support.v4.view.ViewPager {
float mStartDragX;
OnSwipeOutListener mOnSwipeOutListener;
public CustomViewPager(Context context) {
super(context);
}
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setOnSwipeOutListener(OnSwipeOutListener listener) {
mOnSwipeOutListener = listener;
}
private void onSwipeOutAtStart() {
if (mOnSwipeOutListener!=null) {
mOnSwipeOutListener.onSwipeOutAtStart();
}
}
private void onSwipeOutAtEnd() {
if (mOnSwipeOutListener!=null) {
mOnSwipeOutListener.onSwipeOutAtEnd();
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch(ev.getAction() & MotionEventCompat.ACTION_MASK){
case MotionEvent.ACTION_DOWN:
mStartDragX = ev.getX();
break;
}
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev){
if(getCurrentItem()==0 || getCurrentItem()==getAdapter().getCount()-1){
final int action = ev.getAction();
float x = ev.getX();
switch(action & MotionEventCompat.ACTION_MASK){
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
if (getCurrentItem()==0 && x>mStartDragX) {
onSwipeOutAtStart();
}
if (getCurrentItem()==getAdapter().getCount()-1 && x<mStartDragX){
onSwipeOutAtEnd();
}
break;
}
}else{
mStartDragX=0;
}
return super.onTouchEvent(ev);
}
public interface OnSwipeOutListener {
void onSwipeOutAtStart();
void onSwipeOutAtEnd();
}
}
在 ViewPager 上设置OnPageChangeListener怎么样?然后您可以修改导航箭头或 onPageScrolled 中的任何内容。
viewPager.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
updateNavigationArrows();
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
我想知道它对其他人如何起作用,它对我不起作用。
onInterceptTouchEvent()
只需要ACTION_DOWN
事件。虽然onTouchEvent()
一次只接受一个事件,但ACTION_DOWN
其他事件ACTION_UP
。
我必须覆盖两者onInterceptTouchEvent()
并onTouchEvent()
使其正常工作。的抓取初始点,并ACTION_DOWN
抓取最终点。我比较了它来检测滑动方向。onInterceptTouchEvent
X
OnTouchEvent
X2
获取触摸的初始 X 值:
float x1 = 0;
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch(ev.getAction() & MotionEventCompat.ACTION_MASK){
case MotionEvent.ACTION_DOWN:
x1 = ev.getX();
break;
}
return super.onInterceptTouchEvent(ev);
}
从 tjlian616 的代码中,onTouchEvent()
监听ACTION_UP
并获取它的最后一个X
值。虽然我已将当前项目的值设置为 0 以在启动侦听器时滑出。比较它并添加激发了听众。
@Override
public boolean onTouchEvent(MotionEvent ev){
if(getCurrentItem()==0){
final int action = ev.getAction();
switch(action & MotionEventCompat.ACTION_MASK){
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
mStartDragX = ev.getX();
if (x1<mStartDragX){
Log.i("TOUCH: ", "ACTION UP " + x1 + " : " + mStartDragX );
mListener.onSwipeOutAtStart();
}else{
Log.i("TOUCH ELSE : ", "ACTION UP " + x1 + " : " + mStartDragX );
mStartDragX = 0;
}
break;
}
}else{
mStartDragX=0;
}
return super.onTouchEvent(ev);
}