好久没有更新博客了,公司刚刚一个项目结束,总结了一点东西,想保留下来和大家一起分享,费话不多说,先看下效果图
直接上代码了:
activity中使用
DragFloatManager.init(this)
.bindView(dragView)
.setListener(new FloatUtils.OnFloatListener() {
@Override
public void onFloat(boolean isDarg) {
//true,拖拽中,false拖拽结束
}
}).start();
api:
init():初始化,可在activity中初始化,也可在fragment
bindView();绑定一个需要拖拽的View
setListener()监听拖拽
setPaddingBottom():拖动时,拖拽的View距离底部的距离
start():启动拖拽
******注意*****
拖拽的View的父布局必须是RelativeLayout
//////////////////////////////////////////////////////////////////////////////////////
import android.app.Activity;
import android.content.Context;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.RelativeLayout;
import androidx.fragment.app.Fragment;
/*按钮悬浮拖动效果*/
public class FloatUtils {
private View view;
float lastRawX, lastRawY;
boolean isDrag = false; //是否拖动
int width;
int height;
int screenWidth;
int screenHeight;
private OnFloatListener onFloatListener;
private Fragment fragment;
private int paddingBottom;
public interface OnFloatListener {
void onFloat(boolean isDarg);
}
private Activity context;
/*Activity中初始化*/
public FloatUtils(Activity context) {
this.context = context;
}
/*Fragment中初始化*/
public FloatUtils(Fragment fragment) {
this.fragment = fragment;
this.context = fragment.getActivity();
}
/*绑定拖动的控件*/
public FloatUtils bindView(View view) {
this.view = view;
return this;
}
/*设置拖动时,距离底部边缘的距离
* 单位dp*/
public FloatUtils setPaddingBottom(int paddingBottom) {
this.paddingBottom = paddingBottom;
return this;
}
/*设置拖动监听*/
public FloatUtils setListener(OnFloatListener onFloatListener) {
this.onFloatListener = onFloatListener;
return this;
}
/*启动拖动效果
* fragment 中需等待所有控件绘制完毕才可执行*/
public void start() {
if (fragment == null) {
initDragImageView();
} else {
ViewTreeObserver observer = fragment.getView().getViewTreeObserver();
observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
fragment.getView().getViewTreeObserver().removeGlobalOnLayoutListener(this);
initDragImageView();
}
});
}
}
private int dp2px(Context context, float dpValue) {
float scale = 0;
try {
scale = context.getResources().getDisplayMetrics().density;
} catch (Exception e) {
scale = 0;
}
return (int) (dpValue * scale + 0.5f);
}
// 获取最大宽度
private int getMaxWidth() {
if (fragment != null) {
return fragment.getView().getMeasuredWidth();
} else {
DisplayMetrics dm = new DisplayMetrics();
context.getWindowManager().getDefaultDisplay().getRealMetrics(dm);
Log.e("getMaxWidth", dm.widthPixels + "");
return dm.widthPixels;
}
}
// 获取最大高度
private int getMaxHeight() {
if (fragment != null) {
return fragment.getView().getMeasuredHeight();
} else {
DisplayMetrics dm = new DisplayMetrics();
context.getWindowManager().getDefaultDisplay().getRealMetrics(dm);
Log.e("getMaxWidth", dm.heightPixels + "");
return dm.heightPixels;
}
}
private void initDragImageView() {
width = dp2px(context, 50);
height = dp2px(context, 50);
screenWidth = getMaxWidth();
screenHeight = getMaxHeight() - dp2px(context, paddingBottom);
view.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
isDrag = false;
lastRawX = motionEvent.getRawX();
lastRawY = motionEvent.getRawY();
view.bringToFront();
onFloatListener.onFloat(isDrag);
break;
case MotionEvent.ACTION_MOVE:
int dx = (int) (motionEvent.getRawX() - lastRawX);//相对坐标
int dy = (int) (motionEvent.getRawY() - lastRawY);//相对坐标
int l, r, t, b;
if (Math.abs(dx) > 10 || Math.abs(dy) > 10) {
isDrag = true;
onFloatListener.onFloat(isDrag);
l = (int) (view.getLeft() + dx);
r = l + width;
t = (int) (view.getTop() + dy);
b = t + height;
//不划出边界判断,此处应按照项目实际情况,因为本项目需求移动的位置是手机全屏,
// 所以才能这么写,如果是固定区域,要得到父控件的宽高位置后再做处理
if (l < 0) {
l = 0;
r = l + width;
} else if (r > screenWidth) {
r = screenWidth;
l = r - width;
}
if (t < getStatusBarHeight()) {
t = getStatusBarHeight();
b = t + height;
} else if (b > screenHeight) {
b = screenHeight;
t = b - height;
}
setRelativeViewLocation(view, l, t, r, b);//设置按钮位置
lastRawX = motionEvent.getRawX();
lastRawY = motionEvent.getRawY();
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
break;
}
return false;
}
});
}
/*获取状态栏高度
* fragment中不需要使用*/
private int getStatusBarHeight() {
if (fragment == null) {
if (context.isFinishing()) {
return 0;
}
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
return context.getResources().getDimensionPixelSize(resourceId);
} else {
return 0;
}
}
private void setRelativeViewLocation(View view, int left, int top, int right, int bottom) {
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(right - left, bottom - top);
params.setMargins(left, top, 0, 0);
view.setLayoutParams(params);
}
}
代码不难,博主也比较懒,所以就不一一分析了
import android.app.Activity;
import androidx.fragment.app.Fragment;
import com.yunbix.ifsir.utils.FloatUtils;
public class DragFloatManager {
public static FloatUtils init(Activity activity) {
return new FloatUtils(activity);
}
public static FloatUtils init(Fragment activity) {
return new FloatUtils(activity);
}
}