전체 화면을 스크롤 할 수 있도록 전체 레이아웃을 둘러싼 ScrollView가 있습니다. 이 ScrollView에있는 첫 번째 요소는 가로로 스크롤 할 수있는 기능이있는 HorizontalScrollView 블록입니다. 터치 이벤트를 처리하고보기가 ACTION_UP 이벤트에서 가장 가까운 이미지에 "스냅"되도록 ontouchlistener를 horizontalscrollview에 추가했습니다.
그래서 내가 가고있는 효과는 주식 안드로이드 홈 화면과 같습니다. 여기서 한 화면에서 다른 화면으로 스크롤 할 수 있으며 손가락을 들어 올리면 한 화면에 스냅됩니다.
이것은 하나의 문제를 제외하고는 모두 잘 작동합니다 .ACTION_UP이 등록되도록 왼쪽에서 오른쪽으로 거의 완벽하게 가로로 스 와이프해야합니다. 내가 세로로 스 와이프하면 (많은 사람들이 좌우로 스 와이프 할 때 휴대 전화에서하는 경향이 있다고 생각합니다), ACTION_UP 대신 ACTION_CANCEL을받습니다. 내 이론은 가로 스크롤보기가 스크롤보기 내에 있고 스크롤보기가 세로 스크롤을 허용하기 위해 세로 터치를 가로 채고 있기 때문입니다.
가로 스크롤보기 내에서 스크롤보기의 터치 이벤트를 비활성화하고 스크롤보기의 다른 곳에서 일반 세로 스크롤을 허용하는 방법은 무엇입니까?
내 코드 샘플은 다음과 같습니다.
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
있습니다 ... 사용자 정의 스크롤 클래스가 구성 될 때 무슨 일이 일어나고 있는지에 대한 추가 의견이 있습니다.
MeetMe's HorizontalListView
도서관을 사용하고 있습니다.