悬浮按钮在APP中是比较常见的一个功能,因为有着比较不错的交互性,所以,在实际的开发中,或多或少都会被设计进去,今天,我们就来实现一下,可吸附的悬浮按钮是如何实现的,最终的效果图如下所示:
20181211_142637.gif
实现步骤:
1.通过自定时控件继承View,也同样可以继承其他的VIew或者VIewGroup,大家可以根据实际的情况进行选择
public class CustomFloatView 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"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.clb.jsdemo.CustomFloatView
android:id="@+id/float_view"
android:layout_width="50dp"
android:background="#e23232"
android:layout_height="50dp"/>
</LinearLayout>
注意事项
这样,就能实现基本的拖拽功能,不过其中有些注意事项,我在之前就经常犯这样的错
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);
}
最终效果
#这样效果就呈现出来了,如果觉得吸附太过僵硬的话,还可以在其中加入一些动画,因为gif图呈现不是太好,就不在此做演示了,如果大家需要看源码的话,可以跟我联系
网友评论