摘要:測(cè)試效果方向測(cè)試角度位移測(cè)試速度解析一使用初始化時(shí)初始化并為設(shè)置監(jiān)聽器在里為設(shè)置解析對(duì)象不止是,在中也可以用只有有初始化為設(shè)置監(jiān)聽器設(shè)置解析對(duì)象這樣所有的這些事件參數(shù)就是你的了。
零、前言
</>復(fù)制代碼
自定義View經(jīng)常和事件打交道,不過那個(gè)event對(duì)象用著感覺挺麻煩
打算自己寫一個(gè)事件的解析類來輔助事件的分析,功能包括:
</>復(fù)制代碼
1.點(diǎn)擊監(jiān)聽:回調(diào)-->傳出落點(diǎn)(類型PointF)
2.抬起監(jiān)聽:回調(diào)-->手指抬起點(diǎn)(類型PointF)、移動(dòng)方向(類型Orientation,八個(gè))
3.移動(dòng)監(jiān)聽:回調(diào)-->速度(double) y位移(float) x位移(float) 角度(double)、移動(dòng)方向
4.是否移動(dòng)、是否按下的判斷--------源碼比較簡(jiǎn)單,我注釋也很清楚,都貼在文尾,自行cv。
</>復(fù)制代碼
1.方向測(cè)試
</>復(fù)制代碼
2.角度、位移測(cè)試
一、使用:</>復(fù)制代碼
3.速度解析
</>復(fù)制代碼
1.view初始化時(shí)初始化EventParser并為EventParser設(shè)置監(jiān)聽器
2.在onTouchEvent里為mEventParser設(shè)置解析對(duì)象(不止是view,在Activity中也可以用,只有有event)
</>復(fù)制代碼
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();//初始化EventParser
//為EventParser設(shè)置監(jiān)聽器
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);//設(shè)置解析對(duì)象
return true;
}
}
</>復(fù)制代碼
這樣所有的這些事件參數(shù)就是你的了。
當(dāng)然也提供了適配器,只想用一個(gè)回調(diào)方法的,不需要直接實(shí)現(xiàn)接口,你可以:
</>復(fù)制代碼
mEventParser.setOnEventListener(new OnEventAdapter(){
@Override
public void move(double v, float dy, float dx, double dir, Orientation orientation) {
}
});
二、代碼實(shí)現(xiàn)
</>復(fù)制代碼
/**
* 作者:張風(fēng)捷特烈
* 時(shí)間:2018/11/6 0006:20:22
* 郵箱:1981462002@qq.com
* 說明:事件解析器
*/
public class EventParser {
private OnEventListener onEventListener;
private Orientation mOrientation = Orientation.NO;
private PointF mTagPos;//按下坐標(biāo)點(diǎn)
//移動(dòng)時(shí)坐標(biāo)點(diǎn)---在此創(chuàng)建對(duì)象,避免在move中創(chuàng)建大量對(duì)象
private PointF mMovingPos = new PointF(0, 0);
private float detaY = 0;//下移總量
private float detaX = 0;//右移總量
private boolean isDown = false;//是否按下
private boolean isMove = false;//是否移動(dòng)
private PointF mDownPos;//記錄按下時(shí)點(diǎn)
private long lastTimestamp = 0L;//最后一次的時(shí)間戳
public void setOnEventListener(OnEventListener onEventListener) {
this.onEventListener = onEventListener;
}
/**
* 添加自己的事件解析
*
* @param event 事件
*/
public void parseEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
isDown = true;
//按下---為p0賦值
mTagPos = new PointF(event.getX(), event.getY());
mDownPos = mTagPos;
lastTimestamp = System.currentTimeMillis();
if (onEventListener != null) {
onEventListener.down(mTagPos);
}
break;
case MotionEvent.ACTION_MOVE:
//移動(dòng)的那刻的坐標(biāo)(移動(dòng)中,不斷更新)
mMovingPos.x = event.getX();
mMovingPos.y = event.getY();
//處理速度
detaX = mMovingPos.x - mDownPos.x;
detaY = mMovingPos.y - mDownPos.y;
//下移單量
float dx = mMovingPos.x - mTagPos.x;
//右移單量
float dy = mMovingPos.y - mTagPos.y;
double ds = Math.sqrt(dx * dx + dy * dy);//偏移位移單量
double dir = deg((float) Math.acos(detaX / ds));//角度
long curTimestamp = System.currentTimeMillis();
long dt = curTimestamp - lastTimestamp;
//由于速度是C*px/ms
double v = ds / dt * 100;
orientationHandler(dir);//處理方向
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;//更新位置
mTagPos.y = mMovingPos.y;//更新位置----注意這里不能讓兩個(gè)對(duì)象相等
lastTimestamp = curTimestamp;//更新時(shí)間
break;
case MotionEvent.ACTION_UP:
if (onEventListener != null) {
onEventListener.up(mTagPos, mOrientation);
}
reset();//重置工作
break;
}
}
/**
* 重置工作
*/
private void reset() {
isDown = false;//重置按下狀態(tài)
isMove = false;//重置移動(dòng)狀態(tài)
mDownPos.x = 0;//重置:mDownPos
mDownPos.y = 0;//重置:mDownPos
mOrientation = Orientation.NO;//重置方向
}
/**
* 處理方向
*
* @param dir 方向
*/
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;
}
/**
* 弧度制化為角度制
*
* @param rad 弧度
* @return 角度
*/
private float deg(float rad) {
return (float) (rad * 180 / Math.PI);
}
}
</>復(fù)制代碼
/**
* 作者:張風(fēng)捷特烈
* 時(shí)間:2018/11/15 0015:8:14
* 郵箱:1981462002@qq.com
* 說明:移動(dòng)方向枚舉
*/
public enum Orientation {
NO("無"),//無
TOP("上"), //上
BOTTOM("下"),//下
LEFT("左"),//左
RIGHT("右"),//右
LEFT_TOP("左上"),// 左上
RIGHT_TOP("右上"), // 右上
LEFT_BOTTOM("左下"),//左下
RIGHT_BOTTOM("右下")//右下
private String or;
Orientation(String or) {
this.or = or;
}
public String value() {
return or;
}
}
</>復(fù)制代碼
/**
* 作者:張風(fēng)捷特烈
* 時(shí)間:2018/11/15 0015:8:13
* 郵箱:1981462002@qq.com
* 說明:事件監(jiān)聽回調(diào)
*/
public interface OnEventListener {
/**
* 點(diǎn)擊
*
* @param pointF 落點(diǎn)
*/
void down(PointF pointF);
/**
* 抬起
*
* @param pointF 抬起點(diǎn)
* @param orientation 方向
*/
void up(PointF pointF, Orientation orientation);
/**
* 移動(dòng)
*
* @param v 速度
* @param dy y 位移
* @param dx x位移
* @param dir 角度
* @param orientation 方向
*/
void move(double v, float dy, float dx, double dir, Orientation orientation);
}
</>復(fù)制代碼
/**
* 作者:張風(fēng)捷特烈
* 時(shí)間:2018/11/15 0015:8:18
* 郵箱:1981462002@qq.com
* 說明:事件處理適配器
*/
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) {
}
}
后記:捷文規(guī)范
項(xiàng)目源碼 | 日期 | 備注 |
---|---|---|
V0.1--無 | 2018-11-15 | Android自定義控件輔助利器之EventParser |
</>復(fù)制代碼
1----本文由張風(fēng)捷特烈原創(chuàng),轉(zhuǎn)載請(qǐng)注明
2----歡迎廣大編程愛好者共同交流,微信:zdl1994328
3----個(gè)人能力有限,如有不正之處歡迎大家批評(píng)指證,必定虛心改正
4----看到這里,我在此感謝你的喜歡與支持
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/74264.html
閱讀 1210·2021-11-10 11:35
閱讀 2952·2021-09-24 10:35
閱讀 2976·2021-09-22 15:38
閱讀 2815·2019-08-30 15:43
閱讀 1350·2019-08-29 18:39
閱讀 2597·2019-08-29 15:22
閱讀 2805·2019-08-28 18:17
閱讀 621·2019-08-26 13:37