10

私はいくつかの視覚的な表示を追加しようとしています、それ以上のページは、ViewPagerの希望の飛行方向にはありません。しかし、私は関連するコードを置く場所を見つけるのに苦労しています。アンドロイドのオーバースクロールの視覚的表示

次のコードでViewPagerクラスを拡張しようとしましたが、Toastが表示されません(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; 
    } 
} 

答えて

-1

通常ViewPagerと、一つは(あなたのコンテンツがビューあることを行っている)の内容により、ViewPagerをあふれさせるPagerAdapterなどFragmentStatePagerAdapterFragmentPagerAdapterとして、またはを使用しています。

PagerAdapterを使用すると、getCount()というhttp://developer.android.com/reference/android/support/v4/view/PagerAdapter.html#getCount%28%29という1つの方法があり、コンテンツのサイズがわかります。

あなたは今、if control文でメッセージを簡単に表示できるサイズを知っています。

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

注:私は、カスタムViewPagerが必要だと思ういけません。また、ViewPagerの断片を理解する必要があります。 ApiDemosのサンプルを見てください。その素晴らしい情報源です。

+0

ものではありませんでしたこと彼は尋ねた。彼はiOSのラバーバンドのようなオーバースクロールエフェクトを行う方法を特に知りたがっていましたが、これは少なくともICSまでViewPagerには欠けています。 –

1

多くのオプションがあります。トーストを表示したり、ダイアログを表示したり、UI上にTextViewや画像を表示させたりすることができます。また、ViewPagerのView項目の量を知っているので、メッセージで位置0および/またはn + 1で別のビューを表示し、実際にデータが含まれている最後のビューにバウンスさせます。

あなたは実現することができます。

viewPager.setOnPageChangeListener(new OnPageChangeListener() { 
    public void onPageSelected(int position) { 
     //TODO If position is the 0 or n item, add a view at 0 or at n+1 to indicate there is no more pages with data. 
    } 

    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 
     // TODO Show a Toast, View or do anything you want when position = your first/last item; 
    } 

    public void onPageScrollStateChanged(int state) { 
    } 
}); 
+2

ViewPagerの最後をスクロールしようとすると、システム標準のグロー効果があります。これは、リストの一番下をスクロールしたときと同じです。私はそのようなものが欲しいですが、すべてのバージョンで動作するはずです(現在のグローはICSのみです)。あなたの提案は、不器用なUIを作るだろう、そしてそれらが本当に唯一の選択肢であるなら、私は何の指示もしません。 –

+0

私は知っていて、私のAppのためには十分ですが、もし@ekramusが尋ねるなら、彼はもっと何かを必要としていると思います。 :) –

0

あなたが断片的にsetUserVisibleHint(ブール)関数をオーバーロードすることができます。擬似コード:

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",...) 
      } 
     } 
    } 

私はこの目的でこの機能を使用していませんが、他の理由でこの機能を使用しており、適切に発火しています。これが役に立ったら...

+0

これはOscarの答えと同じUIの意味を持ちますが、リスナーを使用するのではなくオーバーライドされないメソッドをオーバーライドするという点を除けば危険です。 –

19

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

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

幸運。

(ちなみに、それは彼らがICSのランチャーメニューで格好いいエッジ傾斜効果を作成する方法です...ので、あなたはこれをしたいとあなたはかなりの創造とすることができ;)

+0

これはそれを行う必要があるように見えます!ありがとう。 –

7

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

しかし、私は答えからかなり簡単なものを実装するのに苦労しています。 互換性ライブラリの同じパッケージで作業していなかったので、私はそれを正しく実装していない可能性があります。

私はいくつかのアプローチを試みたが(どれも成功しなかったし、かなり複雑だった)、少し違った方向に行きましたが、今は魅力的です。私はそれを使用していない人のために反射を使用しましたが、実際に反射の基本であると心配しないでください。

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

このタスクを達成するには、私の3つの部分の解決策に従ってください。 Wnafeeがちょうど(

、私はちょうど hereからソースコードをコピー&ペーストすることによって自分自身のEdgeEffectクラスを作っ言ったように

パートIを(3-10分の間表示されます) )overscroll_edgeをコピーして、彼らはアンドロイドの内部にあるので、あなた自身のプロジェクト にAOSP/RES /描画可能ディレクトリ内 ドローアブルをoverscroll_glowしてください

  1. は、私はクラスが(私は私のクラスEdgeEffectForEarlyVersionsと呼ばれる)EdgeEffectCompatを拡張することを宣言します

    は、私は2つの本当に小さな変更をしました。 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インスタンスとは何も持っていた後、その関数を呼び出すことです。

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

+0

これはv4 compat libを使ってAPI <= 8.(最新のrev 11)で動作しません。 overscrollモードを要求されたときに常にOVER_SCROLL_NEVERを返すBaseViewCompatImplを使用するためです。 onDraw()では、オーバースクロールの描画をスキップします... – Nick

1

独自のedgeffectクラスを作成してEdgeEffectCompatから拡張する場合、いくつかのメソッドはブール値である必要があります。これらのメソッドをブール型に変更し、いずれの場合もtrueを返すことができます。このようにすべてうまく動作します。

関連する問題