我有一个自定义ViewSwitcher
我在其中实现了触摸事件
能够使用触摸屏滚动屏幕。
我的布局层次结构如下所示:
<ViewSwitcher>
<LinearLayout>
<ListView />
</LinearLayout>
<LinearLayout>
<ListView />
</LinearLayout>
</ViewSwitcher>
现在,问题是触摸事件正被消耗
ListViews
我无法切换视图。我工作时效果很好
没有ListViews
。我需要能够滚动浏览
查看并滚动ListView
。
我该如何解决这个问题?
编辑:我还需要ListView
项可点击。
提前致谢!
答案 0 :(得分:79)
谢谢大家回答这个问题。但我能够以更简单的方式解决这个问题。由于我的ViewSwitcher
未检测到触摸事件,因此我拦截了触摸事件,称为onTouchEvent()
并返回false
。这里:
@Override
public boolean onInterceptTouchEvent(MotionEvent ev)
{
onTouchEvent(ev);
return false;
}
通过覆盖onInterceptTouchEvent()
,我能够拦截活动中的触摸事件。然后我调用onTouchEvent()
中的ViewSwitcher
来处理ListViews
的切换。最后返回false
,确保ViewGroup
不会消耗该事件。
答案 1 :(得分:8)
将子视图Touch事件传递给父视图的最简单方法是将其添加到子视图:
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
return false;
}
答案 2 :(得分:1)
我认为没有一种简单的方法可以做到这一点。
这并不复杂,但您需要创建自己的视图来扩展ListView。然后,您可以覆盖onTouch
处理程序并决定(取决于触摸事件)是否要处理它(并返回true)或将其传递给父视图。
问题还在于,一旦View处理触摸事件,它就会获得所有剩余的事件......
onTouch() - 返回一个布尔值 表明你的听众 消耗这个事件。重要的 事情是这个事件可以有 每个后面的多个动作 其他。所以,如果你在什么时候返回false 收到了下行动作,你 表明你没有消耗 这个事件并没有兴趣 在此事件的后续行动中。 因此,你不会被要求任何 事件中的其他行为,例如 作为手指手势,或最终 举动活动
因此,例如,如果您想要垂直移动以滚动列表并在同一触摸事件期间(不抬起手指),您需要水平移动来切换视图,这将是非常具有挑战性的。 / p>
但是,如果您可以使用手势或处理自定义视图中的所有内容,并根据MotionEvent的内容,将命令发送到ViewSwitcher。
答案 3 :(得分:1)
在我的父布局中,我发现阻止孩子捕获触摸事件的唯一方法是重写onInterceptTouchEvent以返回true。
@Override
public boolean onInterceptTouchEvent(MotionEvent ev)
{
return true;
}
答案 4 :(得分:0)
您是否尝试将ListView项设置为不可点击,如下所示:listView.setClickable(false);这应该向上传播click事件。
答案 5 :(得分:0)
如果您的视图想要传递事件,请确保在onTouchEvent中返回false。否则,平台认为您使用了该事件,无需进一步处理。
答案 6 :(得分:0)
我所做的是在viewswitcher中的listview上设置toucheventlistener,处理事件,检测fling动作并调用viewswitcher的metchod。它有效。
答案 7 :(得分:0)
您还可以插入一个电话来处理touchevent
中的dispatchTouchEvent
,但在这种情况下,您还必须覆盖onTouchEvent
以返回true,否则只返回第一个MotionEvent
} DOWN手势将被传递。
这是可触摸的包装容器:
<?xml version="1.0" encoding="utf-8"?>
<view xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.example.myapp.FragmentContainer$TouchableWrapper" />
上课:
public static class TouchableWrapper extends FrameLayout {
private GestureDetector gestureDetector;
public void setGestureDetector(GestureDetector gestureDetector) {
this.gestureDetector = gestureDetector;
}
// these constructors for the XML inflater
public TouchableWrapper(Context context) {
super(context);
}
public TouchableWrapper(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TouchableWrapper(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
Log.d(TAG, "onInterceptTouchEvent " + event.toString());
return false; // true for intercept, false è default and pass on to children View
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
Log.d(TAG, "dispatchTouchEvent " + event.toString());
gestureDetector.onTouchEvent(event);
return super.dispatchTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.d(TAG, "onTouchEvent " + event.toString());
return true; //return super.onTouchEvent(event);
}
}
这是GestureDetector
参考:
private GestureDetector gestureDetector;
这是GestureListener
:
private GestureDetector.SimpleOnGestureListener sOGL = new GestureDetector.SimpleOnGestureListener() {
private static final int SWIPE_THRESHOLD = 100;
private static final int SWIPE_VELOCITY_THRESHOLD = 100;
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
boolean result = false;
try {
float diffY = e2.getY() - e1.getY();
float diffX = e2.getX() - e1.getX();
if (Math.abs(diffX) > Math.abs(diffY)) {
if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
if (diffX > 0) {
goToRight(); // onSwipeRight();
} else {
goToLeft(); // onSwipeLeft();
}
}
result = true;
} else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
if (diffY > 0) {
// onSwipeBottom();
} else {
// onSwipeTop();
}
}
result = true;
} catch (Exception exception) {
exception.printStackTrace();
}
return result; // return false indicate event not handled
}
};
使用Ant来加载可触摸的容器片段和包含的片段:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d(TAG, "onCreateView()");
View view = inflater.inflate(R.layout.fragmentcontainer, container, false);
gestureDetector = new GestureDetector(view.getContext(), sOGL);
((FragmentContainer.TouchableWrapper) view).setGestureDetector(gestureDetector);
FragmentManager fm = this.getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.pager, frag).commit();
return view;
}
答案 8 :(得分:0)
必须使用autoLink =“three”在父视图中处理TextView中的触摸 这样做了:
private LinearLayout mParentView;
private TextView mTextView;
private View.OnTouchListener mParentListener = new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
......
return false;
}
};
mParentView.setOnTouchListener(mParentListener);
mTextView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
mParentListener.onTouch(mParentView, event);
return false;
}
};