10

ViewPager で目的のフリング方向にページがないことを示す視覚的な表示を追加しようとしています。ただし、関連するコードを配置する場所を見つけるのに苦労しています。

次のコードで ViewPager クラスを拡張しようとしましたが、トーストが表示されません (ev.getOrientation()常に 0 を返します)。履歴ポイントでも同じことを試しましたが、ev.getHistorySize()0 も返されます。

私は何が欠けていますか?

クラスの例:

public class CustomViewPager extends ViewPager {

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

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

    /**
     * @see android.support.v4.view.ViewPager#onTouchEvent(android.view.MotionEvent)
     */
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        boolean result = super.onTouchEvent(ev);

        switch (ev.getAction() & MotionEventCompat.ACTION_MASK) {
            case MotionEvent.ACTION_MOVE:
                if (ev.getOrientation() > 0) {
                    Toast.makeText(getContext(), "left", 0).show();
                }
        }

        return result;
    }
}
4

8 に答える 8

19

v4 サポート ライブラリを見ると、EdgeEffectCompat と呼ばれるViewPagerによって使用されるクラスがあることがわかります(これは、ICS+ でビュー ページャーの最初または最後に到達したときにグロー効果を提供します)。ビルド バージョンが 14+ (ICS) かどうかを確認する if ステートメントがあることがわかります。そうである場合、ICS で導入された通常のEdgeEffectクラスを使用して最終的に (十分に長くトレースした場合) 終了します。それ以外の場合は、基本的に何も含まれていない BaseEdgeEffectImpl を使用します。

必要に応じて、独自の EdgeEffect を使用する独自のカスタム ViewPager を作成できます。Android のソース コードを見て、ここで EdgeEffect がどのように実装されているかを確認できます。ほとんどコピーできます (AOSP の /res/drawable ディレクトリにあるoverscroll_edgeおよびoverscroll_glowドローアブルは、Android の内部にあるため、必ず自分のプロジェクトにコピーしてください)。 ) または独自のバージョンを作成してください。

幸運を。

(ちなみに、これが ICS のランチャー メニューで見栄えの良いエッジ ティルト効果を作成する方法です。これにより、好きなだけクリエイティブにすることができます ;)

于 2012-07-15T03:37:40.920 に答える
7

私はこの質問で尋ねられたのとまったく同じ効果を得ようとしていました。私はそれに苦労し、それから@wnafeeの答えを読みました(私はそれなしではそれを行うことができませんでした)。

しかし、それから私は答えからかなり単純に聞こえるものを実装するのに苦労します。実装に非常に苦労したため、答えが正しく理解できなかった可能性がありますが、互換性ライブラリの同じパッケージで作業していなかったため、アクセスできないAPIの問題が多すぎました。

いくつかのアプローチを試した後(どれも成功せず、かなり複雑でした)、少し異なる方向に進みましたが、今ではそれは魅力のように機能します。私はいくつかの反射を使用しました、それを使用したことがない人のために、それが本当に反射の基本であることを心配しないでください。

それが最善の解決策であるかどうかはわかりませんが、私にとってはうまくいったので、それを使用したい場合は大歓迎です。私がやったことのいくつかを説明しているので、Wnafeeの例を読んでください。

このタスクを実行するには、私の3つの部分からなるソリューションに従う必要があります。(3〜10分かかります)

パートI:

Wnafeeが言ったように、ここからソースコードをコピーして貼り付けて、独自のEdgeEffectクラスを作成しました。

(AOSP / res / drawableディレクトリのoverscroll_edgeおよびoverscroll_glowドローアブルは、Androidの内部にあるため、必ず自分のプロジェクトにコピーしてください)

私は2つの本当に小さな変更をしました:

  1. クラスがEdgeEffectCompatを拡張することを宣言します(私は自分のクラスを呼び出しましたEdgeEffectForEarlyVersions)。public class EdgeEffectForEarlyVersions extends EdgeEffectCompat。この変更を行う理由は、mLeftEdgemRightEdgeがタイプであるためEdgeEffectCompatです。
  2. 「my」の新しいクラスのコンストラクターの最初の行で、親コンストラクターへの呼び出しを追加しましたsuper(context);。デフォルトのコンストラクターがないためEdgeEffectCompat、コンストラクターを明示的に呼び出す必要があります。

パートII

その上、私は別の関数を書きました。この関数の目的は、初期バージョン(ICSより前)の場合、EdgeEffectForEarlyVersionsコピーしたばかりのを使用したいということです。その目的を達成するために、私はリフレクションを使用しました。

これは機能です:

private static void changeEdgeEffectCompactOnEarlyVersions(ViewPager viewPager, Context context)
{
    /* In case that the version is earlier than 14 there is only empty implementation for the edge effect, therefore we change it.
     * for more information look on the following links:
     * 1. http://stackoverflow.com/questions/10773565/visual-indication-of-over-scroll-in-android
     * 2. http://grepcode.com/file/repo1.maven.org/maven2/com.google.android/support-v4/r7/android/support/v4/view/ViewPager.java#ViewPager.0mLeftEdge
     * 3. http://grepcode.com/file/repo1.maven.org/maven2/com.google.android/support-v4/r7/android/support/v4/widget/EdgeEffectCompat.java#EdgeEffectCompat
     */

    if (Build.VERSION.SDK_INT < 14)
    {
        try
        {
            Class<ViewPager> viewPagerClass = ViewPager.class;
            //Get the left edge field, since it is private we used getDeclaredField and not getDeclared 
            Field leftEdge = viewPagerClass.getDeclaredField("mLeftEdge");
            leftEdge.setAccessible(true);
            //Get the right edge field, since it is private we used getDeclaredField and not getDeclared
            Field rightEdge = viewPagerClass.getDeclaredField("mRightEdge");
            rightEdge.setAccessible(true);

            EdgeEffectForEarlyVersions leftEdgeEffect = new EdgeEffectForEarlyVersions(context);
            EdgeEffectForEarlyVersions rightEdgeEffect = new EdgeEffectForEarlyVersions(context);

            //Set the mLeftEdge memeber of viewPager not to be the default one, but to be "our" edgeEffect  
            leftEdge.set(viewPager, leftEdgeEffect);
            //Set the mRightEdge memeber of viewPager not to be the default one, but to be "our" edgeEffect
            rightEdge.set(viewPager, rightEdgeEffect);              
        }
        catch (Exception ex)
        {
            Log.e("refelection", ex.getMessage());
        }

    }
}

パートIII

あとは、ViewPagerインスタンスを取得した後でその関数を呼び出すだけです。

私はそれが誰かを助けることを願っています。

于 2012-08-11T03:24:50.257 に答える
3

wnafee は解決策をよく説明しましたが、私たちの間の怠け者のために、かなり前に実際に機能する実装を作成しました。

https://github.com/inovex/ViewPager3D

オーバースクロールだけが必要な場合は、こちらをご覧ください。

https://github.com/inovex/ViewPager3D/issues/1

于 2012-12-11T15:08:39.530 に答える
1

独自の edgeffect クラスを作成し、 EdgeEffectCompat から拡張するときに @goBeepit dev answer を補完するために、一部のメソッドはブール値である必要があります。これらのメソッドをブール型に変更して、どのような場合でも true を返すことができます。このようにして、すべてが正常に機能します

于 2012-09-04T16:59:22.613 に答える
0

Renard の ViewPager3D に基づいて跳ね返り効果を実装しました: https://stackoverflow.com/a/17425468/973379

于 2013-07-02T12:22:33.623 に答える
0

フラグメントで setUserVisibleHint(boolean) 関数をオーバーロードできます。擬似コード:

    void setUserVisibleHint(boolean isVisibleToUser) {
        // If this fragment is becoming visible
        if (isVisibleToUser == true) {
             // Check if it is the last fragment in the viewpager
             if (indexOfThis == getActivity().indexOfLast) {
                // Display right limit reached
                Toast(..., "No more Frags to right",...)
                }
             // Check if it is the first fragment in the viewpager
             else if (indexOfThis == getActivity().indexOfFirst) {
                // Display Left Limit reached
                Toast(..., "No more Frags to left",...)
             }
        }
    }

この目的でこの関数を使用したことはありませんが、他の理由で使用したことがあり、適切に起動します。お役に立てれば...

于 2012-07-13T10:14:00.827 に答える
-1

通常、ViewPager では、またはPagerAdapterなどを使用して ViewPager をコンテンツであふれさせます (コンテンツは views になります)。FragmentPagerAdapterFragmentStatePagerAdapter

これで、 を使用すると、http://developer.android.com/reference/android/support/v4/view/PagerAdapter.html#getCount%28%29PagerAdapterという 1 つのメソッドが作成され、次のサイズが得られます。コンテンツ。getCount()

これで、if 制御ステートメントを使用してメッセージを簡単に表示できるサイズがわかりました。

このコードを試してください: http://developer.android.com/reference/android/support/v4/view/ViewPager.html

注: カスタム ViewPager は必要ないと思います。ViewPager のフラグメントについても理解する必要があります。ApiDemos のサンプルを見てください。その素晴らしいソースです。

于 2012-06-15T09:42:26.763 に答える