27

左/右にスワイプするとタブを切り替えるビューページャーがあります.2番目のタブには、ピンチとドラッグ用のリスナーを持つカスタムビューがいくつかありますが、ピンチまたはドラッグしようとすると、ビューページャーがページをスワイプし始めます.

私の頭に浮かぶ解決策は、それらの特定のビューに触れるときはスワイプを無効にし、それらのビューの外側に触れるときだけスワイプすることです.これは可能ですか?

更新: @Asok が親切に解決策を提供してくれました。しかし、その後、私の場合は機能しないコードを更新したので、機能した以前のコードを投稿します。

public class CustomViewPager extends ViewPager {
private boolean swipeable = true;

public CustomViewPager(Context context) {
    super(context);
}

public CustomViewPager(Context context, AttributeSet attrs) {
    super(context, attrs);
}

// Call this method in your motion events when you want to disable or enable
// It should work as desired.
public void setSwipeable(boolean swipeable) {
    this.swipeable = swipeable;
}

@Override
public boolean onInterceptTouchEvent(MotionEvent arg0) {
    return (this.swipeable) ? super.onInterceptTouchEvent(arg0) : false;
}

ドラッグ可能なビューがあり、ドラッグ開始時にスワイプを無効にし、ドラッグ終了時に再度有効にする必要があるとします。いわゆるビューの TouchEvent で:

    @Override
public boolean onTouchEvent(MotionEvent event) {
    switch(event.getAction()) {
    case MotionEvent.ACTION_DOWN:
//disable swiping when the button is touched
((ActivityOriginal) getActivity()).setSwipeable(false);
//the rest of the code...
        break;
    case MotionEvent.ACTION_MOVE:

        break;
    case MotionEvent.ACTION_UP:
//re enable swipping when the touch is stopped
//the rest of the code...
((ActivityOriginal) getActivity()).setSwipeable(true);
        break;
    }
    return true;
}
4

4 に答える 4

35

私が頭に浮かぶ最初のことはViewPager、タッチ リスナーが特定のイベントの通知を受け取ったときに、swipeable booleaninViewPagerを false に設定し、アプリケーションに最適な方法で true に戻すというカスタムを用意することです。

public class CustomViewPager extends ViewPager {
    private boolean swipeable = true;

    public CustomViewPager(Context context) {
        super(context);
    }

    public CustomViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    // Call this method in your motion events when you want to disable or enable
    // It should work as desired.
    public void setSwipeable(boolean swipeable) {
        this.swipeable = swipeable;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent arg0) {
        return (this.swipeable) ? super.onInterceptTouchEvent(arg0) : false; 
    }

}

レイアウト ファイルを次のように変更してください。

<com.your.package.CustomViewPager .. />

それ以外の:

<android.support.v4.view.ViewPager .. />

編集 2

これが私のセットアップです(上記の作業CustomViewPager):

CustomViewPager mViewPager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Set up the action bar.
    final ActionBar actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    // Create the adapter that will return a fragment for each of the three
    // primary sections of the app.
    mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

    // Set up the CustomViewPager with the sections adapter.
    mViewPager = (CustomViewPager) findViewById(R.id.pager);
    mViewPager.setAdapter(mSectionsPagerAdapter);
    mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
        @Override
        public void onPageSelected(int position) {
            actionBar.setSelectedNavigationItem(position);
        }
    });

    // For each of the sections in the app, add a tab to the action bar.
    for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
        actionBar.addTab(actionBar.newTab()
                .setText(mSectionsPagerAdapter.getPageTitle(i))
                .setTabListener(this));
    }

}

public void swipeOn(View v) {
    mViewPager.setSwipeable(true);
}

public void swipeOff(View v) {
    mViewPager.setSwipeable(false);
}

上記は、拡張 および実装onCreateする私のMainActivityクラスにありますFragmentActivityActionBar.TabListener

于 2013-05-02T16:31:36.733 に答える
35

ドラッグイベントもあるビューの onTouchEvent リスナーでrequestDisallowInterceptTouchEvent(true)を使用しています。

@Override
public boolean onTouchEvent(MotionEvent event) {

    ViewParent parent = getParent(); 
    // or get a reference to the ViewPager and cast it to ViewParent

    parent.requestDisallowInterceptTouchEvent(true);

    // let this view deal with the event or
    return super.onTouchEvent(event);
}
于 2013-10-15T14:39:07.720 に答える
0

私はこのように使用しています

public void setSwipeable(boolean swipeable)
{
    this.swipeable = swipeable;
}

@Override
public void scrollTo(int x, int y){
    if (swipeable){
        super.scrollTo(x, y);
    }
}
于 2014-07-31T08:31:37.837 に答える
0

ビューページャーでタッチイベントをインターセプトしたくない位置がわかっている場合は、私のように行うことができます。

 @Override
 public boolean onInterceptTouchEvent(MotionEvent arg0) {
    if(arg0.getY()>getHeight()/2)return false;
    return super.onInterceptTouchEvent(arg0);
}
于 2019-01-27T12:47:21.550 に答える