/**刪除原有點(diǎn)擊事件, 通過listener注入新的點(diǎn)擊事件*/
public class OnDragTouchListener implements View.OnTouchListener {
private int mScreenWidth, mScreenHeight;//屏幕寬高
private float mOriginalX, mOriginalY;//手指按下時(shí)的初始位置
private float mDistanceX, mDistanceY;//記錄手指與view的左上角的距離
private int left, top, right, bottom;
private OnDraggableClickListener mListener;
private boolean hasAutoPullToBorder;//標(biāo)記是否開啟自動(dòng)拉到邊緣功能
public OnDragTouchListener() {
}
public OnDragTouchListener(boolean isAutoPullToBorder) {
hasAutoPullToBorder = isAutoPullToBorder;
}
@Override
public boolean onTouch(final View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mScreenWidth = v.getResources().getDisplayMetrics().widthPixels;
mScreenHeight = v.getResources().getDisplayMetrics().heightPixels;
mOriginalX = event.getRawX();
mOriginalY = event.getRawY();
mDistanceX = event.getRawX() - v.getLeft();
mDistanceY = event.getRawY() - v.getTop();
break;
case MotionEvent.ACTION_MOVE:
left = (int) (event.getRawX() - mDistanceX);
top = (int) (event.getRawY() - mDistanceY);
right = left + v.getWidth();
bottom = top + v.getHeight();
if (left < 0) {
left = 0;
right = left + v.getWidth();
}
if (top < 0) {
top = 0;
bottom = top + v.getHeight();
}
if (right > mScreenWidth) {
right = mScreenWidth;
left = right - v.getWidth();
}
if (bottom > mScreenHeight) {
bottom = mScreenHeight;
top = bottom - v.getHeight();
}
v.layout(left, top, right, bottom);
break;
case MotionEvent.ACTION_UP:
//如果移動(dòng)距離過小站欺,則判定為點(diǎn)擊
if (mListener != null
&& Math.abs(event.getRawX() - mOriginalX) < 10
&& Math.abs(event.getRawY() - mOriginalY) < 10) {
mListener.onClick(v);
}else {
//在拖動(dòng)過按鈕后,如果其他view刷新導(dǎo)致重繪,會(huì)讓按鈕重回原點(diǎn)泞边,所以需要更改布局參數(shù)
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
startAutoPull(v, lp);
}
//消除警告
v.performClick();
break;
}
return true;
}
public OnDraggableClickListener getOnDraggableClickListener() {
return mListener;
}
public void setOnDraggableClickListener(OnDraggableClickListener listener) {
mListener = listener;
}
public boolean isHasAutoPullToBorder() {
return hasAutoPullToBorder;
}
public void setHasAutoPullToBorder(boolean hasAutoPullToBorder) {
this.hasAutoPullToBorder = hasAutoPullToBorder;
}
/**
* 開啟自動(dòng)拖拽
*
* @param v 拉動(dòng)控件
* @param lp 控件布局參數(shù)
*/
private void startAutoPull(final View v, final ViewGroup.MarginLayoutParams lp) {
if (!hasAutoPullToBorder) {
v.layout(left, top, right, bottom);
lp.setMargins(left, top, 0, 0);
v.setLayoutParams(lp);
if (mListener != null) {
mListener.onDragged(v, left, top);
}
return;
}
//當(dāng)用戶拖拽完后,讓控件根據(jù)遠(yuǎn)近距離回到最近的邊緣
float end = 0;
if ((left + v.getWidth() / 2) >= mScreenWidth / 2) {
end = mScreenWidth - v.getWidth();
}
ValueAnimator animator = ValueAnimator.ofFloat(left, end);
animator.setInterpolator(new DecelerateInterpolator());
animator.addUpdateListener(animation -> {
int leftMargin = (int) ((float) animation.getAnimatedValue());
v.layout(leftMargin, top, right, bottom);
lp.setMargins(leftMargin, top, 0, 0);
v.setLayoutParams(lp);
});
final float finalEnd = end;
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
if (mListener != null) {
mListener.onDragged(v, (int) finalEnd, top);
}
}
});
animator.setDuration(400);
animator.start();
}
/**
* 控件拖拽監(jiān)聽器
*/
public interface OnDraggableClickListener {
/**
* 當(dāng)控件拖拽完后回調(diào)
*
* @param v 拖拽控件
* @param left 控件左邊距
* @param top 控件右邊距
*/
void onDragged(View v, int left, int top);
/**
* 當(dāng)可拖拽控件被點(diǎn)擊時(shí)回調(diào)
*
* @param v 拖拽控件
*/
void onClick(View v);
}
}
View拖動(dòng)+點(diǎn)擊事件
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
- 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來墨吓,“玉大人球匕,你說我怎么就攤上這事√妫” “怎么了亮曹?”我有些...
- 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我乾忱,道長,這世上最難降的妖魔是什么历极? 我笑而不...
- 正文 為了忘掉前任窄瘟,我火速辦了婚禮,結(jié)果婚禮上趟卸,老公的妹妹穿的比我還像新娘蹄葱。我一直安慰自己,他們只是感情好锄列,可當(dāng)我...
- 文/花漫 我一把揭開白布图云。 她就那樣靜靜地躺著,像睡著了一般邻邮。 火紅的嫁衣襯著肌膚如雪竣况。 梳的紋絲不亂的頭發(fā)上,一...
- 文/蒼蘭香墨 我猛地睜開眼晒哄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了肪获?” 一聲冷哼從身側(cè)響起寝凌,我...
- 正文 獨(dú)居荒郊野嶺守林人離奇死亡寒锚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
- 正文 我和宋清朗相戀三年劫映,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片刹前。...
- 正文 年R本政府宣布,位于F島的核電站千诬,受9級特大地震影響耍目,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜徐绑,卻給世界環(huán)境...
- 文/蒙蒙 一邪驮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧傲茄,春花似錦毅访、人聲如沸。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至草巡,卻和暖如春守呜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背山憨。 一陣腳步聲響...
- 正文 我出身青樓侣颂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親枪孩。 傳聞我的和親對象是個(gè)殘疾皇子憔晒,可洞房花燭夜當(dāng)晚...
推薦閱讀更多精彩內(nèi)容
- 引入 最近在做項(xiàng)目優(yōu)化的時(shí)候,發(fā)現(xiàn)點(diǎn)擊某個(gè)控件使用某個(gè)功能時(shí)蔑舞,事先要判斷用戶是否登錄拒担,翻看代碼時(shí)發(fā)現(xiàn)很多地方寫了大...
- 需求描述 點(diǎn)擊“操作指導(dǎo)”按鈕,在其正下方彈出“產(chǎn)品說明書”攻询、“操作視頻”兩個(gè)選項(xiàng)供用戶選擇从撼,點(diǎn)擊PopupWin...
- 實(shí)現(xiàn)想法 很簡單View消費(fèi)自己點(diǎn)擊事件是要觸發(fā)onTouchEvent方法低零,只需要自定義一下View,并重寫on...