安卓可拖动控件图标

这个可拖动的图标写的比较简单,当时产品给的需求是放一个小icon,当做广告,在4个主页面都可以显示拖动

所以自定义的时候就直接继承了ImageView,下面直接上代码吧,要注意的是,获取屏幕高度的时候要减去状态栏的高度

package com.example.myapplication;

import android.annotation.SuppressLint;
import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.WindowManager;
import android.widget.ImageView;


import java.lang.reflect.Field;

/**
 * author: whp
 * date:   2018/5/15
 *
 * @author 99057
 */
@SuppressLint("AppCompatCustomView")
public class CustomDragView extends ImageView {
    private int width;
    private int height;
    private int screenWidth;
    private int screenHeight;
    private float downX;
    private float downY;
    private Context mContext;
    /**
     * 是否拖动
     */
    private boolean isDrag = false;

    public CustomDragView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = getMeasuredWidth();
        height = getMeasuredHeight();
        screenWidth = getScreenWidth(mContext);
        screenHeight = getScreenHeight(mContext) - getStatusBarHeight(mContext);
    }

    public boolean isDrag() {
        return isDrag;
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        if (this.isEnabled()) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    isDrag = false;
                    downX = event.getX();
                    downY = event.getY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    final float xDistance = event.getX() - downX;
                    final float yDistance = event.getY() - downY;
                    int l, r, t, b;
                    //当水平或者垂直滑动距离大于10,才算拖动事件
                    if (Math.abs(xDistance) > 10 || Math.abs(yDistance) > 10) {
                        isDrag = true;
                        l = (int) (getLeft() + xDistance);
                        r = l + width;
                        t = (int) (getTop() + yDistance);
                        b = t + height;
                        if (l < 0) {
                            l = 0;
                            r = l + width;
                        } else if (r > screenWidth) {
                            r = screenWidth;
                            l = r - width;
                        }
                        if (t < 0) {
                            t = 0;
                            b = t + height;
                        } else if (b > screenHeight) {
                            b = screenHeight;
                            t = b - height;
                        }

                        this.layout(l, t, r, b);
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    setPressed(false);
                    break;
                case MotionEvent.ACTION_CANCEL:
                    setPressed(false);
                    break;
                default:
                    break;
            }
            return true;
        }
        return false;
    }

    /**
     * 获取屏幕的宽
     *
     * @param context
     * @return
     */
    public static int getScreenWidth(Context context) {
        DisplayMetrics dm = new DisplayMetrics();
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        windowManager.getDefaultDisplay().getMetrics(dm);
        return dm.widthPixels;
    }

    /**
     * 获取屏幕的高
     *
     * @param context
     * @return
     */
    public static int getScreenHeight(Context context) {
        DisplayMetrics dm = new DisplayMetrics();
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        windowManager.getDefaultDisplay().getMetrics(dm);
        return dm.heightPixels;
    }

    /**
     * 获取状态栏高度
     *
     * @param context
     * @return
     */
    private int getStatusBarHeight(Context context) {
        Class<?> c;
        Object obj;
        Field field;
        int x, statusBarHeight = 0;
        try {
            c = Class.forName("com.android.internal.R$dimen");
            obj = c.newInstance();
            field = c.getField("status_bar_height");
            x = Integer.parseInt(field.get(obj).toString());
            statusBarHeight = context.getResources().getDimensionPixelSize(x);
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return statusBarHeight;
    }


}

 

 

package com.example.myapplication;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.Toast;

import java.lang.reflect.Field;

public class MainActivity extends AppCompatActivity implements View.OnTouchListener {

    private CustomDragView mCustomDragView;
    private RelativeLayout mRootLayout;
    private int xDelta;
    private int yDelta;
    private float mDownX;
    private float mDownY;
    private int mScreenWidth;
    private int mScreenHeight;


    @SuppressLint("ClickableViewAccessibility")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mCustomDragView = findViewById(R.id.CustomDragView);
        mRootLayout = findViewById(R.id.rootLayout);
        mScreenWidth = CustomDragView.getScreenWidth(this);
        mScreenHeight = CustomDragView.getScreenHeight(this);


        mCustomDragView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "点击事件", Toast.LENGTH_LONG).show();
            }
        });
        mCustomDragView.setOnTouchListener(this);
    }

    @Override
    public boolean onTouch(View view, MotionEvent event) {
        final int x = (int) event.getRawX();
        final int y = (int) event.getRawY();
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                mDownX = event.getRawX();
                mDownY = event.getRawY();
                RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) view
                        .getLayoutParams();
                xDelta = x - params.leftMargin;
                yDelta = y - params.topMargin;
                break;
            case MotionEvent.ACTION_MOVE:
                RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view
                        .getLayoutParams();
                int xDistance = x - xDelta;
                int yDistance = y - yDelta;
                int imgWidth = mCustomDragView.getWidth();
                int imgHeight = mCustomDragView.getHeight();
                if (xDistance < 0) {
                    xDistance = 0;
                }
                if (yDistance < 0) {
                    yDistance = 0;
                }
                if ((xDistance + imgWidth) > mScreenWidth) {
                    xDistance = mScreenWidth - imgWidth;
                }
                if ((yDistance + imgHeight) > mScreenHeight) {
                    yDistance = mScreenHeight - imgHeight;
                }

                layoutParams.leftMargin = xDistance;
                layoutParams.topMargin = yDistance;

                view.setLayoutParams(layoutParams);
                break;
            case MotionEvent.ACTION_UP:
                //检测移动的距离,如果很小认为是点击事件
                if (Math.abs(event.getRawX() - mDownX) < 10 && Math.abs(event.getRawY() - mDownY) < 10) {
                    try {
                        //响应点击事件,通过反射获取mListenerInfo实例
                        Field field = View.class.getDeclaredField("mListenerInfo");
                        field.setAccessible(true);
                        //获取mListenerInfo里面的mOnClickListener
                        Object object = field.get(view);
                        field = object.getClass().getDeclaredField("mOnClickListener");
                        field.setAccessible(true);
                        object = field.get(object);
                        //点击事件
                        if (object != null && object instanceof View.OnClickListener) {
                            ((View.OnClickListener) object).onClick(view);
                        }
                    } catch (Exception e) {
                        Log.d("onTouch==>", e.getMessage());
                    }
                }
                break;
            default:
                break;
        }
        mRootLayout.invalidate();
        return true;
    }
}

 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/rootLayout"
    tools:context="com.example.myapplication.MainActivity">

    <com.example.myapplication.CustomDragView
        android:id="@+id/CustomDragView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher" />

</RelativeLayout>

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值