Saya memiliki ScrollView yang mengelilingi seluruh tata letak saya sehingga seluruh layar dapat digulir. Elemen pertama yang saya miliki dalam ScrollView ini adalah blok HorizontalScrollView yang memiliki fitur yang dapat digulir secara horizontal. Saya telah menambahkan daftar ontouchlist ke horizontalscrollview untuk menangani acara sentuh dan memaksa tampilan untuk "snap" ke gambar terdekat di acara ACTION_UP.
Jadi efek yang saya tuju adalah seperti homescreen android stok di mana Anda dapat menggulir dari satu ke yang lain dan terkunci ke satu layar ketika Anda mengangkat jari Anda.
Ini semua berfungsi dengan baik kecuali untuk satu masalah: Saya perlu menggesek dari kiri ke kanan hampir sempurna secara horizontal agar ACTION_UP pernah mendaftar. Jika saya menggesek paling tidak secara vertikal (yang saya pikir banyak orang cenderung lakukan di ponsel mereka ketika menggesek sisi ke sisi), saya akan menerima ACTION_CANCEL bukan ACTION_UP. Teori saya adalah ini karena horizontalscrollview berada dalam scrollview, dan scrollview membajak sentuhan vertikal untuk memungkinkan pengguliran vertikal.
Bagaimana saya bisa menonaktifkan acara sentuh untuk scrollview hanya dari dalam scrollview horizontal saya, tetapi masih memungkinkan untuk bergulir vertikal normal di tempat lain di scrollview?
Ini contoh kode saya:
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
) di sini velir.com/blog/index.php/2010/11/17/... Ada beberapa komentar tambahan tentang apa yang terjadi ketika kelas gulir khusus dibuat.
MeetMe's HorizontalListView
perpustakaan.