Android 安卓多点触控?
作为一名开发人员,我倾向于先编程,然后再研究。我试图实现一个可以处理多个用户输入的屏幕。基本上映射的不仅仅是一个手指。我试过两件事 我有一个实现了OnTouchListener的活动类。在这里,我有两个独立的子视图,它们将活动添加为它们的ontouch侦听器。然后我有一个打印行,打印出event.getPointerCount()并打印出每个指针的位置 将其下载到手机上并进行了测试。我注意到指针从未超过两个。我甚至注意到,如果一个手指放在一个子视图上,另一个手指放在另一个子视图上,那么事件只会到达第一个子组件。接下来,我尝试在每个子组件上放置单独的侦听器,以查看这是否可行,但其作用是相同的 因此,在处理触摸屏幕的用户输入时,android似乎只支持总共两个用户输入 这是真的吗?从测试和研究来看,情况似乎是这样 有人遇到过这种限制吗。有什么巧妙的解决办法吗 感谢您的时间和回复Android 安卓多点触控?,android,multi-touch,ontouchlistener,Android,Multi Touch,Ontouchlistener,作为一名开发人员,我倾向于先编程,然后再研究。我试图实现一个可以处理多个用户输入的屏幕。基本上映射的不仅仅是一个手指。我试过两件事 我有一个实现了OnTouchListener的活动类。在这里,我有两个独立的子视图,它们将活动添加为它们的ontouch侦听器。然后我有一个打印行,打印出event.getPointerCount()并打印出每个指针的位置 将其下载到手机上并进行了测试。我注意到指针从未超过两个。我甚至注意到,如果一个手指放在一个子视图上,另一个手指放在另一个子视图上,那么事件只会到
dk支持的触点数量取决于设备。在所有当前可用版本的Android
MotionEvent
s中,事件被发送到单个目标视图,并描述所有当前活动触点的状态。目标视图由第一个MotionEvent.ACTION\u DOWN
事件发生的位置决定
请参阅Android开发者博客上的文章,快速了解如何在Android上使用多点触控事件。我编写了一个非常简单的应用程序,用于在我的HTC手机上测试多点触控。我的行为很像我的想法,也很像adamp给出的URL。我的结果是,手机只能处理两个手指的输入。我有一个盒子,每个盒子都有自己的听者。单击每个框时,我会为每个框打印一个文本。点击每个get touch事件,但我用食指点击屏幕上的任意位置,得到了两个指针。从MotionEvent.getPointerCount方法。不管食指落在哪里。可能在接收第一个手指向下事件的原始视图之外。不管怎样,如果你想自己试试,这里有代码 我有一个整个项目的7z,但我不认为我可以附加它 因此,这里是布局的主要活动和xml
package com.multitouch;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MultiTouch extends Activity {
protected LinearLayout sq1;
protected LinearLayout sq2;
protected LinearLayout sq3;
protected LinearLayout sq4;
protected String sqText = new String();
protected String sq1Text = new String();
protected String sq2Text = new String();
protected String sq3Text = new String();
private Handler handler = new Handler();
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setViews();
handler.postDelayed(mUpdateUITimerTask, 5000);
}
private final Runnable mUpdateUITimerTask = new Runnable() {
public void run() {
// do whatever you want to change here, like:
updateTextField();
}
};
private void updateTextField() {
TextView view1 = (TextView) this.findViewById(R.id.logView);
TextView view2 = (TextView) this.findViewById(R.id.logView1);
TextView view3 = (TextView) this.findViewById(R.id.logView2);
TextView view4 = (TextView) this.findViewById(R.id.logView3);
//view1.append(sqText + "\n");
view1.setText(sqText);
view2.setText(sq1Text);
view3.setText(sq2Text);
view4.setText(sq3Text);
handler.post(mUpdateUITimerTask);
}
private void setViews() {
sq1 = (LinearLayout) this.findViewById(R.id.square1);
sq2 = (LinearLayout) this.findViewById(R.id.square2);
sq3 = (LinearLayout) this.findViewById(R.id.square3);
sq4 = (LinearLayout) this.findViewById(R.id.square4);
sq1.setOnTouchListener(new TouchListener());
sq2.setOnTouchListener(new TouchListener());
sq3.setOnTouchListener(new TouchListener());
sq4.setOnTouchListener(new TouchListener());
}
private class TouchListener implements OnTouchListener {
@Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getPointerCount()>2) {
sq1Text = "GOT THREE POINTERS!!";
sq2Text = "GOT THREE POINTERS!!";
sq3Text = "GOT THREE POINTERS!!";
sqText = "GOT THREE POINTERS!!";
}
if(event.getAction() == MotionEvent.ACTION_DOWN){
switch(v.getId()) {
case R.id.square1:
sqText = "Square 1 Pressed::Pointer count = " + String.valueOf(event.getPointerCount());
break;
case R.id.square2:
sq1Text = "Square 2 Pressed::Pointer count = " + String.valueOf(event.getPointerCount());
break;
case R.id.square3:
sq2Text = "Square 3 Pressed::Pointer count = " + String.valueOf(event.getPointerCount());
break;
case R.id.square4:
sq3Text = "Square 4 Pressed::Pointer count = " + String.valueOf(event.getPointerCount());
break;
}
} else if(event.getAction() == MotionEvent.ACTION_POINTER_DOWN ||
event.getAction() == MotionEvent.ACTION_POINTER_UP) {
switch(v.getId()) {
case R.id.square1:
sqText = "Square 1 Pointer Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n";
break;
case R.id.square2:
sq1Text = "Square 2 Pointer Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n";
break;
case R.id.square3:
sq2Text = "Square 3 Pointer Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n";
break;
case R.id.square4:
sq3Text = "Square 4 Pointer Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n";
break;
}
} else if(event.getAction() == MotionEvent.ACTION_POINTER_1_DOWN) {
switch(v.getId()) {
case R.id.square1:
sqText = "Square 1 Pointer1Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n";
break;
case R.id.square2:
sq1Text = "Square 2 Pointer1Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n";
break;
case R.id.square3:
sq2Text = "Square 3 Pointer1Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n";
break;
case R.id.square4:
sq3Text = "Square 4 Pointer1Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n";
break;
}
} else if(event.getAction() == MotionEvent.ACTION_POINTER_2_DOWN) {
switch(v.getId()) {
case R.id.square1:
sqText = "Square 1 Pointer2Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n";
break;
case R.id.square2:
sq1Text = "Square 2 Pointer2Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n";
break;
case R.id.square3:
sq2Text = "Square 3 Pointer2Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n";
break;
case R.id.square4:
sq3Text = "Square 4 Pointer2Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n";
break;
}
} else if(event.getAction() == MotionEvent.ACTION_POINTER_3_DOWN) {
switch(v.getId()) {
case R.id.square1:
sqText = "Square 1 Pointer3Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n";
break;
case R.id.square2:
sq1Text = "Square 2 Pointer3Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n";
break;
case R.id.square3:
sq2Text = "Square 3 Pointer3Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n";
break;
case R.id.square4:
sq3Text = "Square 4 Pointer3Down::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n";
break;
}
} else if(event.getAction() == MotionEvent.ACTION_UP) {
switch(v.getId()) {
case R.id.square1:
sqText = "Square 1 UP::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n";
break;
case R.id.square2:
sq1Text = "Square 2 UP::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n";
break;
case R.id.square3:
sq2Text = "Square 3 UP::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n";
break;
case R.id.square4:
sq3Text = "Square 4 UP::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n";
break;
}
} else if(event.getAction() == MotionEvent.ACTION_MOVE) {
switch(v.getId()) {
case R.id.square1:
sqText = "Square 1 MOVE::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n";
break;
case R.id.square2:
sq1Text = "Square 2 MOVE::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n";
break;
case R.id.square3:
sq2Text = "Square 3 MOVE::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n";
break;
case R.id.square4:
sq3Text = "Square 4 MOVE::Pointer count = " + String.valueOf(event.getPointerCount()) + "\n";
break;
}
}
// TODO Auto-generated method stub
return true;
}
}
}
布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:gravity="center_horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/MainLay" >
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:gravity="center_horizontal" android:padding="10dip">
<TableRow android:gravity="center_horizontal" android:padding="10dip">
<LinearLayout android:background="#FFFF00" android:id="@+id/square1" android:padding="10px" android:layout_width="125px" android:layout_height="125px"/>
<LinearLayout android:background="#FF00FF" android:id="@+id/square2" android:padding="10px" android:layout_width="125px" android:layout_height="125px"/>
</TableRow>
<TableRow android:gravity="center_horizontal" android:padding="10dip">
<LinearLayout android:background="#00FFFF" android:id="@+id/square3" android:padding="10px" android:layout_width="125px" android:layout_height="125px"/>
<LinearLayout android:background="#eeeeee" android:id="@+id/square4" android:padding="10px" android:layout_width="125px" android:layout_height="125px"/>
</TableRow>
<TextView android:id="@+id/logView" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
<TextView android:id="@+id/logView1" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
<TextView android:id="@+id/logView2" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
<TextView android:id="@+id/logView3" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
</TableLayout>
</LinearLayout>
祝你好运,如果你尝试了,如果你得到了三分球,请告诉我!!打印报表。我想知道什么手机支持它
谢谢,
dk我编辑了@dakira答案。以下是我的示例代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/MainLay"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tvHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="4dp"
android:text="Place Your Finger on Squire"
android:textColor="#000"
android:textSize="20sp" />
<LinearLayout
android:id="@+id/llStatusHolder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/tvHeader"
android:orientation="vertical"
android:weightSum="2">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="8dp"
android:weightSum="2">
<TextView
android:id="@+id/tvBox1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#FFFF00"
android:gravity="center"
android:padding="4dp"
android:text="Finger : 0"
android:textColor="#000"
android:textSize="28sp" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/square1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="4dp"
android:layout_below="@+id/llStatusHolder"
android:layout_weight="1"
android:background="#FFFF00"
android:orientation="horizontal"
android:padding="10dp">
</LinearLayout>
</RelativeLayout>
</LinearLayout>
希望这能解决很多人的问题:)
谢谢你的URL,它帮助我们澄清了一些事情。但我必须亲自去看看。因此,我编写了一个简单的应用程序来测试文章中所说的内容。将添加代码以自我回答此问题。Galaxy S似乎最多支持五个计数器。由来自不同论坛的人使用上述软件演示。使用LG optimus。仅检测1个计数器。
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MultiTouchTestActivity extends Activity {
protected LinearLayout sq1;
TextView tvBox1;
int counter1 = 0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_multi_touch_test);
setViews();
}
private void updateTextField() {
tvBox1.setText("Finger : " + counter1);
}
private void setViews() {
tvBox1 = (TextView) findViewById(R.id.tvBox1);
sq1 = (LinearLayout) this.findViewById(R.id.square1);
sq1.setOnTouchListener(new TouchListener());
}
private class TouchListener implements OnTouchListener {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == 1) {
setCounterValue(1, 0);
}else if (event.getAction() == MotionEvent.ACTION_DOWN) {
setCounterValue(1, event.getPointerCount());
} else if (event.getAction() == MotionEvent.ACTION_POINTER_DOWN ||
event.getAction() == MotionEvent.ACTION_POINTER_UP) {
setCounterValue(1, event.getPointerCount());
} else if (event.getAction() == MotionEvent.ACTION_POINTER_1_DOWN) {
setCounterValue(1, event.getPointerCount());
} else if (event.getAction() == MotionEvent.ACTION_POINTER_2_DOWN) {
setCounterValue(1, event.getPointerCount());
} else if (event.getAction() == MotionEvent.ACTION_POINTER_3_DOWN) {
setCounterValue(1, event.getPointerCount());
} else if (event.getAction() == MotionEvent.ACTION_UP) {
setCounterValue(1, event.getPointerCount());
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
setCounterValue(1, event.getPointerCount());
}else if (event.getAction() == MotionEvent.ACTION_BUTTON_RELEASE) {
setCounterValue(1, 0);
}
updateTextField();
return true;
}
}
void setCounterValue(int hasvalue, int value) {
switch (hasvalue) {
case 1:
counter1 = value;
break;
}
}
}