最近在做自定义View,有一个需求是需要自定义一个View实现全屏拖动。刚好研究了下,发现还是蛮简单的,在这里总结下大概的思路,直接上代码:
1、编写一个 main.xml 布局文件
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/framelayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="60dp"
android:layout_height="match_parent"
android:background="@color/colorPrimary">
<ImageView
android:id="@+id/imageview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/icon_a" />
</LinearLayout>
<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="60dp">
</FrameLayout>
</FrameLayout>
2、自定义 TouchView,为了以后的扩展
public class TouchView extends View {
private static final String TAG = "TouchView";
/**
* 记录X轴最后位置
*/
int lastX = 0;
/**
* 记录Y轴最后位置
*/
int lastY = 0;
/**
* 记录Action_Down - X轴位置
*/
int downX = 0;
/**
* 记录Action_Down - Y轴位置
*/
int downY = 0;
/**
* 记录Action_Down 时间
*/
long lastDownInMills;
final int DEFAULT_LIMITLEFT = 0;
final int DEFAULT_LIMITTOP = 0;
int limitLeft;
int limitTop;
int limitRight;
int limitBottom;
int screenWidth;
int screenHeight;
private OnClickListener l;
public TouchView(Context context) {
super(context);
}
public TouchView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
screenWidth = metrics.widthPixels;
screenHeight = metrics.heightPixels;
setLimitAuto();
}
public TouchView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/**
* 自适应边界
*/
private void setLimitAuto() {
setLimitAuto(null);
}
/**
* 根据parentView自适应边界
*
* @param parentView
*/
public void setLimitAuto(ViewGroup parentView) {
if (parentView == null) {
this.limitLeft = DEFAULT_LIMITLEFT;
this.limitTop = DEFAULT_LIMITTOP;
this.limitRight = screenWidth;
this.limitBottom = screenHeight;
} else {
this.limitLeft = parentView.getLeft();
this.limitTop = parentView.getTop();
this.limitRight = parentView.getRight();
this.limitBottom = parentView.getBottom();
}
}
/**
* 设定自定义边界
*
* @param limitLeft
* @param limitTop
* @param limitRight
* @param limitBottom
*/
public void setLimitParams(int limitLeft, int limitTop, int limitRight, int limitBottom) {
this.limitLeft = limitLeft;
this.limitTop = limitTop;
this.limitRight = limitRight;
this.limitBottom = limitBottom;
}
@Override
public void setOnClickListener(@Nullable OnClickListener l) {
this.l = l;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// System.out.println(event.getRawX());
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
lastDownInMills = System.currentTimeMillis();
lastX = (int) event.getRawX();
lastY = (int) event.getRawY();
downX = (int) event.getRawX();
downY = (int) event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
int dx = (int) event.getRawX() - lastX;
int dy = (int) event.getRawY() - lastY;
int left = getLeft() + dx;
int top = getTop() + dy;
int right = getRight() + dx;
int bottom = getBottom() + dy;
if (left < limitLeft) {
left = limitLeft;
right = left + getWidth();
}
if (top < limitTop) {
top = limitTop;
bottom = top + getHeight();
}
if (right > limitRight) {
right = limitRight;
left = limitRight - getWidth();
}
if (bottom > limitBottom) {
bottom = limitBottom;
top = limitBottom - getHeight();
}
layout(left, top, right, bottom);
lastX = (int) event.getRawX();
lastY = (int) event.getRawY();
break;
case MotionEvent.ACTION_UP:
dx = (int) event.getRawX() - downX;
dy = (int) event.getRawY() - downY;
if (dx + dy == 0 && System.currentTimeMillis() - lastDownInMills < 500) {
//TODO x + y移动距离小于2px 且 触碰时间小于500ms 触发点击事件
if (l != null) {
l.onClick(this);
}
}
onLastMovePosition.onLastMovePosition((int) event.getRawX(), (int) event.getRawY());
break;
}
return true;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
public void setOnLastMovePosition(OnMovePositionListener onLastMovePosition) {
this.onLastMovePosition = onLastMovePosition;
}
private OnMovePositionListener onLastMovePosition;
public interface OnMovePositionListener {
void onLastMovePosition(int x, int y);
}
}