2012-11-01 16 views
12

私は(シャーロック)FragmentActivityに2つのタブ付きフラグメントがあります。左側のフラグメントは、アルバムの画像を表示するGridViewであり、右側のフラグメントは個々の画像を表示するために使用されるViewPagerから構成されます。左の断片から、画像をスクロールして選択することができます。右のフラグメントにタブ(またはスワイプ)で移動すると、そのピクチャが表示され、ViewPagerなので前または次のピクチャにスワイプできます。FragmentActivityのタブ間でのスワイプを無効にする

これは、FragmentActivityが右のスワイプをインターセプトして、左のタブに戻ることを除いて、素晴らしいことです。私は右のタブにいるときにFragmentActivityがスワイプを傍受しないようにしたいと思います。私がタブ間でのスワイプを完全に無効にしなければならないとすれば、それは満足できるでしょう。スワイプを現在のタブ専用にして、タブ間を移動するのには使用しないでください。

次の画像は、現在の動作を示しています。右のイメージは、右にスワイプするとどうなるかを示しています。あなたが見ることができるように、左のタブが現れ始める。右のタブにのみスワイプを適用して、左のタブが表示されないように画像をスワイプすることができます。

enter image description here

私はViewPager内スワイプ制御するためのソリューションを参照してくださいが、タブ付きフラグメント間をスワイプ制御するための解決策を見つけるためには至っていません。ここ

はGridViewの断片とViewPagerフラグメントのXMLである:ここ

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
       android:layout_width="fill_parent" 
       android:layout_height="fill_parent" 
       android:orientation="vertical"> 
    <FrameLayout android:id="@android:id/tabcontent" 
       android:layout_width="fill_parent" 
       android:layout_height="fill_parent"> 
    <GridView xmlns:android="http://schemas.android.com/apk/res/android" 
       android:id="@+id/gridview" 
       android:layout_width="fill_parent" 
       android:layout_height="fill_parent" 
       android:columnWidth="100dip" 
       android:gravity="center" 
       android:horizontalSpacing="4dip" 
       android:numColumns="auto_fit" 
       android:stretchMode="columnWidth" 
       android:verticalSpacing="4dip" /> 
    </FrameLayout> 
</LinearLayout> 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
       android:layout_width="fill_parent" 
       android:layout_height="fill_parent" 
       android:orientation="vertical"> 

    <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android" 
            android:id="@+id/pager" 
            android:layout_width="fill_parent" 
            android:layout_height="0px" 
            android:layout_weight="1"/> 
</LinearLayout> 

ViewPager断片のコード要約:

public class FragmentFlash extends SherlockFragment { 

    private GestureDetector gestureDetector; 
    View.OnTouchListener gestureListener; 
    private ViewPager pager = null; 
    private int pagerPosition; 

    @Override 
     public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     pagerPosition = 0; 
     // Gesture detection 
     gestureDetector = new GestureDetector(new MyGestureDetector()); 
     gestureListener = new View.OnTouchListener() { 
      public boolean onTouch(View v, MotionEvent event) { 
       return gestureDetector.onTouchEvent(event); 
      } 
     }; 
     } 

    @Override 
     public View onCreateView(LayoutInflater inflater, ViewGroup container, 
           Bundle savedInstanceState) { 
     View v = inflater.inflate(R.layout.flash, container, false); 
     pager = (ViewPager) v.findViewById(R.id.pager); 
     pager.setOnTouchListener(gestureListener); 
     return v; 
    } 

    class MyGestureDetector extends SimpleOnGestureListener { 
     private static final int SWIPE_MIN_DISTANCE = 10; 
     private static final int SWIPE_MAX_OFF_PATH = 250; 
     private static final int SWIPE_THRESHOLD_VELOCITY = 50; 

     @Override 
     public boolean onDown(MotionEvent e) { 
     return true;//false; make onFling work with fragments 
     } 

     @Override 
     public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { 
     try { 
      if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH) 
       return false; 
      else 
       // right to left swipe 
       if(distanceX > SWIPE_MIN_DISTANCE) { 
        if (pagerPosition < imageUrls.length-1) 
        pager.setCurrentItem(++pagerPosition); 
       // left to right swipe 
       } else if (distanceX < -SWIPE_MIN_DISTANCE) { 
        if (pagerPosition > 0) 
        pager.setCurrentItem(--pagerPosition); 
       } 
      return true; 
     } catch (Exception e) { 
      // nothing 
     } 
     return false; 
     } 
    } 

    private class ImagePagerAdapter extends PagerAdapter { 

     private String[] images; 
     private LayoutInflater inflater; 

     ImagePagerAdapter(String[] images) { 
     this.images = images; 
     inflater = mContext.getLayoutInflater(); 
     } 

     @Override 
     public void destroyItem(View container, int position, Object object) { 
     ((ViewPager) container).removeView((View) object); 
     } 

     @Override 
     public void finishUpdate(View container) { 
     } 

     @Override 
     public int getCount() { 
     return images.length; 
     } 

     @Override 
     public Object instantiateItem(View view, int position) { 
     final View imageLayout = inflater.inflate(R.layout.item_pager_image, null); 
     final ImageView imageView = (ImageView) imageLayout.findViewById(R.id.image); 
     final ProgressBar spinner = (ProgressBar) imageLayout.findViewById(R.id.loading); 

     byte[] image = ;//get byte array from file at images[position]; 
     if (null != image) { 
      Bitmap bitmap = BitmapFactory.decodeByteArray(image, 0, image.length); 
      imageView.setImageBitmap(bitmap); 
     } 
     ((ViewPager) view).addView(imageLayout, 0); 

     return imageLayout; 
     } 

     @Override 
     public boolean isViewFromObject(View view, Object object) { 
     return view.equals(object); 
     } 

     @Override 
     public void restoreState(Parcelable state, ClassLoader loader) { 
     } 

     @Override 
     public Parcelable saveState() { 
     return null; 
     } 

     @Override 
     public void startUpdate(View container) { 
     } 
    } 

    public void pagerPositionSet(int pagerPosition, String[] imageUrls) { 
     Log.i(Flashum.LOG_TAG, "FragmentFlash pagerPositionSet: " + pagerPosition); 
     if (pagerPosition >= 0) 
     this.pagerPosition = pagerPosition; 
     if (pager != null) { 
     pager.setAdapter(new ImagePagerAdapter(imageUrls)); 
     pager.setCurrentItem(this.pagerPosition); 
     } 
    } 

} 

これはitem_pager_image.xmlある:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:padding="1dip" > 

    <ImageView 
     android:id="@+id/image" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center" 
     android:adjustViewBounds="true" 
     android:contentDescription="@string/descr_image" /> 

    <ProgressBar 
     android:id="@+id/loading" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center" 
     android:visibility="gone" /> 

</FrameLayout> 

答えて

17

[OK]を、私は最終的にこれを考え出しました。 Laurence Dawsonは正しかったですが、そのフラグメントにCustomViewPagerを適用する代わりに、FragmentActivityに適用する必要があります。アクティビティによって管理されるタブ間の切り替えは、ViewPagerアダプタでもあります。このように、活動のためのXMLは

<TabHost 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@android:id/tabhost" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <LinearLayout 
     android:orientation="vertical" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 

     <TabWidget 
      android:id="@android:id/tabs" 
      android:orientation="horizontal" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_weight="0"/> 

     <FrameLayout 
      android:id="@android:id/tabcontent" 
      android:layout_width="0dp" 
      android:layout_height="0dp" 
      android:layout_weight="0"/> 

     <com.Flashum.CustomViewPager 
      android:id="@+id/pager" 
      android:layout_width="match_parent" 
      android:layout_height="0dp" 
      android:layout_weight="1"/> 

    </LinearLayout> 
</TabHost> 

され、カスタムViewPagerは、コンストラクタは、それがfalseを返すようにonInterceptTouchEventを引き起こすことが可能であることをことを除い示唆しているよう。これにより、フラグメントアクティビティがスワイプに作用してフラグメントに専念できるようになりません!

public class CustomViewPager extends ViewPager { 

    private boolean enabled; 

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

    @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; 
    } 
} 
+0

"の代わりに、FragmentActivityに適用する必要があるフラグメントにCustomViewPagerを適用します。私はあなたが断片にこれを適用する必要があると述べておらず、私が提供したリンクもそうではありません。あなたの答えは提供されたリンクからコードをコピーするだけで、onInterceptTouchEventを無効にしてスワイプを無効にする方法を既に完全に説明しています。 – Ljdawson

9

ViewPagerのonInterceptTouchEventメソッドをオーバーライドする必要があります。あなたが拡張ViewPagerでこれを行うか、これを追加するには素晴らしいチュートリアルのこのリンクを訪問することができます:

http://blog.svpino.com/2011/08/disabling-pagingswiping-on-android.html

+1

私はこのコードを試しましたが、これはViewPagerフラグメント内のスワイプを制御するためだけのものであることがわかりました。これは、FragmentActivityがタブ間でスワイプするのを妨げません。言い換えると、私が右にスワイプすると、MyGestureDetector :: onScroll()が呼び出されるだけでなく、左のタブが左側に表示され始め、FragmentActivityもスワイプを検出し処理していることを示します。 – cdavidyoung

+0

なぜジェスチャー検出器を持っているのか分かりませんが、ViewPagerがすべてのスワイプを処理します – Ljdawson

+0

スワイプの感度を調整できるように、これを行いました。今では非常に小さなスワイプで、私は正しいタブの中にとどまることができます。ただし、通常のスワイプでは、FragmentActivityがそれを検出して引き継ぎます。ところで、私は自分のジェスチャー検出器を無効にしようとしましたが、あなたが参照したカスタムViewPagerでさえそれは助けにはなりません。 – cdavidyoung

関連する問題