Ich habe eine ScrollView, die mein gesamtes Layout umgibt, sodass der gesamte Bildschirm scrollbar ist. Das erste Element in dieser ScrollView ist ein HorizontalScrollView-Block mit Funktionen, durch die horizontal gescrollt werden kann. Ich habe der horizontalen Bildlaufansicht einen Ontouchlistener hinzugefügt, um Berührungsereignisse zu verarbeiten und die Ansicht zu zwingen, am nächsten Bild des ACTION_UP-Ereignisses zu "fangen".
Der Effekt, den ich anstrebe, ist also wie der Standard-Android-Homescreen, auf dem Sie von einem zum anderen scrollen können und der auf einem Bildschirm einrastet, wenn Sie Ihren Finger heben.
Dies alles funktioniert bis auf ein Problem hervorragend: Ich muss fast perfekt horizontal von links nach rechts wischen, damit sich ein ACTION_UP jemals registriert. Wenn ich im geringsten vertikal wische (was meiner Meinung nach viele Leute auf ihren Handys tun, wenn sie von einer Seite zur anderen wischen), erhalte ich eine ACTION_CANCEL anstelle einer ACTION_UP. Meine Theorie ist, dass dies daran liegt, dass sich die horizontale Bildlaufansicht innerhalb einer Bildlaufansicht befindet und die Bildlaufansicht die vertikale Berührung entführt, um ein vertikales Bildlauf zu ermöglichen.
Wie kann ich die Berührungsereignisse für die Bildlaufansicht nur in meiner horizontalen Bildlaufansicht deaktivieren und trotzdem das normale vertikale Bildlauf an anderer Stelle in der Bildlaufansicht zulassen?
Hier ist ein Beispiel meines Codes:
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
) hier velir.com/blog/index.php/2010/11/17/… Es gibt einige zusätzliche Kommentare dazu, was passiert , wenn die benutzerdefinierte Bildlaufklasse zusammengesetzt wird.
MeetMe's HorizontalListView
Bibliothek.