让控件随着手指进行移动

我们主要是通过控件的OnTouchListener进行操作,移动时改变控件的位置

实现 implements View.OnTouchListener,实现其方法

记得控件img.setOnTouchListener(this);

代码中的width和height代表的是控件可移动的宽高(也就是范围)

public boolean onTouch(View v, MotionEvent event) {

    switch (v.getId()){
        //首先确定是哪个控件
        case R.id.img:
            int ea = event.getAction();
            switch(ea){
                //再判断手势
                case MotionEvent.ACTION_DOWN:
                    lastX = (int) event.getRawX();// 获取触摸事件触摸位置的原始X坐标
                    lastY = (int) event.getRawY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    int dx = (int) event.getRawX() - lastX;
                    int dy = (int) event.getRawY() - lastY;
                    int l = v.getLeft() + dx;
                    int b = v.getBottom() + dy;
                    int r = v.getRight() + dx;
                    int t = v.getTop() + dy;
                    // 下面判断移动是否超出屏幕
                    if (l < 0) {
                        l = 0;
                        r = l + v.getWidth();
                    }
                    if (t < 0) {
                        t = 0;
                        b = t + v.getHeight();
                    }
                    if (r > width) {
                        r = width;
                        l = r - v.getWidth();
                    }
                    if (b > heigth) {
                        b = heigth;
                        t = b - v.getHeight();
                    }
                    v.layout(l, t, r, b);
                    lastX = (int) event.getRawX();
                    lastY = (int) event.getRawY();
                    v.postInvalidate();
                    break;
                case MotionEvent.ACTION_UP:
                    break;
                default:
                    break;
            }
            break;
    }

    return true;

}

在我们的界面中一般从上到下是标题栏,内容显示区域,底部导航栏三部分

我们获取中间显示部分的宽高,要获取控件的宽高,我们不能在oncreat里面通过getWidth这样进行获取,会发现得到的是0,我们需要在onWindowFocusChanged方法中得到

public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);

    int navigationBarHeight = getNavigationBarHeight(this);
    heigth = shou.getHeight()-navigationBarHeight;
    width = shou.getWidth();

}

你会发现我们还减去了一个navigationBarHeight,这个高度是虚拟键的高度,当然我们也需要判断当前手机是否有虚拟键。

虚拟键高度

public static int getNavigationBarHeight(Context context) {
        int result = 0;
        if (hasNavBar(context)) {
            Resources res = context.getResources();
            int resourceId = res.getIdentifier("navigation_bar_height", "dimen", "android");
            if (resourceId > 0) {
                result = res.getDimensionPixelSize(resourceId);
            }
        }
        return result;
    }

是否有虚拟键

 public static boolean hasNavBar(Context context) {
        Resources res = context.getResources();
        int resourceId = res.getIdentifier("config_showNavigationBar", "bool", "android");
        if (resourceId != 0) {
            boolean hasNav = res.getBoolean(resourceId);
            // check override flag
String sNavBarOverride = getNavBarOverride();
            if ("1".equals(sNavBarOverride)) {
                hasNav = false;
            } else if ("0".equals(sNavBarOverride)) {
                hasNav = true;
            }
            return hasNav;
        } else { // fallback
           return !ViewConfiguration.get(context).hasPermanentMenuKey();
        }
    }

虚拟键是否重新

private static String getNavBarOverride() {
        String sNavBarOverride = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            try {
                Class c = Class.forName("android.os.SystemProperties");
                Method m = c.getDeclaredMethod("get", String.class);
                m.setAccessible(true);
                sNavBarOverride = (String) m.invoke(null, "qemu.hw.mainkeys");
            } catch (Throwable e) {
            }
        }
        return sNavBarOverride;
    }}

关于虚拟键的问题,这三个方法都写上

猜你喜欢

转载自blog.csdn.net/ZhangXuxiaoqingnian/article/details/82683908