Android 超简单的拖动按钮 悬浮按钮 吸附按钮

第一种

  

第二种

  

第一种实现方法

xml布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/startBtn"
        android:layout_width="35dp"
        android:layout_height="35dp"
        android:layout_centerInParent="true"
        android:background="@drawable/addstock" />

</RelativeLayout>

Activity调用

        DisplayMetrics dm = getResources().getDisplayMetrics();
        screenWidth = dm.widthPixels;
        screenHeight = dm.heightPixels;

        // Toast.makeText(getActivity(), screenWidth + "==" + screenHeight + "="
        // + vHeight, 0).show();

        // 拖动的按钮
        btn = (Button) view.findViewById(R.id.startBtn);
        btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                if (bool) {
                    LatestNetDataPackage lnPackage = new LatestNetDataPackage(R.string.COMMAND_LATESTNET, fundKind, sortType,
                            requestType, curPage, FUND_COUNT, 0);
                    dataPackage = lnPackage;
                    NetWorkTaskManager.addRequestToRequestCache(lnPackage, HListViewFragment.this, HListViewFragment.this,
                            getActivity());
                    btn.setBackgroundResource(R.drawable.deletestock);
                    bool = false;
                } else {
                    LatestNetDataPackage lnPackage = new LatestNetDataPackage(R.string.COMMAND_LATESTNET, fundKind, sortType,
                            requestType, curPage, FUND_COUNT, 1);
                    dataPackage = lnPackage;
                    NetWorkTaskManager.addRequestToRequestCache(lnPackage, HListViewFragment.this, HListViewFragment.this,
                            getActivity());
                    btn.setBackgroundResource(R.drawable.addstock);
                    bool = true;
                }
            }
        });

        btn.setOnTouchListener(new OnTouchListener() {
            int lastX, lastY; // 记录移动的最后的位置
            private int btnHeight;

            public boolean onTouch(View v, MotionEvent event) {
                // 获取Action
                int ea = event.getAction();
                switch (ea) {
                case MotionEvent.ACTION_DOWN: // 按下
                    lastX = (int) event.getRawX();
                    lastY = (int) event.getRawY();
                    screenWidth = view.getWidth();
                    screenHeight = view.getHeight();
                    btnHeight = btn.getHeight();
                    // Toast.makeText(getActivity(), "ACTION_DOWN:" + lastX + ",
                    // " + lastY, 0).show();
                    break;
                case MotionEvent.ACTION_MOVE: // 移动
                    // 移动中动态设置位置
                    int dx = (int) event.getRawX() - lastX;
                    int dy = (int) event.getRawY() - lastY;
                    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 > screenWidth) {
                        right = screenWidth;
                        left = right - v.getWidth();
                    }
                    if (top < 0) {
                        top = 0;
                        bottom = top + v.getHeight();
                    }
                    if (bottom > screenHeight) {
                        bottom = screenHeight;
                        top = bottom - v.getHeight();
                    }
                    v.layout(left, top, right, bottom);
                    // Toast.makeText(getActivity(), "position:" + left + ", " +
                    // top + ", " + right + ", " + bottom, 0)
                    // .show();
                    // 将当前的位置再次设置
                    lastX = (int) event.getRawX();
                    lastY = (int) event.getRawY();
                    break;
                case MotionEvent.ACTION_UP: // 抬起
                    // 向四周吸附
//                    int dx1 = (int) event.getRawX() - lastX;
//                    int dy1 = (int) event.getRawY() - lastY;
//                    int left1 = v.getLeft() + dx1;
//                    int top1 = v.getTop() + dy1;
//                    int right1 = v.getRight() + dx1;
//                    int bottom1 = v.getBottom() + dy1;
//                    if (left1 < (screenWidth / 2)) {
//                        if (top1 < 100) {
//                            v.layout(left1, 0, right1, btnHeight);
//                        } else if (bottom1 > (screenHeight - 200)) {
//                            v.layout(left1, (screenHeight - btnHeight), right1, screenHeight);
//                        } else {
//                            v.layout(0, top1, btnHeight, bottom1);
//                        }
//                    } else {
//                        if (top1 < 100) {
//                            v.layout(left1, 0, right1, btnHeight);
//                        } else if (bottom1 > (screenHeight - 200)) {
//                            v.layout(left1, (screenHeight - btnHeight), right1, screenHeight);
//                        } else {
//                            v.layout((screenWidth - btnHeight), top1, screenWidth, bottom1);
//                        }
//                    }
//                    break;
                }
                return false;
            }
        });

view指的是布局

第二种实现方法

xml布局

<com.ui.view.DragFrameLayout
        android:id="@+id/becausefloat"
        android:layout_width="fill_parent"
        android:layout_height="0.0dp"
        android:layout_gravity="center_vertical"
        android:layout_weight="1" >

        <FrameLayout
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />

        <ImageView
            android:id="@+id/dragImg"
            android:layout_width="35dp"
            android:layout_height="35dp"
            android:background="@drawable/deletestock" />
    </com.ui.view.DragFrameLayout>

自定义控件 com.ui.view.DragFrameLayout

package com.ui.view;

import com.ui.R;

import android.content.Context;
import android.graphics.Rect;
import android.location.Location;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.FrameLayout;

public class DragFrameLayout extends FrameLayout {

    private View view;

    private int width, heigh;

    private int screenWid, screenHei;

    private boolean isClickDrag = false;

    private boolean isTouchDrag = false;

    private float startX, startY;

    private CheckClick checkClick = new CheckClick();

    private DragImageClickListener dragImageListener;

    public DragImageClickListener getDragImageListener() {
        return dragImageListener;
    }

    public void setDragImageListener(DragImageClickListener dragImageListener) {
        this.dragImageListener = dragImageListener;
    }

    public interface DragImageClickListener {
        public abstract void onClick();
    }

    private class CheckClick implements Runnable {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            isClickDrag = false;
            Log.i("drag", "=====checkTap====");
        }

    }

    public DragFrameLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
    }

    public DragFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    public void dragInit(View view) {
        screenWid = getWidth();
        screenHei = getHeight();
        width = view.getWidth();
        heigh = view.getHeight();
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        // TODO Auto-generated method stub
        switch (ev.getAction()) {

        case MotionEvent.ACTION_DOWN:
            float x = ev.getX();
            float y = ev.getY();
            Rect frame = new Rect();
            if (view == null) {
                view = findViewById(R.id.dragImg);
                dragInit(view);
            }
            view.getHitRect(frame);
            if (frame.contains((int) (x), (int) (y))) {

                isTouchDrag = true;
                startX = x;
                startY = y;
                return true;
            }
            break;

        }
        return false;
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right,
            int bottom) {

        super.onLayout(changed, left, top, right, bottom);

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        float x = event.getX();
        float y = event.getY();
        Rect frame = new Rect();

        switch (event.getAction()) {

        case MotionEvent.ACTION_DOWN:

            view.getHitRect(frame);
            if (frame.contains((int) (x), (int) (y))) {
                startX = x;
                startY = y;
                isTouchDrag = true;
                isClickDrag = true;
                postDelayed(checkClick, ViewConfiguration.getTapTimeout());
            }
            break;
        case MotionEvent.ACTION_MOVE:

            float distanX = Math.abs(x - startX);
            float distanY = Math.abs(y - startY);

            if (Math.sqrt(distanY * distanY + distanX * distanX) > 10) {
                isClickDrag = false;
            }
            move(x, y);
            break;

        case MotionEvent.ACTION_CANCEL:
            isClickDrag = false;
            isTouchDrag = false;
            break;
        case MotionEvent.ACTION_UP:
            if (isClickDrag == true) {
                dragImageListener.onClick();
                removeCallbacks(checkClick);
            }
            isClickDrag = false;
            isTouchDrag = false;

            // 这段是把控件吸附四周
//            if (x > width && x < screenWid - width && y > heigh
//                    && y < screenHei -  heigh) {
//                int minType = minDIstance(x, y);
//                Log.i("tags", screenHei + "==mintype=" + minType);
//                switch (minType) {
//                case LEFT:
//                    x = width;
//                    break;
//                case RIGHT:
//                    x = screenWid - width;
//                    break;
//                case TOP:
//                    y = heigh;
//                    break;
//                case BOTTOM:
//                    y = screenHei - heigh;
//                    break;
//                default:
//                    break;
//                }
//                move(x, y);
//            }
            break;
        case MotionEvent.ACTION_OUTSIDE:
            isClickDrag = false;
            isTouchDrag = false;
            break;
        }
        return true;
    }

    private final static int LEFT = 1;
    private final static int RIGHT = 2;
    private final static int TOP = 3;
    private final static int BOTTOM = 4;

    private int minDIstance(float x, float y) {
        Log.i("tags", "x=" + x + "==y=" + y);
        boolean left, top;

        if (x <= (screenWid - x)) {
            left = true;
        } else {
            left = false;
        }
        if (y <= (screenHei - y)) {
            top = true;
        } else {
            top = false;
        }
        
        if(left&&top){
            if(x<=y){
                return LEFT;
            }else{
                return TOP;
            }
        }
        if(left&&(!top)){
            if(x<=(screenHei-y)){
                return LEFT;
            }else{
                return BOTTOM;
            }
        }
        
        if((!left)&top){
            if((screenWid-x)<= y){
                return RIGHT;
            }else{
                return TOP;
            }
        }
        
        if((!left)&(!top)){
            if((screenWid-x)<= (screenHei-y)){
                return RIGHT;
            }else{
                return BOTTOM;
            }
        }
        return 0;

    }

    private void move(float x, float y) {
        int left = (int) (x - width / 2);
        int top = (int) (y - heigh / 2);
        if (left <= 0)
            left = 0;
        if (top <= 0)
            top = 0;

        if (left > screenWid - width)
            left = screenWid - width;
        if (top > screenHei - heigh)
            top = screenHei - heigh;

        FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) view
                .getLayoutParams();

        params.setMargins(left, top, (screenWid - left - width), (screenHei
                - top - heigh));

        view.setLayoutParams(params);
        requestLayout();
    }

    public double getDistance(double lat1, double lon1, double lat2, double lon2) {
        float[] results = new float[1];
        Location.distanceBetween(lat1, lon1, lat2, lon2, results);
        return results[0];
    }

}

Activity调用方法

        dragImg = (ImageView)findViewById(R.id.dragImg);
        frameLayout = (DragFrameLayout)findViewById(R.id.becausefloat);
        frameLayout.setDragImageListener(new DragImageClickListener() {

            private boolean isDaix;

            @Override
            public void onClick() {
                // TODO Auto-generated method stub
                if (isDaix) {
                    dragImg.setBackgroundResource(R.drawable.deletestock);
                    isDaix = false;
                } else {
                    dragImg.setBackgroundResource(R.drawable.addstock);
                    isDaix = true;
                }
                Toast.makeText(MainActivity.this, "点击",
                        Toast.LENGTH_LONG).show();
            }
        });
原文地址:https://www.cnblogs.com/zhujiabin/p/9172735.html