1.先創建一個類繼承你想要的View並實現前三個構造方法
public class DragFloatActionButton extends androidx.appcompat.widget.AppCompatImageView {
public DragFloatActionButton(Context context) {
super(context);
}
public DragFloatActionButton(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public DragFloatActionButton(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
2.複寫觸控方法
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
return true;
}
3.取得觸碰的X,Y座標
int rawX = (int) event.getRawX();
int rawY = (int) event.getRawY();
4.判斷 按下,移動,抬起三種操作模式
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.d("event", "ACTION_DOWN");
break;
case MotionEvent.ACTION_MOVE:
Log.d("event", "ACTION_MOV");
break;
case MotionEvent.ACTION_UP:
Log.d("event", "ACTION_UP");
break;
}
5.按下動作(ACTION_DOWN)
//取得按下時間
startTime = System.currentTimeMillis();
//不要讓父控件攔截事件
getParent().requestDisallowInterceptTouchEvent(true);
lastX = rawX;
lastY = rawY;
if (getParent() != null) {
//取得父控件的寬高
ViewGroup parent = (ViewGroup) getParent();
parentHeight = parent.getHeight();
parentWidth = parent.getWidth();
6.移動事件(ACTION_MOVE)
//移動座標-最後一次座標
int dx = rawX - lastX;
int dy = rawY - lastY;
float x = getX() + dx;
float y = getY() + dy;
x = x < 0 ? 0 : x > parentWidth - getWidth() ? parentWidth - getWidth() : x;
y = getY() < 0 ? 0 : getY() + getHeight() > parentHeight ? parentHeight - getHeight() : y;
setX(x);
setY(y);
lastX = rawX;
lastY = rawY;
7.抬起事件(ACTION_UP)
//取得最後抬起時間
long endTime = System.currentTimeMillis();
if (endTime - startTime < 100) {
Log.d("event", "點擊");
//觸發點擊事件
performClick();
} else {
Log.d("event", "拖移");
}
if (rawX >= parentWidth / 2) {
//靠右吸附
animate().setInterpolator(new DecelerateInterpolator())
.setDuration(500)
.xBy(parentWidth - getWidth() - getX())
.start();
} else {
//靠左吸附
ObjectAnimator oa = ObjectAnimator.ofFloat(this, "x", getX(), 0);
oa.setInterpolator(new DecelerateInterpolator());
oa.setDuration(500);
}
8.完整程式碼
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import androidx.annotation.Nullable;
public class DragFloatActionButton extends androidx.appcompat.widget.AppCompatImageView {
private long startTime;
private int lastX;
private int lastY;
private int parentHeight;
private int parentWidth;
public DragFloatActionButton(Context context) {
super(context);
}
public DragFloatActionButton(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public DragFloatActionButton(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
int rawX = (int) event.getRawX();
int rawY = (int) event.getRawY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startTime = System.currentTimeMillis();
//不要讓父控件攔截事件
getParent().requestDisallowInterceptTouchEvent(true);
lastX = rawX;
lastY = rawY;
if (getParent() != null) {
//取得父控件的寬高
ViewGroup parent = (ViewGroup) getParent();
parentHeight = parent.getHeight();
parentWidth = parent.getWidth();
}
break;
case MotionEvent.ACTION_MOVE:
//移動座標-最後一次座標
int dx = rawX - lastX;
int dy = rawY - lastY;
float x = getX() + dx;
float y = getY() + dy;
x = x < 0 ? 0 : x > parentWidth - getWidth() ? parentWidth - getWidth() : x;
y = getY() < 0 ? 0 : getY() + getHeight() > parentHeight ? parentHeight - getHeight() : y;
setX(x);
setY(y);
lastX = rawX;
lastY = rawY;
break;
case MotionEvent.ACTION_UP:
long endTime = System.currentTimeMillis();
if (endTime - startTime < 100) {
Log.d("event", "點擊");
performClick();
} else {
Log.d("event", "拖移");
}
if (rawX >= parentWidth / 2) {
//靠右吸附
animate().setInterpolator(new DecelerateInterpolator())
.setDuration(500)
.xBy(parentWidth - getWidth() - getX())
.start();
} else {
//靠左吸附
ObjectAnimator oa = ObjectAnimator.ofFloat(this, "x", getX(), 0);
oa.setInterpolator(new DecelerateInterpolator());
oa.setDuration(500);
oa.start();
}
break;
}
return true;
}
}