Android:如何实全屏现拖动View

最近在做自定义View,有一个需求是需要自定义一个View实现全屏拖动。刚好研究了下,发现还是蛮简单的,在这里总结下大概的思路,直接上代码:

1、编写一个 main.xml 布局文件

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/framelayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="60dp"
        android:layout_height="match_parent"
        android:background="@color/colorPrimary">

        <ImageView
            android:id="@+id/imageview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/icon_a" />

    </LinearLayout>

    <FrameLayout
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginStart="60dp">

    </FrameLayout>

</FrameLayout>

2、自定义 TouchView,为了以后的扩展

 


public class TouchView extends View {
    private static final String TAG = "TouchView";

    /**
     * 记录X轴最后位置
     */
    int lastX = 0;
    /**
     * 记录Y轴最后位置
     */
    int lastY = 0;
    /**
     * 记录Action_Down - X轴位置
     */
    int downX = 0;
    /**
     * 记录Action_Down - Y轴位置
     */
    int downY = 0;
    /**
     * 记录Action_Down 时间
     */
    long lastDownInMills;

    final int DEFAULT_LIMITLEFT = 0;
    final int DEFAULT_LIMITTOP = 0;

    int limitLeft;
    int limitTop;
    int limitRight;
    int limitBottom;

    int screenWidth;
    int screenHeight;

    private OnClickListener l;

    public TouchView(Context context) {
        super(context);
    }

    public TouchView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        screenWidth = metrics.widthPixels;
        screenHeight = metrics.heightPixels;
        setLimitAuto();
    }

    public TouchView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    /**
     * 自适应边界
     */
    private void setLimitAuto() {
        setLimitAuto(null);
    }

    /**
     * 根据parentView自适应边界
     *
     * @param parentView
     */
    public void setLimitAuto(ViewGroup parentView) {
        if (parentView == null) {
            this.limitLeft = DEFAULT_LIMITLEFT;
            this.limitTop = DEFAULT_LIMITTOP;
            this.limitRight = screenWidth;
            this.limitBottom = screenHeight;
        } else {
            this.limitLeft = parentView.getLeft();
            this.limitTop = parentView.getTop();
            this.limitRight = parentView.getRight();
            this.limitBottom = parentView.getBottom();
        }
    }

    /**
     * 设定自定义边界
     *
     * @param limitLeft
     * @param limitTop
     * @param limitRight
     * @param limitBottom
     */
    public void setLimitParams(int limitLeft, int limitTop, int limitRight, int limitBottom) {
        this.limitLeft = limitLeft;
        this.limitTop = limitTop;
        this.limitRight = limitRight;
        this.limitBottom = limitBottom;
    }

    @Override
    public void setOnClickListener(@Nullable OnClickListener l) {
        this.l = l;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
       // System.out.println(event.getRawX());
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                lastDownInMills = System.currentTimeMillis();
                lastX = (int) event.getRawX();
                lastY = (int) event.getRawY();
                downX = (int) event.getRawX();
                downY = (int) event.getRawY();
                break;
            case MotionEvent.ACTION_MOVE:
                int dx = (int) event.getRawX() - lastX;
                int dy = (int) event.getRawY() - lastY;
                int left = getLeft() + dx;
                int top = getTop() + dy;
                int right = getRight() + dx;
                int bottom = getBottom() + dy;

                if (left < limitLeft) {
                    left = limitLeft;
                    right = left + getWidth();
                }
                if (top < limitTop) {
                    top = limitTop;
                    bottom = top + getHeight();
                }
                if (right > limitRight) {
                    right = limitRight;
                    left = limitRight - getWidth();
                }
                if (bottom > limitBottom) {
                    bottom = limitBottom;
                    top = limitBottom - getHeight();
                }

                layout(left, top, right, bottom);
                lastX = (int) event.getRawX();
                lastY = (int) event.getRawY();
                break;
            case MotionEvent.ACTION_UP:
                dx = (int) event.getRawX() - downX;
                dy = (int) event.getRawY() - downY;
                if (dx + dy == 0 && System.currentTimeMillis() - lastDownInMills < 500) {
                    //TODO x + y移动距离小于2px 且 触碰时间小于500ms 触发点击事件
                    if (l != null) {
                        l.onClick(this);
                    }
                }
                onLastMovePosition.onLastMovePosition((int) event.getRawX(), (int) event.getRawY());
                break;
        }
        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }

    public void setOnLastMovePosition(OnMovePositionListener onLastMovePosition) {
        this.onLastMovePosition = onLastMovePosition;
    }

    private OnMovePositionListener onLastMovePosition;

    public interface OnMovePositionListener {
        void onLastMovePosition(int x, int y);
    }

}

3、直接调用,就可以了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值