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.