Tengo un ScrollView que rodea todo mi diseño para que toda la pantalla se pueda desplazar. El primer elemento que tengo en este ScrollView es un bloque HorizontalScrollView que tiene características que se pueden desplazar horizontalmente. Agregué un ontouchlistener a la vista de desplazamiento horizontal para manejar eventos táctiles y forzar la vista a "ajustar" a la imagen más cercana en el evento ACTION_UP.
Entonces, el efecto que busco es como la pantalla de inicio de Android en la que puedes desplazarte de una a otra y se ajusta a una pantalla cuando levantas el dedo.
Todo esto funciona muy bien, excepto por un problema: necesito deslizar de izquierda a derecha casi perfectamente horizontalmente para que un ACTION_UP se registre. Si al menos deslizo verticalmente (lo que creo que muchas personas tienden a hacer en sus teléfonos cuando deslizan de lado a lado), recibiré un ACTION_CANCEL en lugar de un ACTION_UP. Mi teoría es que esto se debe a que la vista de desplazamiento horizontal está dentro de una vista de desplazamiento, y la vista de desplazamiento está secuestrando el toque vertical para permitir el desplazamiento vertical.
¿Cómo puedo deshabilitar los eventos táctiles para la vista de desplazamiento desde mi vista de desplazamiento horizontal, pero aún permitir el desplazamiento vertical normal en otra parte de la vista de desplazamiento?
Aquí hay una muestra de mi código:
public class HomeFeatureLayout extends HorizontalScrollView {
private ArrayList<ListItem> items = null;
private GestureDetector gestureDetector;
View.OnTouchListener gestureListener;
private static final int SWIPE_MIN_DISTANCE = 5;
private static final int SWIPE_THRESHOLD_VELOCITY = 300;
private int activeFeature = 0;
public HomeFeatureLayout(Context context, ArrayList<ListItem> items){
super(context);
setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
setFadingEdgeLength(0);
this.setHorizontalScrollBarEnabled(false);
this.setVerticalScrollBarEnabled(false);
LinearLayout internalWrapper = new LinearLayout(context);
internalWrapper.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
internalWrapper.setOrientation(LinearLayout.HORIZONTAL);
addView(internalWrapper);
this.items = items;
for(int i = 0; i< items.size();i++){
LinearLayout featureLayout = (LinearLayout) View.inflate(this.getContext(),R.layout.homefeature,null);
TextView header = (TextView) featureLayout.findViewById(R.id.featureheader);
ImageView image = (ImageView) featureLayout.findViewById(R.id.featureimage);
TextView title = (TextView) featureLayout.findViewById(R.id.featuretitle);
title.setTag(items.get(i).GetLinkURL());
TextView date = (TextView) featureLayout.findViewById(R.id.featuredate);
header.setText("FEATURED");
Image cachedImage = new Image(this.getContext(), items.get(i).GetImageURL());
image.setImageDrawable(cachedImage.getImage());
title.setText(items.get(i).GetTitle());
date.setText(items.get(i).GetDate());
internalWrapper.addView(featureLayout);
}
gestureDetector = new GestureDetector(new MyGestureDetector());
setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (gestureDetector.onTouchEvent(event)) {
return true;
}
else if(event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL ){
int scrollX = getScrollX();
int featureWidth = getMeasuredWidth();
activeFeature = ((scrollX + (featureWidth/2))/featureWidth);
int scrollTo = activeFeature*featureWidth;
smoothScrollTo(scrollTo, 0);
return true;
}
else{
return false;
}
}
});
}
class MyGestureDetector extends SimpleOnGestureListener {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
try {
//right to left
if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
activeFeature = (activeFeature < (items.size() - 1))? activeFeature + 1:items.size() -1;
smoothScrollTo(activeFeature*getMeasuredWidth(), 0);
return true;
}
//left to right
else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
activeFeature = (activeFeature > 0)? activeFeature - 1:0;
smoothScrollTo(activeFeature*getMeasuredWidth(), 0);
return true;
}
} catch (Exception e) {
// nothing
}
return false;
}
}
}
HomeFeatureLayout extends HorizontalScrollView
) aquí velir.com/blog/index.php/2010/11/17/… Hay algunos comentarios adicionales sobre lo que está sucediendo a medida que se compone la clase de desplazamiento personalizada.
MeetMe's HorizontalListView
biblioteca