Android 可拖动的悬浮按钮

来源:互联网 发布:鲁大师软件下载 编辑:程序博客网 时间:2024/04/28 21:04

这是控件的主代码,在你的项目里面,新建一个同名的类,把代码直接复制进去就能用了。另外,这个类里面引用了工具类的一些代码。工具类在这个主类的源码下面也有贴出,直接把工具类的相关代码,复制到你自己的工具类里就行了,有问题可以加我QQ咨询:326257241。

/** * @ClassName: FloatDragView * @Description: 可拖动的悬浮按钮 * @Author: 李岳锋 * @Date:2017/3/1 */public class FloatDragView {    private Activity context; // 上下文    private ImageView mImageView; // 可拖动按钮    private static int mScreenWidth = -1; //屏幕的宽度    private static int mScreenHeight = -1; //屏幕的高度    private int relativeMoveX; // 控件相对屏幕左上角移动的位置X    private int relativeMoveY; // 控件相对屏幕左上角移动的位置Y    private boolean isIntercept = false; // 是否截断touch事件    private int startDownX; // 按下时的位置控件相对屏幕左上角的位置X    private int startDownY; // 按下时的位置控件距离屏幕左上角的位置Y    private static int[] lastPosition; // 用于记录上一次的位置(坐标0对应x,坐标1对应y)    /**     * @param context 上下文     * @param mViewContainer 可拖动按钮要存放的对应的Layout     * @param clickListener 可拖动按钮的点击事件     */    public static ImageView addFloatDragView(Activity context , RelativeLayout mViewContainer,                                             View.OnClickListener clickListener) {        FloatDragView floatDragView = new FloatDragView(context);        ImageView imageView = floatDragView.getFloatDragView(clickListener);        mViewContainer.addView(imageView);        return imageView;    }    // 初始化实例    private FloatDragView(Activity context) {        setScreenHW(context);        this.context = context;        lastPosition = new int[]{0,0};    }    // 获取可拖动按钮的实例    private ImageView getFloatDragView(View.OnClickListener clickListener) {        if (mImageView != null) {            return mImageView;        } else {            mImageView = new ImageView(context);            mImageView.setClickable(true);            mImageView.setFocusable(true);            mImageView.setImageResource(R.drawable.analyze_btn_selector);            setFloatDragViewParams(mImageView);            mImageView.setOnClickListener(clickListener);            setFloatDragViewTouch(mImageView);            return mImageView;        }    }    // 设置可拖动按钮的位置参数    private void setFloatDragViewParams(View floatDragView) {        // 记录最后图片在窗体的位置        int moveX = lastPosition[0];        int moveY = lastPosition[1];        if (0 != moveX || 0 != moveY) {// 移动后的位置            // 每次移动都要设置其layout,不然由于父布局可能嵌套listView,当父布局发生改变冲毁(如下拉刷新时)则移动的view会回到原来的位置            RelativeLayout.LayoutParams lpFeedback = new RelativeLayout.LayoutParams(                    RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);            lpFeedback.setMargins(moveX, moveY, 0, 0);            floatDragView.setLayoutParams(lpFeedback);        } else {// 初始位置            RelativeLayout.LayoutParams lpFeedback = new RelativeLayout.LayoutParams(                    RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);            lpFeedback.setMargins(0, 0, 20, 218);            lpFeedback.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);            lpFeedback.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);            floatDragView.setLayoutParams(lpFeedback);        }    }    // 可拖动按钮的touch事件    private void setFloatDragViewTouch(final ImageView floatDragView) {        floatDragView.setOnTouchListener(new View.OnTouchListener() {            @Override            public boolean onTouch(final View v, MotionEvent event) {                int action = event.getAction();                switch (action) {                    case MotionEvent.ACTION_DOWN:                        isIntercept = false;                        startDownX = relativeMoveX = (int) event.getRawX();                        startDownY = relativeMoveY = (int) event.getRawY();                        break;                    case MotionEvent.ACTION_MOVE:                        int dx = (int) event.getRawX() - relativeMoveX;                        int dy = (int) event.getRawY() - relativeMoveY;                        int left = v.getLeft() + dx;                        int top = v.getTop() + dy;                        int right = v.getRight() + dx;                        int bottom = v.getBottom() + dy;                        if (left < 0) {                            left = 0;                            right = left + v.getWidth();                        }                        if (right > mScreenWidth) {                            right = mScreenWidth;                            left = right - v.getWidth();                        }                        if (top < 0) {                            top = 0;                            bottom = top + v.getHeight();                        }                        if (bottom > mScreenHeight) {                            bottom = mScreenHeight;                            top = bottom - v.getHeight();                        }                        v.layout(left, top, right, bottom);                        relativeMoveX = (int) event.getRawX();                        relativeMoveY = (int) event.getRawY();                        break;                    case MotionEvent.ACTION_UP:                        int lastMoveDx = Math.abs((int) event.getRawX() - startDownX);                        int lastMoveDy = Math.abs((int) event.getRawY() - startDownY);                        if (5 < lastMoveDx || 5 < lastMoveDy) {// 防止点击的时候稍微有点移动点击事件被拦截了                            isIntercept = true;                        } else {                            isIntercept = false;                        }                        // 每次移动都要设置其layout,不然由于父布局可能嵌套listview,                        // 当父布局发生改变冲毁(如下拉刷新时)则移动的view会回到原来的位置                        RelativeLayout.LayoutParams lpFeedback = new RelativeLayout.LayoutParams(                                RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);                        lpFeedback.setMargins(v.getLeft(), v.getTop(), 0, 0);                        v.setLayoutParams(lpFeedback);                        // preferenceUtil.saveInt("moveX", v.getLeft());                        // preferenceUtil.saveInt("moveY", v.getTop());                        // 设置靠近边沿的                        setImageViewNearEdge(v);                        break;                }                return isIntercept;            }        });    }    // 将拖动按钮移动到边沿    private void setImageViewNearEdge(final View v) {        if (v.getLeft() < ((Utils.getScreenSize(context).x) / 2)) {            // 设置位移动画 向左移动控件位置            final TranslateAnimation animation = new TranslateAnimation(0, -v.getLeft(), 0, 0);            animation.setDuration(300);// 设置动画持续时间            animation.setRepeatCount(0);// 设置重复次数            animation.setFillAfter(true);            animation.setRepeatMode(Animation.ABSOLUTE);            animation.setAnimationListener(new Animation.AnimationListener() {                @Override                public void onAnimationStart(Animation arg0) {                    // TODO: 2017/3/1                  }                @Override                public void onAnimationRepeat(Animation arg0) {                    // TODO: 2017/3/1                }                @Override                public void onAnimationEnd(Animation arg0) {                    v.clearAnimation();                    RelativeLayout.LayoutParams lpFeedback = new RelativeLayout.LayoutParams(                            RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);                    lpFeedback.setMargins(0, v.getTop(), 0, 0);                    v.setLayoutParams(lpFeedback);                    v.postInvalidateOnAnimation();                    lastPosition[0] = 0;                    lastPosition[1] = v.getTop();                }            });            v.startAnimation(animation);        } else {            final TranslateAnimation animation = new TranslateAnimation(0, (Utils.getScreenSize(context).x                    - v.getLeft() - v.getWidth()), 0, 0);            animation.setDuration(300);// 设置动画持续时间            animation.setRepeatCount(0);// 设置重复次数            animation.setRepeatMode(Animation.ABSOLUTE);            animation.setFillAfter(true);            animation.setAnimationListener(new Animation.AnimationListener() {                @Override                public void onAnimationStart(Animation arg0) {                    // TODO: 2017/3/1                }                @Override                public void onAnimationRepeat(Animation arg0) {                    // TODO Auto-generated method stub                }                @Override                public void onAnimationEnd(Animation arg0) {                    v.clearAnimation();                    RelativeLayout.LayoutParams lpFeedback = new RelativeLayout.LayoutParams(                            RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);                    lpFeedback.setMargins(Utils.getScreenSize(context).x - v.getWidth(), v.getTop(), 0, 0);                    v.setLayoutParams(lpFeedback);                    v.postInvalidateOnAnimation();                    lastPosition[0] =Utils.getScreenSize(context).x - v.getWidth();                    lastPosition[1] = v.getTop();                }            });            v.startAnimation(animation);        }    }    // 计算屏幕的实际高宽    private void setScreenHW(Activity context) {        if (mScreenHeight < 0) {            // 减去状态栏高度,否则挨着底部移动,导致图标变小            Point screen = Utils.getScreenSize(context);            mScreenWidth = screen.x;            mScreenHeight = screen.y - Utils.getStatusBarHeight(context);        }    }}

以下是工具类的代码

public class Utils {    // 状态栏高度    private static  int statusBarHeight = 0;    // 屏幕像素点    private static final Point screenSize = new Point();    // 获取屏幕像素点    public static Point getScreenSize(Activity context) {        if (context == null) {            return screenSize;        }        WindowManager wm = (WindowManager) context                .getSystemService(Context.WINDOW_SERVICE);        if (wm != null) {            DisplayMetrics mDisplayMetrics = new DisplayMetrics();            Display diplay = wm.getDefaultDisplay();            if (diplay != null) {                diplay.getMetrics(mDisplayMetrics);                int W = mDisplayMetrics.widthPixels;                int H = mDisplayMetrics.heightPixels;                if (W * H > 0 && (W > screenSize.x || H > screenSize.y)) {                    screenSize.set(W, H);                }            }        }        return screenSize;    }    // 获取状态栏高度    public static int getStatusBarHeight(Context context) {        if (statusBarHeight <= 0) {            Rect frame = new Rect();            ((Activity) context).getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);            statusBarHeight = frame.top;        }        if (statusBarHeight <= 0) {            try {                Class<?> c = Class.forName("com.android.internal.R$dimen");                Object obj = c.newInstance();                Field field = c.getField("status_bar_height");                int x = Integer.parseInt(field.get(obj).toString());                statusBarHeight = context.getResources().getDimensionPixelSize(x);            } catch (Exception e1) {                e1.printStackTrace();            }        }        return statusBarHeight;    }}

使用方法

mRootView 就是要出现悬浮按钮的界面的根view。就是setContentView的View。FloatDragView.addFloatDragView(this, mRootView, new View.OnClickListener() {   @Override   public void onClick(View view) {   // 点击事件   }});
0 0
原创粉丝点击