TouchListener PK OnTouchEvent + multi-touch
Introduction to this section:
As the title states, this section brings you a comparison between TouchListener and OnTouchEvent, as well as more points Touch knowledge points! TouchListener is based on listening, while OnTouchEvent is based on callbacks! Let’s use two simple examples to deepen the understanding. Everyone’s understanding!
1. TouchListener based on listening
Code example:
Implementation rendering:
Implementation code: main.xml
android:layout_width="match_parent"
android:layout_height=" match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@ dimen/activity_vertical_margin"
tools:context=".MyActivity">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android :id="@+id/imgtouch"
android:background="../style/images/touch"/>
</RelativeLayout>
MainAcitivity.java
private ImageView imgtouch;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
imgtouch = (ImageView)findViewById(R.id.imgtouch);
imgtouch.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Toast.makeText(getApplicationContext(),"你通过监听器模式:OnTouchListener摸了伦家~",Toast.LENGTH_LONG).show();
return true;
}
});
}
}
Code analysis:
It is simply to set an ImageView, then setOnTouchListener, and rewrite the onTouch method! It is very simple. In fact, this is already in the frame layout section There is an example. Do you still remember the cute girl who moved with her finger?
OnTouchListener related methods and properties:
onTouch(View v, MotionEvent event): The parameters here are the components that trigger the touch event. , touch event event Encapsulates the detailed information of the triggering event, including the type of event, triggering time and other information. For example, event.getX(), event.getY()
We can also judge the type of touch action and use event.getAction() to judge again; such as:
event.getAction == MotionEvent.ACTION_DOWN: Press event
event.getAction == MotionEvent.ACTION_MOVE: Move event
event.getAction == MotionEvent.ACTION_UP: Pop-up event
2. Callback-based onTouchEvent() method
is also a touch event, but onTouchEvent is more used for customized views, so This method has been overridden in the view class, and this touch event is based on callbacks, that is to say: if the value we return is false, then the event will continue to propagate outward and be processed by the external container or Activity !Of course it also involves gestures, which we will explain in detail later! onTouchEvent is actually similar to onTouchListener, except that the processing mechanism is not used. The former is a callback and the latter is in listening mode!
Code example: Define a simple view, draw a small blue circle, which can move with your finger
Implementation code:MyView.java
public float X = 50;
public float Y = 50;
//创建画笔
Paint paint = new Paint();
public MyView(Context context,AttributeSet set)
{
super(context,set);
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setColor(Color.BLUE);
canvas.drawCircle(X,Y,30,paint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
this.X = event.getX();
this.Y = event.getY();
//通知组件进行重绘
this.invalidate();
return true;
}
}
main.xml:
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MyActivity">
<example.jay.com.touch2.MyView
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
Implementation renderings:
Use your finger to touch to move~
3 .Multi-touch
Principles of things:
The so-called multi-touch means multiple fingers operating on the screen. The most commonly used one is probably the zoom function, such as Many image browsers support zooming! In theory, the Android system itself can handle the touch of up to 256 fingers, of course, this depends on the support of the mobile phone hardware; however, mobile phones that support multi-touch generally support 2-4 points, and of course some have more! We found that MotionEvent is used in the first two points, and MotionEvent represents a touch event; previously we can judge what kind of operation it is based on event.getAction() & MotionEvent.ACTION_MASK, in addition to the three introduced above In addition to single-point operations, there are two multi-point dedicated operations:
- MotionEvent.ACTION_POINTER_DOWN: When a point on the screen is already pressed, press it again at this time Triggered at other points.
- MotionEvent.ACTION_POINTER_UP: Triggered when multiple points on the screen are pressed and one of the points is released (that is, when the non-last point is released).
The simple process is probably like this:
- When we touch the screen with a finger——> Trigger the ACTION_DOWN event
- Then another finger also touches the screen——> Triggers the ACTION_POINTER_DOWN event. If there are other fingers touching, continue to trigger
- A finger leaves the screen——> Triggers the ACTION_POINTER_UP event. If another finger continues to leave, continue Trigger
- When the last finger leaves the screen——> Trigger the ACTION_UP event
- And during the entire process, the ACTION_MOVE event will be triggered continuously
We can obtain the positions of different touch points through event.getX(int) or event.getY(int): For example, event.getX(0) can get the X coordinate of the first contact point, event.getX(1) can get the X coordinate of the second contact point like this... In addition, we can also determine how many fingers are currently touching by calling the getPointerCount() method of the MotionEvent object~
Code example:
Okay, Let’s write the most common example of dragging an image with one finger and zooming an image with two fingers:
Implementation renderings:
Implementation Code:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="@+id/img_test"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="matrix"
android:src="@drawable/pic1" />
</RelativeLayout>
MainActivity.java
import android.app.Activity;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.os.Bundle;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
public class MainActivity extends Activity implements OnTouchListener {
private ImageView img_test;
// Zoom control
private Matrix matrix = new Matrix();
private Matrix savedMatrix = new Matrix();
// Representation of different states:
private static final int NONE = 0;
private static final int DRAG = 1;
private static final int ZOOM = 2;
private int mode = NONE;
// Define the first pressed point, the focus of the two contact points, and the cause of the accident The distance between two fingers pressing:
private PointF startPoint = new PointF();
private PointF midPoint = new PointF();
private float oriDis = 1f;
/*
* (non-Javadoc)
*
* @see android.app.Activity#onCreate(android.os.Bundle)
*/
@Override
protected void onCreate(Bundle savedInstanceState ) {
’ ’ ’ ’ s ’ s to this);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
ImageView view = (ImageView) v;
switch (event.getAction() & MotionEvent.ACTION_MASK) {
// Single finger
case MotionEvent.ACTION_DOWN:
matrix.set(view.getImageMatrix());
savedMatrix.set(matrix);
startPoint.set(event.getX(), event.getY());
mode = DRAG;
break;
// 双指
case MotionEvent.ACTION_POINTER_DOWN:
oriDis = distance(event);
if (oriDis > 10f) {
savedMatrix.set(matrix);
midPoint = middle(event);
mode = ZOOM;
}
break;
// 手指放开
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
break;
// 单指滑动事件
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
// 是一个手指拖动
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() - startPoint.x, event.getY() - startPoint.y);
} else if (mode == ZOOM) {
// 两个手指滑动
float newDist = distance(event);
if (newDist > 10f) {
matrix.set(savedMatrix);
float scale = newDist / oriDis;
matrix.postScale(scale, scale, mid Point.
return true ;
}
// Calculate the distance between two touch points
private float distance(MotionEvent event) {
float x = event.getX(0) - event.getX( 1);
float y = event.getY(0) - event.getY(1);
return FloatMath.sqrt(x * x + y * y);
}
// Calculate the midpoint of two touch points
private PointF middle(MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY (0) + event.getY(1);
return new PointF(x / 2, y / 2);
}
}
Summary of this section:
Okay,
and OnTouchEvent