我想在HorizontalScrollView
中实现Snapping effect,即当用户水平滚动时,最明显的项目(项目可见> 50%)到达中心。
我尝试使用
执行此操作 hsv.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
@Override
public void onScrollChanged() {
int scrollX = hsv.getScrollX(); // For HorizontalScrollView
Log.e("scrollX",String.valueOf(scrollX));
// DO SOMETHING WITH THE SCROLL COORDINATES
}
});
但即使我们不触摸屏幕,该值也不会保持不变。
以下是logcat的一部分:
03-28 11:11:22.116 26639-26639/package_name E/scrollX: 0
03-28 11:11:22.133 26639-26639/package_name E/scrollX: 792
03-28 11:11:22.133 26639-26639/package_name E/scrollX: 0
03-28 11:11:22.151 26639-26639/package_name E/scrollX: 795
03-28 11:11:22.151 26639-26639/package_name E/scrollX: 0
03-28 11:11:22.166 26639-26639/package_name E/scrollX: 799
03-28 11:11:22.166 26639-26639/package_name E/scrollX: 0
03-28 11:11:22.183 26639-26639/package_name E/scrollX: 801
03-28 11:11:22.183 26639-26639/package_name E/scrollX: 0
03-28 11:11:22.199 26639-26639/package_name E/scrollX: 803
03-28 11:11:22.199 26639-26639/package_name E/scrollX: 0
03-28 11:11:22.216 26639-26639/package_name E/scrollX: 804
03-28 11:11:22.216 26639-26639/package_name E/scrollX: 0
03-28 11:11:22.233 26639-26639/package_name E/scrollX: 805
03-28 11:11:22.233 26639-26639/package_name E/scrollX: 0
03-28 11:11:22.249 26639-26639/package_name E/scrollX: 806
03-28 11:11:22.249 26639-26639/package_name E/scrollX: 0
现在我已经尝试过这些解决方案,I am not getting the point
或I don't know to do it
。请帮忙。
我的用例:
我有一个HorizontalScrollView
附加到Recyclerview(垂直)的适配器,所以snapHelper
可以垂直完成,但我不知道如何使它成为水平。
答案 0 :(得分:2)
Here是自定义水平滚动视图的完整代码,用于捕捉项目。
public class HomeFeatureLayout extends HorizontalScrollView {
private static final int SWIPE_MIN_DISTANCE = 5;
private static final int SWIPE_THRESHOLD_VELOCITY = 300;
private ArrayList mItems = null;
private GestureDetector mGestureDetector;
private int mActiveFeature = 0;
public HomeFeatureLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public HomeFeatureLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public HomeFeatureLayout(Context context) {
super(context);
}
public void setFeatureItems(ArrayList items){
LinearLayout internalWrapper = new LinearLayout(getContext());
internalWrapper.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
internalWrapper.setOrientation(LinearLayout.HORIZONTAL);
addView(internalWrapper);
this.mItems = items;
for(int i = 0; i< items.size();i++){
LinearLayout featureLayout = (LinearLayout) View.inflate(this.getContext(),R.layout.homefeature,null);
//...
//Create the view for each screen in the scroll view
//...
internalWrapper.addView(featureLayout);
}
setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
//If the user swipes
if (mGestureDetector.onTouchEvent(event)) {
return true;
}
else if(event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL ){
int scrollX = getScrollX();
int featureWidth = v.getMeasuredWidth();
mActiveFeature = ((scrollX + (featureWidth/2))/featureWidth);
int scrollTo = mActiveFeature*featureWidth;
smoothScrollTo(scrollTo, 0);
return true;
}
else{
return false;
}
}
});
mGestureDetector = new GestureDetector(new MyGestureDetector());
}
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) {
int featureWidth = getMeasuredWidth();
mActiveFeature = (mActiveFeature < (mItems.size() - 1))? mActiveFeature + 1:mItems.size() -1;
smoothScrollTo(mActiveFeature*featureWidth, 0);
return true;
}
//left to right
else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
int featureWidth = getMeasuredWidth();
mActiveFeature = (mActiveFeature > 0)? mActiveFeature - 1:0;
smoothScrollTo(mActiveFeature*featureWidth, 0);
return true;
}
} catch (Exception e) {
Log.e("Fling", "There was an error processing the Fling event:" + e.getMessage());
}
return false;
}
}
}
此示例以编程方式添加视图并将其称为Features
。但您可以简单地更改该行为并使用getChildrenCount()
代替mItems.size()
等等。
重要的部分是GestureDetector
和TouchListener
。在TouchListener中,您可以收听用户手指被移除时的ACTION_UP
(如滚动后),并根据滚动量及其值计算哪个视图为active
位置。你也可以添加一个GestureDetector来捕捉fling操作并在那里做同样的事情。