4

多くのページをスワイプして使用するアプリに取り組んでいますが、一部のページでは、何かを選択するまで次のページにスクロールできないようにしたいと考えています。

現時点では、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);
    }
}

注:前のページへのスワイプを防止するように実装しようとしましたが、前のページにスワイプすることはできますが、左端からスワイプして右に少しスワイプする必要があります。気まぐれですが、スワイプを完全に防ぐことはできません。

ここでやりたいことは次の 3 つです。

  1. アイテムまたは何かを選択するまで、次の画面にスクロールできないようにする
  2. 全体を通して前の画面へのスクロールを防止 (部分的に実装)
  3. Android がグラデーションで上下の画面を表示する方法のように、ユーザーにフィードバックを提供して、スクロールが無効になっていることを示します。
4

5 に答える 5

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
     }
   }

});

もっとシンプルでエレガントな解決策があるかもしれませんが、これはうまくいきました。

于 2012-11-07T13:21:23.580 に答える
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 を 1 増やします。

        maxPageToScroll = viewPager.getCurrentItem() + 1;

これはユーザーフォームのスクロールを妨げないことに注意してください...ビューページャーがページを変更するのを妨げるだけです。

于 2013-02-22T08:04:00.700 に答える
-1

ユーザーが通過できない最大ページを持つウィザードのビューページャーを実装しました。

最後に、解決策はアダプターにありました。PagerAdapter のカウントを変更すると、ユーザーが最大ページを通過するのをブロックします。

@Override
public int getCount() {
    return mProgress; //max page + 1
}

ユーザーが次のページに進むと:

private void setWizardProgress(int progress) {
    if(progress > mProgress) {
        mProgress = progress;
        mWizardPagerAdapter.notifyDataSetChanged();
    }
}

このようにして、ユーザーが最大ページにいるとき、進行状況が更新されるまで右にスクロールできません。

于 2014-02-06T12:49:25.327 に答える