Sim*_*mon 5 android touch-event android-layout motionevent android-recyclerview
这似乎是android中相当普遍的模式.我正在尝试创建类似Facebook显示广告的方式:
您可以看到它们具有外部垂直回收视图,内部水平回收视图作为外部垂直recyclerview适配器中的项目之一.
我按照Google的指南"在ViewGroup中管理触摸事件" - http://developer.android.com/training/gestures/viewgroup.html,因为Recyclerview扩展了ViewGroup,其代码类似于我想要做的.
我对它进行了一些定制,以便检测Y轴的移动而不是X轴的移动,并将其应用到外部垂直再循环视图.
/**
* Created by Simon on 10/11/2015.
*///This is the recyclerview that would allow all vertical scrolls
public class VerticallyScrollRecyclerView extends RecyclerView {
public VerticallyScrollRecyclerView(Context context) {
super(context);
}
public VerticallyScrollRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public VerticallyScrollRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
ViewConfiguration vc = ViewConfiguration.get(this.getContext());
private int mTouchSlop = vc.getScaledTouchSlop();
private boolean mIsScrolling;
private float startY;
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = MotionEventCompat.getActionMasked(ev);
// Always handle the case of the touch gesture being complete.
if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
// Release the scroll.
mIsScrolling = false;
startY = ev.getY();
return false; // Do not intercept touch event, let the child handle it
}
switch (action) {
case MotionEvent.ACTION_MOVE: {
if (mIsScrolling) {
// We're currently scrolling, so yes, intercept the
// touch event!
return true;
}
// If the user has dragged her finger horizontally more than
// the touch slop, start the scroll
// left as an exercise for the reader
final float yDiff = calculateDistanceY(ev.getY());
Log.e("yDiff ", ""+yDiff);
// Touch slop should be calculated using ViewConfiguration
// constants.
if (yDiff > mTouchSlop) {
// Start scrolling!
Log.e("Scroll", "we are scrolling vertically");
mIsScrolling = true;
return true;
}
break;
}
}
return false;
}
private float calculateDistanceY(float endY) {
return startY - endY;
}
}
Run Code Online (Sandbox Code Playgroud)
我的xml布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/main_recyclerview_holder">
<com.example.simon.customshapes.VerticallyScrollRecyclerView
android:id="@+id/main_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)
当我尝试拖动内部水平回收视图时(希望touchevent被外部垂直回收视图拦截),外部回收视图根本不会垂直滚动.
它也给我一个错误说:
处理滚动时出错; 未找到id -1的指针索引.是否跳过任何MotionEvents?
有谁知道如何正常工作?
小智 1
我也遇到了类似的问题,网上也没有找到解决办法。在我的应用程序中,我有自定义交互元素列表,您可以通过水平滑动进行交互(在这种情况下滚动应该被锁定),但是当您垂直滑动时它应该滚动。根据您的评论,您已经解决了您的问题,但是对于那些问题与我相似并且其研究引导他们来到这里的人,我将发布我的解决方案。我仔细研究了一下RecyclerView,这就是我发现的。“处理滚动时出错;未找到 id -1 的指针索引。是否跳过了任何 MotionEvent?” - 问题是mScrollPointerId用于 get 的变量是在发生时index设置的。在我的特殊情况下,当发生时我从返回,因为在那一刻我不知道天气用户想要滚动或与列表元素交互。在这种情况下不会被调用。后来,当我发现用户想要与元素交互时,我从and被调用返回 false,但它无法处理滚动,因为未设置。这里的解决方案只是在发生时调用。onTouchEventACTION_DOWNACTION_DOWNfalseonInterceptTouchEventonTouchEventonInterceptTouchEventonTouchEventmScrollPointerIdonTouchEventonInterceptTouchEventACTION_DOWN
@Override
public boolean onInterceptTouchEvent(MotionEvent e) {
...
switch (action) {
case MotionEvent.ACTION_DOWN: {
onTouchEvent(e);
...
break;
}
...
}
...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2777 次 |
| 最近记录: |