Android draggable hover button

Keywords: Android

This is the main code of the control. In your project, create a new class with the same name, and copy the code directly to use it. In addition, some code of tool class is referenced in this class. Tool class is also posted under the source code of this main class. Copy the relevant code of tool class directly to your own tool class. If you have any questions, please add my QQ consultation: 326257241.

/**
 * @ClassName: FloatDragView
 * @Description: Draggable hover button
 * @Author: Arjung
 * @Date: 2016/3/18
 */
public class FloatDragView {


    private Activity context; // context
    private ImageView mImageView; // Draggable button
    private static int mScreenWidth = -1; //The width of the screen
    private static int mScreenHeight = -1; //Screen height
    private int relativeMoveX; // The position X of the control relative to the upper left corner of the screen
    private int relativeMoveY; // Position Y of the control relative to the upper left corner of the screen
    private boolean isIntercept = false; // Whether to truncate the touch event
    private int startDownX; // Position control when pressed relative to position X in the upper left corner of the screen
    private int startDownY; // Position control when pressed position Y from the top left corner of the screen
    private static int[] lastPosition; // Used to record the last position (coordinate 0 corresponds to x, coordinate 1 corresponds to y)


    /**
     * @param context context
     * @param mViewContainer The Layout corresponding to the button to be dragged
     * @param clickListener Draggable button click event
     */
    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;
    }

    // Initialize instance
    private FloatDragView(Activity context) {
        setScreenHW(context);
        this.context = context;
        lastPosition = new int[]{0,0};
    }

    // Get an instance of a draggable button
    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;
        }

    }

    // Set the position parameter of the draggable button
    private void setFloatDragViewParams(View floatDragView) {

        // Record the position of the last picture on the form
        int moveX = lastPosition[0];
        int moveY = lastPosition[1];
        if (0 != moveX || 0 != moveY) {// Position after move
            // Every time you move, you need to set its layout. Otherwise, because the parent layout may be nested with listView, when the parent layout changes and crashes (such as when the drop-down is refreshed), the moved view will return to its original position
            RelativeLayout.LayoutParams lpFeedback = new RelativeLayout.LayoutParams(
                    RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
            lpFeedback.setMargins(moveX, moveY, 0, 0);
            floatDragView.setLayoutParams(lpFeedback);
        } else {// initial position 
            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 events for draggable buttons
    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) {// To prevent a little bit of movement when clicking, click event is blocked
                            isIntercept = true;
                        } else {
                            isIntercept = false;
                        }
                        // The layout should be set for each move, otherwise, because the parent layout may nest listview,
                        // When the parent layout changes and is destroyed (such as when the drop-down is refreshed), the moved view will return to its original position
                        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());
                        // Set near edge
                        setImageViewNearEdge(v);
                        break;
                }
                return isIntercept;
            }
        });
    }

    // Move drag button to edge
    private void setImageViewNearEdge(final View v) {

        if (v.getLeft() < ((Utils.getScreenSize(context).x) / 2)) {
            // Animate displacement move control position left
            final TranslateAnimation animation = new TranslateAnimation(0, -v.getLeft(), 0, 0);
            animation.setDuration(300);// Set animation duration
            animation.setRepeatCount(0);// Set number of repetitions
            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);// Set animation duration
            animation.setRepeatCount(0);// Set number of repetitions
            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);
        }
    }

    // Calculate the actual height and width of the screen
    private void setScreenHW(Activity context) {
        if (mScreenHeight < 0) {
            // Subtract the height of the status bar, otherwise move next to the bottom, resulting in smaller icons
            Point screen = Utils.getScreenSize(context);
            mScreenWidth = screen.x;
            mScreenHeight = screen.y - Utils.getStatusBarHeight(context);
        }
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236

Here is the code for the tool class

public class Utils {

    // Status bar height
    private static  int statusBarHeight = 0;
    // Screen pixels
    private static final Point screenSize = new Point();

    // Get screen pixels
    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;
    }

    // Get status bar height
    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;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

usage method

mRootView Is the root of the interface where the hover button will appear view. Namely setContentView Of View. 

FloatDragView.addFloatDragView(this, mRootView, new View.OnClickListener() {
   @Override
   public void onClick(View view) {
   // Click event
   }
});

Posted by AjithTV on Sat, 02 May 2020 17:29:39 -0700