悬浮按钮在APP中是比较常见的一个功能,因为有着比较不错的交互性,所以,在实际的开发中,或多或少都会被设计进去,今天,我们就来实现一下,可吸附的悬浮按钮是如何实现的,最终的效果图如下所示:
20181211_142637.gif
实现步骤:
1.通过自定时控件继承View,也同样可以继承其他的VIew或者VIewGroup,大家可以根据实际的情况进行选择public class Cust
omFloatView extends View{ int screenHeight; int screenWidth; public CustomFloatView(Context context) { this(context, null);
} public CustomFloatView(Context context, AttributeSet attrs) { this(context, attrs, -1);
} public CustomFloatView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr);
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
screenWidth = displayMetrics.widthPixels;
screenHeight = displayMetrics.heightPixels;
}
}
2.重写onTouchEvent方法/**
* 控件最终的位置
*/
private int lastX = 0; private int lastY = 0; @Override
public boolean onTouchEvent(MotionEvent motionEvent) { int action = motionEvent.getAction(); int rowX = (int) motionEvent.getRawX(); int rowY = (int) motionEvent.getRawY(); switch (action) { case MotionEvent.ACTION_DOWN: //获取触摸点位置
getParent().requestDisallowInterceptTouchEvent(true);
lastX = rowX;
lastY = rowY; break; case MotionEvent.ACTION_MOVE: //计算移动了多少
int dx = rowX - lastX; int dy = rowY - lastY; //计算当前的位置
int l = getLeft() + dx; int r = getRight() + dx; int t = getTop() + dy; int b = getBottom() + dy; //设置当前位置
layout(l, t, r, b); //将当前位置设为最终的位置
lastX = rowX;
lastY = rowY; break; case MotionEvent.ACTION_UP: //判断当前位置离哪里比较近
break;
} return true;
}
3.在布局中使用
<?xml version="1.0" encoding="utf-8"?>
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:id="@+id/float_view"
android:layout_width="50dp"
android:background="#e23232"
android:layout_height="50dp"/>
注意事项
这样,就能实现基本的拖拽功能,不过其中有些注意事项,我在之前就经常犯这样的错
1.千万不要把lastX和lastY写在onTouchEvent方法中,否则,当你拖拽的时候,就会发现按钮会一直闪,并且会一直在开始的位置和当前位置交替出现
image.png
2.注意在拖拽结束后注意重新设置按钮的坐标,不然按钮会回到最初的位置(如果需求就是要回到最初的位置,那就不用在处理了)
image.png
以上只是实现了基本的拖拽功能,还有吸附功能没有进行处理,其实这个很简单,只要获取屏幕宽度判断一下当前的位置靠那边近一点,设置对应的坐标就可以了
实现步骤
1.首先需要获取屏幕的宽度,可以在构造方法中进行获取,获取的方式也是各种各样,大家可以自行选择
public CustomFloatView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr);
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
screenWidth = displayMetrics.widthPixels;
screenHeight = displayMetrics.heightPixels;
}
2.获取当前控件的坐标位置和控件大小int rowX = (int) motionEvent.getRawX();int rowY = (int) motionEvent.getRawY();
3.判断当前控件离哪边比较近,动态设置坐标/**
* 创建者:clb
* 创建时间: 2018-12-11 14:15
* 功能:吸附到边缘
*/
private void toSlide(int rowX, int rowY) { //计算移动了多少
int dx = rowX - lastX; int dy = rowY - lastY; int left = getLeft(); int right = getRight(); int top = getTop(); int bottom = getBottom(); //计算当前的位置
int l; int r; int t = top + dy; int b = bottom + dy; //判断当前控件距离哪边比较近
if (left > screenWidth / 2) { //距离右边比较近
//那么设置控件的四个点,纵坐标不变
l = (screenWidth - (right - left));
r = screenWidth;
} else { //距离左边比较近
l = 0;
r = right - left;
} //设置当前位置
layout(l, t, r, b); //将当前位置设为最终的位置
lastX = rowX;
lastY = rowY;
Log.d("最终坐标", l + "*******" + t + "*******" + r + "*******" + b);
}
最终效果
作者:莫语莫雨