ViewPagerで指でスワイプしてページングを無効にし、プログラムでスワイプできるようにするにはどうすればよいですか?


550

ViewPagerがあり、その下に10個のボタンがあります。ボタン#4などをクリックすると、ポケットベルはによってすぐにページ4に移動しmPager.setCurrentItem(3);ます。しかし、指で水平にスワイプしてページングを無効にしたいと思います。したがって、ページングはボタンをクリックすることによってのみ行われます。では、指でのスワイプを無効にするにはどうすればよいですか?


そもそもViewFlipperを使ってませんか?それはあなたに大きな頭痛の種を救います。
Alex Semeniuk

回答:


885

サブクラス化する必要がありViewPagerます。 onTouchEvent子ビューにタッチを許可するなど、変更したくない多くの良い点があります。 onInterceptTouchEventあなたが変えたいものです。のコードをViewPager見ると、コメントが表示されます。

    /*
     * This method JUST determines whether we want to intercept the motion.
     * If we return true, onMotionEvent will be called and we do the actual
     * scrolling there.
     */

ここに完全なソリューションがあります:

まず、このクラスをsrcフォルダーに追加します。

import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.animation.DecelerateInterpolator;
import android.widget.Scroller;
import java.lang.reflect.Field;

public class NonSwipeableViewPager extends ViewPager {

    public NonSwipeableViewPager(Context context) {
        super(context);
        setMyScroller();
    }

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

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        // Never allow swiping to switch between pages
        return false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // Never allow swiping to switch between pages
        return false;
    }

    //down one is added for smooth scrolling

    private void setMyScroller() {
        try {
            Class<?> viewpager = ViewPager.class;
            Field scroller = viewpager.getDeclaredField("mScroller");
            scroller.setAccessible(true);
            scroller.set(this, new MyScroller(getContext()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public class MyScroller extends Scroller {
        public MyScroller(Context context) {
            super(context, new DecelerateInterpolator());
        }

        @Override
        public void startScroll(int startX, int startY, int dx, int dy, int duration) {
            super.startScroll(startX, startY, dx, dy, 350 /*1 secs*/);
        }
    }
}

次に、ViewPagerおそらくとして指定した通常のの代わりに、このクラスを使用してくださいandroid.support.v4.view.ViewPager。レイアウトファイルでは、次のように指定します。

<com.yourcompany.NonSwipeableViewPager
    android:id="@+id/view_pager"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1" />

この特定の例はにありLinearLayout、画面全体を占めることを意図しています。そのため、layout_weightは1で、layout_height0 dpです。

そして、setMyScroller();方法はスムーズな移行のためのものです


3
@louielouie補足:特別な理由はありますか?フルスクリーン効果を実現するために高さよりも高0dpさ/ 1重量ソリューションを選択した理由は何match_parentですか?そうすることでパフォーマンスが向上しますか?
ubuntudroid 2013

29
この回答は、キーボードの左/右キーを使用するときにページスワイプを妨げません(エミュレータで試してください)。タッチデバイスでは問題にならないかもしれませんが、テレビやラップトップでは問題になる可能性があります。
Vincent Mimoun-Prat 2014

8
@MarvinLabs @Thorbearキーボードによるページスクロールを無効にする正しい方法は、をオーバーライドすることexecuteKeyEvent()です。これは、次に呼び出すメソッドですallowScroll()// Never allow swiping by keyboard LEFT, RIGHT, TAB and SHIFT+TAB keys @Override public boolean executeKeyEvent(KeyEvent event) { return false; }
2015年

6
まあ、これは垂直スクロールも無効にします...リストビューを使用している場合、これは悪いことです。
Maysi

5
私はそれが害を及ぼさないと私が信じているので、グーグルがタッチ/スワイプを処理する方法に関するインターフェースメソッドを提供するメソッドを提供したかもしれないと思いますか?
ネオンワージ2015年

466

のより一般的な拡張は、ページングをオンザフライで有効化および無効化できるようにメソッドViewPagerを作成するSetPagingEnabledことです。スワイプを有効または無効にするには、2つのメソッドをオーバーライドonTouchEventonInterceptTouchEventます。ページングが無効になっている場合、どちらも「false」を返します。

public class CustomViewPager extends ViewPager {

    private boolean enabled;

    public CustomViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.enabled = true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (this.enabled) {
            return super.onTouchEvent(event);
        }

        return false;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        if (this.enabled) {
            return super.onInterceptTouchEvent(event);
        }

        return false;
    }

    public void setPagingEnabled(boolean enabled) {
        this.enabled = enabled;
    } 
}

次に、XMLの組み込みのビューページャーの代わりにこれを選択します

<mypackage.CustomViewPager 
    android:id="@+id/myViewPager" 
    android:layout_height="match_parent" 
    android:layout_width="match_parent" />

setPagingEnabledメソッドを呼び出すだけでfalse、ユーザーはページを移動するためにスワイプできなくなります。


3
水平スクロールを使用する複数のサブビューがあるビュー(AChartEngineチャートなど)に最適です。私のフラグメントでは、アクティビティへのコールバックを使用して、ユーザーがチャートにタッチした(ACTION_MOVE)か、チャートから離した(ACTION_CANCEL)かに応じて、ページングをオフまたはオフにするように指示しています。どうもありがとう!
riper

32
あなたは簡単にすることができるonTouchEventonInterceptTouchEventしてメソッドをreturn enabled && super.onTouchEvent(event);
nbarraille

2
@nbarrailleそれはスタイルの問題です。より読みやすいスタイルを使用できます。
Rajul 2014

7
また、フィールドの名前を「有効」から「swipePageChangeEnabled」などに変更することをお勧めします。コードを書いてから1か月後、「有効」が何を意味するのかほとんど覚えていないでしょう。特に、クラスが「CustomViewPager」と呼ばれる場合、カスタマイズが何であるかが明確ではありません。それはスタイルの問題でもありますが、サポートできないプロジェクトになりたくない場合はスタイルが重要です。修正するよりも完全に書き直す方が簡単です。
bytefu 2015

4
どこでsetPagingEnabledを呼び出しますか?._。
Ntikki 2015年

107

最も簡単な方法は、setOnTouchListenerに戻り、に戻ることtrueですViewPager

mPager.setOnTouchListener(new OnTouchListener()
    {           
        @Override
        public boolean onTouch(View v, MotionEvent event)
        {
            return true;
        }
    });

53
時々動作しません。私はFragmentPagerAdapterといくつかのFragmentでViewPagerを使用しています。OnTouchListenerをポケットベルに設定した後、左にフリングすると、UIはまだ少し左に移動します。
Chris.Zou 2013

16
pager.setCurrentItem(pager.getCurrentItem());戻る前に追加すると機能しますtrue
dng

1
以前はうまくいきました。なぜそれがもううまくいかないのか分かりません。
Android開発者

私のために働くようです。public int getItemPosition(Object object) { return POSITION_NONE; }アダプターにあるレイアウトの不具合を解決するには、ページの再作成を強制し、おそらく他の問題も解決します。
r-hold

6
これは部分的に機能するソリューションです。水平スワイプが奇妙な方法で処理されます。これをViewPagerの一部としてDrag'n Drop Gridviewでテストしました。このソリューションを使用してドラッグすると、左から右および右から左へのドラッグが失敗します。個人的には、ラジュルのアプローチが一番良いと思います。
トンSnoei 14

58

スタイル可能として宣言する方が良いので、そのプロパティをxmlから変更できます:

private boolean swipeable;

public MyViewPager(Context context, AttributeSet attrs) {
    super(context, attrs);
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyViewPager);
    try {
        swipeable = a.getBoolean(R.styleable.MyViewPager_swipeable, true);
    } finally {
        a.recycle();
    }
}

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

@Override
public boolean onTouchEvent(MotionEvent event) {
    return swipeable ? super.onTouchEvent(event) : false;
}

そして、あなたのvalues / attr.xmlで:

<declare-styleable name="MyViewPager">
  <attr name="swipeable" format="boolean" />
</declare-styleable>

レイアウトxmlで使用できるように:

<mypackage.MyViewPager
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/viewPager"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:swipeable="false" />

もちろん、まだget / setプロパティを持つことができます。


58

別のViewPager内にViewPager自体がある場合は、オーバーライドのみonTouchEventonInterceptTouchEvent十分ではありません。子ViewPagerは、最初/最後のページに配置されていない限り、親ViewPagerから水平スクロールタッチイベントを盗みます。

この設定を正しく機能させるには、canScrollHorizontallyメソッドもオーバーライドする必要があります。

LockableViewPager以下の実装を参照してください。

public class LockableViewPager extends ViewPager {

    private boolean swipeLocked;

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

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

    public boolean getSwipeLocked() {
        return swipeLocked;
    }

    public void setSwipeLocked(boolean swipeLocked) {
        this.swipeLocked = swipeLocked;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return !swipeLocked && super.onTouchEvent(event);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        return !swipeLocked && super.onInterceptTouchEvent(event);
    }

    @Override
    public boolean canScrollHorizontally(int direction) {
        return !swipeLocked && super.canScrollHorizontally(direction);
    }

}

3
ありがとう、これは別のViewPager内のViewPagerで非常にうまく機能します。
Fernanda Bari

1
これは私にも、別のViewPager内のViewPagerにも機能します。その場合、正しい解決策が機能しませんでした。
Rafael

タブで使用するとアニメーションも停止します。
Rishabh Srivastava 2017

無効にして有効にしたい場合は、setSwipeLocked(false)を呼び出すイベントをどこで取得できますか?
Ravi Yadav

57

これで、カスタムを作成する必要はありません ViewPager

ViewPager2 Androidで利用可能な新しい名前ビュー

垂直方向のサポート

  • ViewPager2従来の水平ページングに加えて垂直ページングをサポートします。属性をViewPager2設定することにより、要素の垂直ページングを有効にすることができandroid:orientationます

XMLの使用

<androidx.viewpager2.widget.ViewPager2
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:orientation="vertical" />

コードを使用する

使用中のスワイプを無効にするにviewpager2

viewPager2.setUserInputEnabled(false);

viewpager2使用中のスワイプを有効にするには

viewPager2.setUserInputEnabled(true);

詳細については、こちらを確認してください

更新


3
それは素晴らしいですが、それでも不完全であるように見えます。私は5つの断片とそれを試してみたとページ断片のうちの1つとの間に切り替えた後に失われた種類の、すなわちビューはどちらも回復していないされなかったも再膨張させた
Toochka

私のためにそれが正常に動作していますが、ここからサンプル動作するコードを見つけることができますことを聞いて申し訳ありません@Toochka stackoverflow.com/a/54643817/7666442あなたのコード共有してください可能な場合
Nilesh Rathod

1
この方法を使用して、ViewPager2でのスワイプを無効にできました
voghDev

1
聞いて@voghDev幸せ
Nilesh Rathod

1
@PhaniRithvijこの回答を確認してくださいstackoverflow.com/a/54643817/7666442 i使用方法の詳細をすべて追加viewpager2しましたRecyclerView.Adapter
Nilesh Rathod

35

ViewPagerから拡張する場合は、前に@araksで示したようにオーバーライドする必要もあります。executeKeyEvent

@Override
public boolean executeKeyEvent(KeyEvent event)
{
    return isPagingEnabled ? super.executeKeyEvent(event) : false;
}

Galaxy Tab 4 10 'のような一部のデバイスでは、ほとんどのデバイスでは表示されないこれらのボタンが表示されます。

キーボードのボタン


50
サムスンは常にAndroid開発者のために物事を台無しにしています。
toobsco42

2
@ toobsco42この場合、サムスンだけではありません。SwiftKey(人気のキーボードアプリ)を使用すると、キーボードに矢印を付けることができます。
スーフィアン2016年

1
これは、キーボード/トラッカーボールを使用している誰かがポケットベルをページングしないようにする場合の修正でもあります。
se22as 2017年

28

スワイプを無効にするには

mViewPager.beginFakeDrag();

スワイプを有効にするには

mViewPager.endFakeDrag();

22
少なくとも私のアプリでは、動きの小さな部分を許容するため、これは良い解決策ではありません。
koras

私にとってはうまくいきます。提供されている他のソリューションと比較した場合の欠点は何ですか?
userM1433372

13

特定の1ページでスワイプを無効にし、ラバーバンドのアニメーションを表示する必要がありました。その方法は次のとおりです。

    mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {

        @Override
        public void onPageScrolled(int position, float positionOffset,
                                   int positionOffsetPixels) {
            if (position == MANDATORY_PAGE_LOCATION && positionOffset > 0.5) {
                mViewPager.setCurrentItem(MANDATORY_PAGE_LOCATION, true);
            }
        }

次のページが部分的に表示されるまで待機します。の次のページのコードonPageSelectedが実行されます。次のページでも切り替わります。したがって、このコードは必要ありません。
CoolMind 2018

13

私はこれを投稿するのがとても遅いことを知っていますが、これはあなたの結果を達成するための小さなハックです;)

ビューページャーの下にダミービューを追加するだけです。

<android.support.v4.view.ViewPager
     android:layout_width="match_parent"
     android:layout_height="match_parent">
</android.support.v4.view.ViewPager>

<RelativeLayout
     android:id="@+id/dummyView"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
</RelativeLayout>

次に、OnClickListenerをに追加しますRelativeLayout

dummyView = (RelativeLayout) findViewById(R.id.dummyView);

dummyView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
         //Just leave this empty
    }
});

レイアウト、配置、動作を少し工夫すれば、想像したことをすべて実行する方法を見つけることができます。

幸運を!


より簡単な方法は、イベントを処理する必要がない場合setClickablesetOnClickListener、の代わりに使用することですonClick
カオス

これもビューページャー内のタッチをブロックしませんか?
Android開発者

はい、そうです。これは、OP @androiddeveloperに必要な予想される動作です
Dinuka Jay

@RickGrimesTheCoderあなたは私の質問を理解していないと思います。ビューページャーのフラグメント内のビューを意味します。彼らはまだ触れることができますか?
Android開発者

いいえ、viewpager自体にクリックリスナーがあるため、そうではありません。これは、フラグメント内にインタラクティブな要素がない場合にのみ適しています。たとえば、フラグメントを動的に変更するWelcome ViewPager @androiddeveloper
Dinuka Jay

12

私はCustomViewPagerスワイプコントロールでを書きました:

public class ScrollableViewPager extends ViewPager {
    private boolean canScroll = true;
    public ScrollableViewPager(Context context) {
        super(context);
    }
    public ScrollableViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public void setCanScroll(boolean canScroll) {
        this.canScroll = canScroll;
    }
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return canScroll && super.onTouchEvent(ev);
    }
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return canScroll && super.onInterceptTouchEvent(ev);
    }
}

あなたが設定した場合canScrolltrue、これはViewPager、指でスワイプすることができfalse、逆に。

私はこれを自分のプロジェクトで使用していますが、今まではうまくいきます。


1
ViewPager内にボタンがあり、クリックしたい場合はどうなりますか?この解決策は... viewpager以下のすべてのものをクリックすることを停止する
aimiliano

6

私はこのクラスを成功させました。一部のデバイスで矢印を使用したスワイプを回避するため、またはアクセシビリティのために、executeKeyEventをオーバーライドする必要があります。

import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;

public class ViewPagerNoSwipe extends ViewPager {
    /**
     * Is swipe enabled
     */
    private boolean enabled;

    public ViewPagerNoSwipe(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.enabled = false; // By default swiping is disabled
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return this.enabled ? super.onTouchEvent(event) : false;
    }

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

    @Override
    public boolean executeKeyEvent(KeyEvent event) {
        return this.enabled ? super.executeKeyEvent(event) : false;
    }

    public void setSwipeEnabled(boolean enabled) {
        this.enabled = enabled;
    }

}

そしてxmlでこれを次のように呼び出します:

<package.path.ViewPagerNoSwipe
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

できます。スワイプのみが無効になり、タブをクリックすることが有効になります。AS performClick()は、メソッドがオーバーライドされないことを警告します。
CoolMind 2018

5

Kotlinでは、上記の答えを組み合わせた私の解決策。

class CustomViewPager(context: Context, attrs: AttributeSet): ViewPager(context, attrs) {
    var swipeEnabled = false

    override fun onTouchEvent(ev: MotionEvent?): Boolean {
        return if (swipeEnabled) super.onTouchEvent(ev) else false
    }

    override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
        return if (swipeEnabled) super.onInterceptTouchEvent(ev) else false
    }

    override fun executeKeyEvent(event: KeyEvent): Boolean {
        return if (swipeEnabled) super.executeKeyEvent(event) else false
    }
}

オーバーライドonInterceptTouchEvent()すると、子ビューが入力を受け取ることができなくなります。ほとんどの場合、これは意図された動作ではありません。
Alex Semeniuk

各フラグメントの子ビューと対話することができました。何を参照しているかわからない。
ジェフパジェット

5

Kotlinでは、ViewPagerクラスを継承するカスタムウィジェットを作成し、スワイプ動作を制御するためのフラグ値を追加することで、これを解決できます。

NoSwipePager.kt

class NoSwipePager(context: Context, attrs: AttributeSet) : ViewPager(context, attrs) {

    var pagingEnabled: Boolean = false

    override fun onTouchEvent(event: MotionEvent): Boolean {
        return if (this.pagingEnabled) {
            super.onTouchEvent(event)
        } else false
    }

    override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
        return if (this.pagingEnabled) {
            super.onInterceptTouchEvent(event)
        } else false
    }
}

XMLで

<your.package.NoSwipePager
    android:id="@+id/view_pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@id/tab_layout" />

プログラムでスワイプを無効にします。kotlin-android-extensionsプラグインがbuild.gradleで適用されている場合、以下のコードを記述することでスワイプを無効にすることができます。

view_pager.pagingEnabled = false

それ以外の場合は、以下のコードを使用してスワイプを無効にすることができます。

val viewPager : ViewPager = findViewById(R.id.view_pager)
viewPager.pagingEnabled = false

オーバーライドonInterceptTouchEvent()すると、子ビューが入力を受け取ることができなくなります。ほとんどの場合、これは意図された動作ではありません
Alex Semeniuk

@AlexSemeniukこれを実装した後に問題が発生しましたか?一部のアクションでリサイクラービューのアイテムをスワイプできるようにしましたが、正常に動作しています。したがって、私の場合、実装は正常に機能しています。
Sagar Chapagain

Sagar Chapagain:またはもちろんです。各ページにはカスタムビューが含まれており、タッチをさまざまな方法で処理します(スクロール、ドラッグ、シングルタップ、ロングタップなど)。super.onInterceptTouchEvent(event)これらのビューで結果を呼び出さないと、入力を受け取りません(これはonInterceptTouchEventメソッドの文書化された目的です)。
Alex Semeniuk

その場合は、子フラグメントを使用してバックスタックを維持する必要があります。
Sagar Chapagain

これは現在の質問にどのように関連していますか?フラグメントはいくつかのコンテナ(Views)内に配置され、独自のレイアウトにはViewsが含まれます。ViewPager内にあるコンテンツに関係なく、onInterceptTouchEvent()メソッドをオーバーライドすると、コンテンツ(コンテンツ)が入力を受け取ることができないという事実に対処しています。
Alex Semeniuk


1

特定のページ(この例では2ページ目)でスワイプを無効にする別の簡単なソリューション:

int PAGE = 2;
viewPager.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
        if (viewPager.getCurrentItem() == PAGE) {
                viewPager.setCurrentItem(PAGE-1, false);
                viewPager.setCurrentItem(PAGE, false);
                return  true;
        }
        return false;
}

1
This worked for me

viewPager.setOnTouchListener(new View.OnTouchListener() {
                                         @Override
                                         public boolean onTouch(View v, MotionEvent event) {
                                             if (viewPager.getCurrentItem() == 0) {
                                                 viewPager.setCurrentItem(-1, false);
                                                 return true;
                                             }
                                             else if (viewPager.getCurrentItem() == 1) {
                                                 viewPager.setCurrentItem(1, false);
                                                 return true;
                                             }
                                             else if (viewPager.getCurrentItem() == 2) {
                                                 viewPager.setCurrentItem(2, false);
                                                 return true;
                                             }
                                             return true;
                                         }
                                     });

1

ズームとパンをサポートするImageViewsとViewPagerを使用してイメージギャラリーを作成する場合は、Phimpme Android (およびGithubサンプル-PhotoViewのデフォルトのViewPagerを拡張してズーム可能なImageViewを実装する、ここで説明する簡単なソリューションを参照してください。このソリューションは、ViewPager単独では機能しません。

public class CustomViewPager extends ViewPager {
    public CustomViewPager(Context context) {
        super(context);
    }

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

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        try {
            return super.onInterceptTouchEvent(event);
        } catch (IllegalArgumentException e) {
            return false;
        }
    }
}

1

ViewPager2を使用している場合は、以下を使用する必要があります。

viewpager.setUserInputEnabled(false);

ドキュメントから:

ユーザーが開始したスクロールを有効または無効にします。これには、タッチ入力(スクロールおよびフリングジェスチャー)とアクセシビリティ入力が含まれます。キーボード入力の無効化はまだサポートされていません。ユーザーが開始したスクロールが無効になっている場合でも、プログラムによるsetCurrentItemのスクロールは機能します。デフォルトでは、ユーザーが開始したスクロールは有効になっています。

おかげで:https : //stackoverflow.com/a/61685871/9026710


0

Xamarinで同じものをAndroidに実装する場合は、C#に翻訳します。

私は属性に「ScrollEnabled」という名前を付けました。iOSは同じ名前のexcatを使用するだけだからです。したがって、両方のプラットフォームで同じ名前を付けることで、開発者にとってより簡単になります。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Support.V4.View;
using Android.Util;

namespace YourNameSpace.ViewPackage {

    // Need to disable swiping for ViewPager, if user performs Pre DSA and the dsa is not completed yet
    // http://stackoverflow.com/questions/9650265/how-do-disable-paging-by-swiping-with-finger-in-viewpager-but-still-be-able-to-s
    public class CustomViewPager: ViewPager {
        public bool ScrollEnabled;

        public CustomViewPager(Context context, IAttributeSet attrs) : base(context, attrs) {
            this.ScrollEnabled = true;
        }

        public override bool OnTouchEvent(MotionEvent e) {
            if (this.ScrollEnabled) {
                return base.OnTouchEvent(e);
            }
            return false;
        }

        public override bool OnInterceptTouchEvent(MotionEvent e) {
            if (this.ScrollEnabled) {
                return base.OnInterceptTouchEvent(e);
            }
            return false;
        }

        // For ViewPager inside another ViewPager
        public override bool CanScrollHorizontally(int direction) {
            return this.ScrollEnabled && base.CanScrollHorizontally(direction);
        }

        // Some devices like the Galaxy Tab 4 10' show swipe buttons where most devices never show them
        // So, you could still swipe through the ViewPager with your keyboard keys
        public override bool ExecuteKeyEvent(KeyEvent evt) {
            return this.ScrollEnabled ? base.ExecuteKeyEvent(evt) : false;
        }
    }
}

.axmlファイル:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
  <YourNameSpace.ViewPackage.CustomViewPager
      android:id="@+id/pager"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:background="@android:color/white"
      android:layout_alignParentTop="true" />
</LinearLayout>

0

上記のコードはどれもスムーズに機能していません。

<HorizontalScrollView
                    android:id="@+id/horizontalScrollView"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:fillViewport="true">

                    <android.support.v4.view.ViewPager
                        android:id="@+id/pager"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent" />
                </HorizontalScrollView>

0

これが私の実装
です。スワイプアニメーションを無効にしたい場合は、swipeListenerを左右に使用し、指なしでスクロールできますが、アニメーションは必要ありません。

1-オーバーライドViewpagerメソッドonInterceptTouchEventonTouchEvent

2-自分で作成 GestureDetector

3-スワイプジェスチャーを検出し、 setCurrentItem(item, false)

ViewPager

public class ViewPagerNoSwipe extends ViewPager {
    private final GestureDetector gestureDetector;
    private OnSwipeListener mOnSwipeListener;

    public void setOnSwipeListener(OnSwipeListener onSwipeListener) {
        mOnSwipeListener = onSwipeListener;
    }

    public ViewPagerNoSwipe(@NonNull Context context) {
        super(context);
        gestureDetector = new GestureDetector(context, new GestureListener());

    }

    public ViewPagerNoSwipe(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        gestureDetector = new GestureDetector(context, new GestureListener());


    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return true;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        gestureDetector.onTouchEvent(ev);
        return false;
    }

    public class GestureListener extends GestureDetector.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 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) {
                            if(mOnSwipeListener!=null)
                            mOnSwipeListener.onSwipeRight();
                        } else {
                            if(mOnSwipeListener!=null)
                                mOnSwipeListener.onSwipeLeft();
                        }
                        result = true;
                    }
                } else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffY > 0) {
                        if(mOnSwipeListener!=null)
                            mOnSwipeListener.onSwipeBottom();
                    } else {
                        if(mOnSwipeListener!=null)
                            mOnSwipeListener.onSwipeTop();
                    }
                    result = true;
                }
            } catch (Exception exception) {
                exception.printStackTrace();
            }
            return result;
        }
    }

    public interface OnSwipeListener {

         void onSwipeRight();

        void onSwipeLeft();

        void onSwipeTop();

        void onSwipeBottom();
    }
}

ViewPagerのセットアップ時に、swipeListenerを設定します

postsPager.setOnSwipeListener(new ViewPagerNoSwipe.OnSwipeListener() {
            @Override
            public void onSwipeRight() {

              postsPager.setCurrentItem(postsPager.getCurrentItem() + 1,false);

            }

            @Override
            public void onSwipeLeft() {

            postsPager.setCurrentItem(postsPager.getCurrentItem() - 1, false);

            }
             ...
           }

0

ビューページャーを少しカスタマイズして、スワイプを簡単に無効にしました。

public class CustomViewPager extends ViewPager {

private boolean swipeLocked;

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

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

public boolean getSwipeLocked() {
    return swipeLocked;
}

public void setSwipeLocked(boolean swipeLocked) {
    this.swipeLocked = swipeLocked;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    return !swipeLocked && super.onTouchEvent(event);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    return !swipeLocked && super.onInterceptTouchEvent(event);
}

@Override
public boolean canScrollHorizontally(int direction) {
    return !swipeLocked && super.canScrollHorizontally(direction);
}
}

-1
shareViewPager?.setOnTouchListener(object :View.OnTouchListener{
            override fun onTouch(v: View?, event: MotionEvent?): Boolean {
                for (PAGE in 0..shareViewPager.adapter!!.count){
                    if (shareViewPager.currentItem==PAGE){
                        shareViewPager.setCurrentItem(PAGE-1,false)
                        shareViewPager.setCurrentItem(PAGE,false)
                    }}
                return true
            }

        })
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.