当多个指针在不同的视图上时,如何获得屏幕上的指针总数?我在屏幕上有多个视图,如果指针不在视图的相关区域,则视图将在false
ON_DOWN
的情况下返回onTouchEvent
。
当第一根手指在一个视图上,第二根手指触摸到另一个视图时,两个视图都将返回" 1"用于getPointerCount
方法。有没有办法在整个屏幕上获得总指针计数,无论哪个视图处理指针触摸?
修改 Views
不在同一个父ViewGroup
中,这就是onInterceptTouch
无法返回总指针数的原因。我可以将onInterceptTouch
放到非常根ViewGroup
,但是我希望Android能够提供指针的总计数而不需要像这样的一些肮脏的解决方法。
答案 0 :(得分:1)
没有直接的方法可以使用Activity
上调用的方法,而是使用@ S.D。指出,您可以使用onInterceptTouchEvent
的{{1}}来执行此操作:
<强> MyLinearLayout.java 强>
ViewGroup
<强> mylayout.xml 强>
public class MyLinearLayout extends LinearLayout {
public MyLinearLayout(Context context) {
super(context);
}
public MyLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(21)
public MyLinearLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public boolean onInterceptTouchEvent(final MotionEvent ev) {
Log.e("TOUCHES", "num: " + ev.getPointerCount());
return super.onInterceptTouchEvent(ev);
}
}
<强> MyActivity.java 强>
<mypackage.MyLinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/t1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.5"
android:clickable="true"
android:gravity="center"
android:text="0"/>
<TextView
android:id="@+id/t2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.5"
android:clickable="true"
android:gravity="center"
android:text="0"/>
</mypackage.MyLinearLayout>
此示例将使用每个public class MapsActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mylayout);
final TextView t1 = (TextView) findViewById(R.id.t1);
final TextView t2 = (TextView) findViewById(R.id.t2);
t1.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(final View view, final MotionEvent motionEvent) {
t1.setText(""+motionEvent.getPointerCount());
return true;
}
});
t2.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(final View view, final MotionEvent motionEvent) {
t2.setText(""+motionEvent.getPointerCount());
return true;
}
});
}
}
收到的TextView
的{{1}}设置t1和t2 getPointerCount()
的文本,并记录总值MotionEvent
TextView
getPointerCount()
答案 1 :(得分:1)
您需要一个自定义ViewGroup来拦截传下来的所有触摸事件。
您需要了解Android中的工作原理:
ViewGroup.onInterceptTouchEvent(MotionEvent)
允许ViewGroup在触及儿童之前拦截触摸事件。如果您在此处返回true
,则会在onTouchEvent()
中收到后续触摸事件,并且在当前事件结束(删除指针)之前,孩子将不再接收任何触摸事件ViewGroup.requestDisallowInterceptTouchEvent(boolean)
进行拦截:他们通常在识别正在进行的触摸事件时执行,并且他们不希望父级中断它。如果ViewGroup收到此请求,它必须将其传递给父级并尊重它(=不要从此处拦截事件)ViewGroup
在收到onInterceptTouchEvent
后不会致电requestDisallowInterceptTouchEvent(true)
如果您需要听取每个触摸事件,即使孩子们不允许拦截,您也需要欺骗ViewGroup
认为它没有被禁止但你仍然需要尊重禁止(避免拦截触摸事件)
这是我为我的一个项目编写的一个类,它正是这样做的:
public class InterceptTouchFrameLayout extends FrameLayout {
private boolean mDisallowIntercept;
public interface OnInterceptTouchEventListener {
/**
* If disallowIntercept is true the touch event can't be stealed and the return value is ignored.
* @see android.view.ViewGroup#onInterceptTouchEvent(android.view.MotionEvent)
*/
boolean onInterceptTouchEvent(InterceptTouchFrameLayout view, MotionEvent ev, boolean disallowIntercept);
/**
* @see android.view.View#onTouchEvent(android.view.MotionEvent)
*/
public boolean onTouchEvent(InterceptTouchFrameLayout view, MotionEvent event);
}
private static final class DummyInterceptTouchEventListener implements OnInterceptTouchEventListener {
@Override
public boolean onInterceptTouchEvent(InterceptTouchFrameLayout view, MotionEvent ev, boolean disallowIntercept) {
return false;
}
@Override
public boolean onTouchEvent(InterceptTouchFrameLayout view, MotionEvent event) {
return false;
}
}
private static final OnInterceptTouchEventListener DUMMY_LISTENER = new DummyInterceptTouchEventListener();
private OnInterceptTouchEventListener mInterceptTouchEventListener = DUMMY_LISTENER;
public InterceptTouchFrameLayout(Context context) {
super(context);
}
public InterceptTouchFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public InterceptTouchFrameLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
getParent().requestDisallowInterceptTouchEvent(disallowIntercept);
mDisallowIntercept = disallowIntercept;
}
public void setOnInterceptTouchEventListener(OnInterceptTouchEventListener interceptTouchEventListener) {
mInterceptTouchEventListener = interceptTouchEventListener != null ? interceptTouchEventListener : DUMMY_LISTENER;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean stealTouchEvent = mInterceptTouchEventListener.onInterceptTouchEvent(this, ev, mDisallowIntercept);
return stealTouchEvent && !mDisallowIntercept || super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean handled = mInterceptTouchEventListener.onTouchEvent(this, event);
return handled || super.onTouchEvent(event);
}
}
您只需将听众设置为:view.setOnInterceptTouchEventListener()
在该侦听器中,您可以保持指针数量(在onIntercetTouchEvent()
方法内)。
只需将该布局作为布局的根目录(全屏)。
如果你试图在没有禁令的情况下做同样的事情,你可能会得到不正确的信息,因为你没有被授予接收所有触摸事件的权利。