Tôi có một ScrollView bao quanh toàn bộ bố cục của mình để toàn bộ màn hình có thể cuộn được. Phần tử đầu tiên tôi có trong ScrollView này là một khối ngangScrollView có các tính năng có thể cuộn qua chiều ngang. Tôi đã thêm một ontouchlistener vào heftalscrollview để xử lý các sự kiện chạm và buộc chế độ xem "chụp" vào hình ảnh gần nhất trong sự kiện ACTION_UP.
Vì vậy, hiệu ứng tôi sẽ làm giống như màn hình chính của android, nơi bạn có thể cuộn từ màn hình này sang màn hình khác và nó chạm vào một màn hình khi bạn nhấc ngón tay lên.
Tất cả điều này hoạt động tuyệt vời ngoại trừ một vấn đề: Tôi cần vuốt từ trái sang phải gần như hoàn toàn theo chiều ngang để ACTION_UP được đăng ký. Nếu tôi vuốt theo chiều dọc ở mức tối thiểu (mà tôi nghĩ nhiều người có xu hướng làm trên điện thoại của họ khi vuốt sang bên), tôi sẽ nhận được ACTION_CANCEL thay vì ACTION_UP. Lý thuyết của tôi là điều này là do heftalscrollview nằm trong một scrollview và scrollview đang chiếm quyền điều khiển theo chiều dọc để cho phép cuộn dọc.
Làm cách nào tôi có thể vô hiệu hóa các sự kiện cảm ứng cho cuộn xem từ ngay trong cuộn xem ngang của mình, nhưng vẫn cho phép cuộn dọc bình thường ở nơi khác trong cuộn xem?
Đây là một mẫu mã của tôi:
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
) ở đây velir.com/blog/index.php/2010/11/17/NH Có một số nhận xét bổ sung về những gì đang diễn ra khi lớp cuộn tùy chỉnh được tạo.
MeetMe's HorizontalListView
thư viện.