Android Custom Control 1--EventParser

Keywords: Java Mobile Android Programming

Zero, preface

Custom View s often deal with events, but that event object feels troublesome to use.
I intend to write an event resolution class to assist in event analysis. The functions include:

1. Click Listen: Callback - > Outgoing Point (Type PointF)  
2. Lift monitoring: callback - > finger lift point (type PointF), moving direction (type Orientation, eight)  
3. Mobile monitoring: callback - > speed (double) y displacement (float) x displacement (float) angle (double), moving direction  
4. Whether to move, whether to press the judgment - - - the source code is relatively simple, I comment very clearly, are posted at the end of the text, self-cv.
Test results:

1. Direction testing

2. Angle and displacement measurement

3. Velocity Analysis

I. Use:

1. Initialize EventParser at view initialization and set up listeners for EventParser
2. Set parsing objects for mEventParser in onTouchEvent (not only view, but also Activity, only event)

public class EventView extends View {
    private EventParser mEventParser;
    public EventView(Context context) {
        this(context, null);
    }
    public EventView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    private void init() {
        mEventParser = new EventParser();//Initialize EventParser
        //Setting up listeners for EventParser
        mEventParser.setOnEventListener(new OnEventListener() {
            @Override
            public void down(PointF pointF) {
            }
            @Override
            public void up(PointF pointF, Orientation orientation) {
            }
            @Override
            public void move(double v, float dy, float dx, double dir, Orientation orientation) {
            }
        });
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mEventParser.parseEvent(event);//Setting parsing objects
        return true;
    }
}

So all these event parameters are yours.
Of course, it also provides an adapter, just want to use a callback method, without directly implementing the interface, you can:

mEventParser.setOnEventListener(new OnEventAdapter(){
    @Override
    public void move(double v, float dy, float dx, double dir, Orientation orientation) {
    }
});

2. Code Implementation

1. Parser main class: EventParser
/**
 * Author: Zhang Fengjie's <br/>
 * Time: 2018/11/6 0006:20:22 < br/>
 * E-mail: 1981462002@qq.com<br/>
 * Description: Event parser
 */
public class EventParser {
    private OnEventListener onEventListener;
    private Orientation mOrientation = Orientation.NO;

    private PointF mTagPos;//Press the coordinate point
    //Moving Coordinate Points - Create objects here to avoid creating large numbers of objects in move s
    private PointF mMovingPos = new PointF(0, 0);

    private float detaY = 0;//Total amount of downward movement
    private float detaX = 0;//Right shift total

    private boolean isDown = false;//Whether or not to press
    private boolean isMove = false;//Whether to move

    private PointF mDownPos;//Record down time point
    private long lastTimestamp = 0L;//Last timestamp

    public void setOnEventListener(OnEventListener onEventListener) {
        this.onEventListener = onEventListener;
    }

    /**
     * Add your own event resolution
     *
     * @param event Event
     */
    public void parseEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                isDown = true;
                //Press - assign a value to p0
                mTagPos = new PointF(event.getX(), event.getY());
                mDownPos = mTagPos;
                lastTimestamp = System.currentTimeMillis();
                if (onEventListener != null) {
                    onEventListener.down(mTagPos);
                }
                break;
            case MotionEvent.ACTION_MOVE:
                //The coordinates of the moment of movement (moving, constantly updating)
                mMovingPos.x = event.getX();
                mMovingPos.y = event.getY();
                //processing speed
                detaX = mMovingPos.x - mDownPos.x;
                detaY = mMovingPos.y - mDownPos.y;
                //Downward single volume
                float dx = mMovingPos.x - mTagPos.x;
                //Right shift single volume
                float dy = mMovingPos.y - mTagPos.y;
                double ds = Math.sqrt(dx * dx + dy * dy);//Offset shift single quantity
                double dir = deg((float) Math.acos(detaX / ds));//angle

                long curTimestamp = System.currentTimeMillis();
                long dt = curTimestamp - lastTimestamp;
                //Because the velocity is C*px/ms
                double v = ds / dt * 100;
                orientationHandler(dir);//Processing direction
                if (onEventListener != null) {
                    onEventListener.move(v, detaY, detaX, detaY < 0 ? dir : -dir, mOrientation);
                }
                if (Math.abs(detaY) > 50 / 3.0) {
                    isMove = true;
                }
                mTagPos.x = mMovingPos.x;//Update location
                mTagPos.y = mMovingPos.y;//Update Location - Note that you can't make two objects equal here
                lastTimestamp = curTimestamp;//Update time
                break;
            case MotionEvent.ACTION_UP:
                if (onEventListener != null) {
                    onEventListener.up(mTagPos, mOrientation);
                }
                reset();//Reset work
                break;
        }
    }

    /**
     * Reset work
     */
    private void reset() {
        isDown = false;//Reset Press State
        isMove = false;//Reset Moving State
        mDownPos.x = 0;//Reset: mDownPos
        mDownPos.y = 0;//Reset: mDownPos
        mOrientation = Orientation.NO;//Reset direction
    }

    /**
     * Processing direction
     *
     * @param dir direction
     */
    private void orientationHandler(double dir) {
        if (detaY < 0 && dir > 70 && dir < 110) {
            mOrientation = Orientation.TOP;
        }
        if (detaY > 0 && dir > 70 && dir < 110) {
            mOrientation = Orientation.BOTTOM;
        }
        if (detaX > 0 && dir < 20) {
            mOrientation = Orientation.RIGHT;
        }
        if (detaX < 0 && dir > 160) {
            mOrientation = Orientation.LEFT;
        }
        if (detaY < 0 && dir <= 70 && dir >= 20) {
            mOrientation = Orientation.RIGHT_TOP;
        }
        if (detaY < 0 && dir >= 110 && dir <= 160) {
            mOrientation = Orientation.LEFT_TOP;
        }
        if (detaX > 0 && detaY > 0 && dir >= 20 && dir <= 70) {
            mOrientation = Orientation.RIGHT_BOTTOM;
        }
        if (detaX < 0 && detaY > 0 && dir >= 110 && dir <= 160) {
            mOrientation = Orientation.LEFT_BOTTOM;
        }
    }

    public boolean isDown() {
        return isDown;
    }

    public boolean isMove() {
        return isMove;
    }

    /**
     * Radius system into angle system
     *
     * @param rad radian
     * @return angle
     */
    private float deg(float rad) {
        return (float) (rad * 180 / Math.PI);
    }
}
2. Direction enumeration:
/**
 * Author: Zhang Fengjie's <br/>
 * Time: 2018/11/15 0015:8:14 < br/>
 * E-mail: 1981462002@qq.com<br/>
 * Description: Moving Direction Enumeration
 */
public enum Orientation {

    NO("nothing"),//nothing
    TOP("upper"), //upper
    BOTTOM("lower"),//lower
    LEFT("Left"),//Left
    RIGHT("right"),//right
    LEFT_TOP("Left upper"),// Left upper
    RIGHT_TOP("Right upper"), // Right upper
    LEFT_BOTTOM("Left lower"),//Left lower
    RIGHT_BOTTOM("lower right")//lower right
    
    private String or;
    
    Orientation(String or) {
        this.or = or;

    }

    public String value() {
        return or;
    }
}
3. Event monitoring callback
/**
 * Author: Zhang Fengjie's <br/>
 * Time: 2018/11/15 0015:8:13 < br/>
 * E-mail: 1981462002@qq.com<br/>
 * Note: Event monitoring callback
 */

public interface OnEventListener {
    /**
     * click
     *
     * @param pointF Drop point
     */
    void down(PointF pointF);

    /**
     * lift
     *
     * @param pointF      Lift the starting point
     * @param orientation direction
     */
    void up(PointF pointF, Orientation orientation);

    /**
     * move
     *
     * @param v           speed
     * @param dy          y displacement
     * @param dx          x displacement
     * @param dir         angle
     * @param orientation direction
     */
    void move(double v, float dy, float dx, double dir, Orientation orientation);
}
4. Event Processing Adapter
/**
 * Author: Zhang Fengjie's <br/>
 * Time: 2018/11/15 0015:8:18 < br/>
 * E-mail: 1981462002@qq.com<br/>
 * Description: Event Processing Adapter
 */
public class OnEventAdapter implements OnEventListener {
    @Override
    public void down(PointF pointF) {

    }

    @Override
    public void up(PointF pointF, Orientation orientation) {

    }

    @Override
    public void move(double v, float dy, float dx, double dir, Orientation orientation) {

    }
}

Postscript: Jasper Specification

1. The Growth Record and Corrigendum List of this Paper
Project source code date Remarks
V0.1-- no 2018-11-15 Event Parser for Android Custom Control Auxiliaries
2. statement

1. This article was originally created by Zhang Fengjie and reproduced by him.
2. Welcome all programming enthusiasts to communicate with each other. Wechat: zdl1994328
3. Individual ability is limited. If there is something wrong, you are welcome to criticize and testify. You must correct it modestly.
4 - Seeing this, I would like to thank you for your love and support.

Posted by Arenium on Tue, 23 Apr 2019 09:27:34 -0700