android View拖拽效果

好久没有更新博客了,公司刚刚一个项目结束,总结了一点东西,想保留下来和大家一起分享,费话不多说,先看下效果图

直接上代码了:

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);
    }

}
发布了16 篇原创文章 · 获赞 14 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/liulong_/article/details/103424994