自定义可吸附的悬浮按钮

作者: 莫语莫雨 | 来源:发表于2018-12-11 14:30 被阅读25次

    悬浮按钮在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>
    

    注意事项

    这样,就能实现基本的拖拽功能,不过其中有些注意事项,我在之前就经常犯这样的错

    1.千万不要把lastX和lastY写在onTouchEvent方法中,否则,当你拖拽的时候,就会发现按钮会一直闪,并且会一直在开始的位置和当前位置交替出现 image.png
    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图呈现不是太好,就不在此做演示了,如果大家需要看源码的话,可以跟我联系

    相关文章

      网友评论

        本文标题:自定义可吸附的悬浮按钮

        本文链接:https://www.haomeiwen.com/subject/fiishqtx.html