deshabilitar deslizar entre pestañas en FragmentActivity
Tengo un (Sherlock) FragmentActivity con 2 fragmentos con pestañas. El fragmento de la izquierda es un GridView que muestra imágenes de un álbum y el fragmento de la derecha consiste en un ViewPager que se usa para ver imágenes individuales. Desde el fragmento izquierdo puede desplazarse por las imágenes y seleccionar una. Al tabular (o deslizar) hacia el fragmento de la derecha, se mostrará la imagen y, dado que se trata de un ViewPager, puede pasar a la imagen anterior o siguiente.
Esto funciona muy bien, excepto que FragmentActivity quiere interceptar el golpe derecho y volver a la pestaña izquierda. Me gustaría evitar que FragmentActivity intercepte los swipes cuando estoy en la pestaña derecha. Si tuviera que deshabilitar el deslizamiento entre las pestañas por completo sería satisfactorio. Solo quiero que el deslizar se dedique a la pestaña actual y que no se use 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 movimiento hacia la derecha. Como puedes ver, la pestaña izquierda comienza a aparecer. Quiero que el deslizamiento se aplique a la pestaña derecha solo para que pueda deslizar entre las imágenes sin que aparezca la pestaña izquierda.
Veo soluciones para controlar el deslizamiento dentro de un ViewPager pero todavía tengo que encontrar una solución para controlar el deslizamiento entre fragmentos con pestañas.
Aquí está el xml para el fragmento de GridView y el fragmento de 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>