Deshabilitar el desplazamiento entre las pestañas en FragmentActivity

Tengo una (Sherlock) FragmentActivity con 2 fragmentos con pestañas. El fragmento de la izquierda es un GridView que muestra las imágenes de un álbum y el fragmento de la derecha consiste en un ViewPager que se utiliza para ver las imágenes individuales. Desde el fragmento izquierdo puede desplazarse por las imágenes y seleccionar una. Tabbing (o deslizamiento) sobre el fragmento de la derecha mostrará la imagen y porque es un ViewPager puede pasar a la imagen anterior o siguiente.

Esto funciona muy bien, excepto que la FragmentActivity quiere interceptar el desplazamiento a la derecha y volver a la pestaña izquierda. Me gustaría evitar que la FragmentActivity intercepte los swipes cuando estoy en la pestaña derecha. Si tuviera que desactivar el deslizamiento entre pestañas por completo sería satisfactorio. Sólo quiero que el swiping se dedique a la pestaña actual y no se utilice para moverse entre pestañas.

Las siguientes imágenes indican el comportamiento actual. La imagen de la derecha muestra lo que sucede cuando hago un golpe a la derecha. Como puede ver, la pestaña izquierda empieza a aparecer. Quiero que el golpe en lugar de aplicar a la pestaña derecha sólo para que pueda pasar entre las imágenes sin la pestaña izquierda que aparece.

Introduzca aquí la descripción de la imagen

Veo soluciones para controlar swiping dentro de un ViewPager pero aún no he encontrado una solución para controlar el deslizamiento entre fragmentos con fichas.

Aquí está el xml para el fragmento GridView y el fragmento ViewPager:

<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> 

Aquí un resumen de código del fragmento 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); } } } 

Este es el 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> 

Ok, finalmente me di cuenta de esto. Laurence Dawson estaba en el camino correcto, pero en lugar de aplicar el CustomViewPager al fragmento necesita ser aplicado a la FragmentActivity. Usted ve, el cambio entre las pestañas, que es administrado por la actividad, es también un adaptador de ViewPager. Por lo tanto, xml para la actividad es

 <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> 

Y el ViewPager personalizado es como se sugiere, excepto que el constructor le permite causar onInterceptTouchEvent devolver false. ¡Esto evita que la FragmentActivity actúe sobre el swipe para que pueda ser dedicada al fragmento!

 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; } } 

Necesita anular el método onInterceptTouchEvent para su ViewPager, puede hacerlo ampliando ViewPager o visite este enlace para obtener un gran tutorial sobre cómo añadir esto:

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

  • ViewPager no carga correctamente la página central
  • El paquete de compatibilidad de Android no incluye Activity.getFragmentManager ()
  • Viewpageindicator dentro del fragmento
  • Ver saltos y parpadea al instante, aunque animateLayoutChanges = "true"
  • FragmentManager reemplazar fragmentos sin llamar onPause () onDestroy () para el fragmento antiguo
  • Recarga de WebView cuando Fragmento en ViewPager se retiene desde BackStack
  • Cambiar el icono del menú de opciones en la barra de acciones dependiendo de un fragmento abierto
  • No se muestran los elementos de acción del fragmento inicial de Viewpager
  • Comunicación entre Fragmentos
  • Pasar datos entre fragmentos
  • El método getView () de ArrayAdapter no se recibe
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.