1. The basic

  1. Master View system event distribution and processing, refer to Android Custom View(9) : Event distribution and processing
  2. To master the basic gesture listening and gestural action related callback timing, see Android custom View(10) : Gesture listening & Processing
  3. 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

  1. GestureOverlayView inherits FrameLayout, and FrameLayout inherits ViewGroup(inherits View);
  2. GestureOverlayView overrides the View’s dispatchTouchEvent method
  3. GestureOverlayView. SetEnabled () the default set to true, namely capture event distribution;
  4. 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