我们主要是通过控件的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;
}}
关于虚拟键的问题,这三个方法都写上