好久没有更新博客了,公司刚刚一个项目结束,总结了一点东西,想保留下来和大家一起分享,费话不多说,先看下效果图
直接上代码了:
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); } }