1. The basic
- Master View system event distribution and processing, refer to Android Custom View(9) : Event distribution and processing
- To master the basic gesture listening and gestural action related callback timing, see Android custom View(10) : Gesture listening & Processing
- To learn how to use the GestureLibrary and GestureOverlayView APIS, refer to the official API documentation
2. Draw
Drawing description:
(See code comment for specific usage and key points)
1. Add the GestureOverlayView control to the layout file. 2. Then get the control object in the code; 3. Initialize the paint brush; 4. Set monitoring; 5. If an activity is associated, remove it at onDestroy().Copy the code
2.1 XML code
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.gesture.GestureOverlayView
android:id="@+id/gesture_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:gravity="center"
android:layout_height="match_parent">
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</android.gesture.GestureOverlayView>
</RelativeLayout>
Copy the code
2.2 the activity code
package com.cupster.android_x_frame;
import android.gesture.Gesture;
import android.gesture.GestureOverlayView;
import android.graphics.Color;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class DrawGestureActivity extends AppCompatActivity implements GestureOverlayView.OnGesturePerformedListener.GestureOverlayView.OnGesturingListener {
GestureOverlayView mGestureOverlayView;
TextView mTvHint;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_draw_gesture);
mGestureOverlayView = findViewById(R.id.gesture_overlay);
mTvHint = findViewById(R.id.text);
mGestureOverlayView.setFadeOffset(800);// Default 420ms, set to 800ms
mGestureOverlayView.setGestureStrokeType(GestureOverlayView.GESTURE_STROKE_TYPE_MULTIPLE);// The default is single-finger continuous drawing, set to multi-finger drawing
mGestureOverlayView.setGestureStrokeWidth(10);// Draw the line width
mGestureOverlayView.setGestureColor(Color.parseColor("#3ca1f9"));// Draw the color
mGestureOverlayView.setUncertainGestureColor(Color.parseColor("#a7dbf7"));/ / the colour gradually
// Set the listener
mGestureOverlayView.addOnGesturePerformedListener(this);
mGestureOverlayView.addOnGesturingListener(this);
}
@Override
protected void onDestroy(a) {
mGestureOverlayView.removeOnGesturePerformedListener(this);
mGestureOverlayView.removeOnGesturingListener(this);
super.onDestroy();
}
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
//=========GesturePerformedListener=============
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
@Override
public void onGesturePerformed(GestureOverlayView gestureOverlayView, Gesture gesture) {
mTvHint.append("\n");
mTvHint.append("--> All drawing paths, identified");
}
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
//=========GesturingListener=====================
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
@Override
public void onGesturingStarted(GestureOverlayView gestureOverlayView) {
mTvHint.append("\n");
mTvHint.append("--> Start drawing with single hand gesture");
}
@Override
public void onGesturingEnded(GestureOverlayView gestureOverlayView) {
mTvHint.append("\n");
mTvHint.append("--> End of single gesture drawing"); }}Copy the code
2.3 Source code analysis
2.3.1 conclusion
- GestureOverlayView inherits FrameLayout, and FrameLayout inherits ViewGroup(inherits View);
- GestureOverlayView overrides the View’s dispatchTouchEvent method
- GestureOverlayView. SetEnabled () the default set to true, namely capture event distribution;
- GestureOverlayView. SetEnabled (false), can be regarded as FrameLayout, namely no response gesture drawing;
Validation code:
// With test disabled, mGestureOverlayView is enabled by default to draw == read gesture events
mGestureOverlayView.setEnabled(false);
mTvHint.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
mTvHint.append("\n");
mTvHint.append("Draw not enabled, event distribution normal");
return true; }});Copy the code
2.3.2 source
See the code comments for parsing
public class GestureOverlayView extends FrameLayout {...@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (isEnabled()) {
final booleancancelDispatch = (mIsGesturing || (mCurrentGesture ! =null &&
mCurrentGesture.getStrokesCount() > 0 && mPreviousWasGesturing)) &&
mInterceptEvents;
processEvent(event);// That is, grab event distribution
if (cancelDispatch) {
event.setAction(MotionEvent.ACTION_CANCEL);
}
super.dispatchTouchEvent(event);
return true;// Reply to the event handled by the upper level, but not delivered
}
//isEnabled== false, which can be regarded as FrameLayout and distribute events normally
return super.dispatchTouchEvent(event); }... }...private boolean processEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touchDown(event);// This callback is ongestuinfo. //
invalidate();
return true;
case MotionEvent.ACTION_MOVE:
if (mIsListeningForGestures) {
Rect rect = touchMove(event);// Here call onGesture
if(rect ! =null) {
invalidate(rect);
}
return true;
}
break;
case MotionEvent.ACTION_UP:
if (mIsListeningForGestures) {
touchUp(event, false);/ / callback onGestureEnded
invalidate();
return true;
}
break;
case MotionEvent.ACTION_CANCEL:
if (mIsListeningForGestures) {
touchUp(event, true);// The flag bit is true to cancel the gesture
invalidate();
return true; }}return false; }... ./** * Call invalidate(), invalidate(rect) */
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
if(mCurrentGesture ! =null&& mGestureVisible) { canvas.drawPath(mPath, mGesturePaint); }}...Copy the code