最近在写控件的时候,需要获取view 距离顶部的位置,一般view.getLocationOnScreen(p) 但是这个是全屏的获取坐标,需要减去actionbar 的高度和状态栏的高度,有时候会存在偏差,直接view.getTop()就可以直接获取到准确的值,所以总结记录下。
int actionBarHeight = 0;
TypedValue tv = new TypedValue();
if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
//方法一
actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics());
Log.d("PopupListView","tv.data="+tv.data+",actionBarHeight="+actionBarHeight);
//方法二
int[] attribute = new int[] { android.R.attr.actionBarSize };
TypedArray array = context.obtainStyledAttributes(tv.resourceId, attribute);
int actionBarHeight1 = array.getDimensionPixelSize(0 /* index */, -1 /* default size */);
array.recycle();
//方法三
TypedArray actionbarSizeTypedArray = context.obtainStyledAttributes(new int[] { android.R.attr.actionBarSize });
float actionBarHeight2 = actionbarSizeTypedArray.getDimension(0, 0);
actionbarSizeTypedArray.recycle();
}
相关代码说明:
// 参数: int resid, TypedValue outValue, boolean resolveRefs
context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)
方法说明:取回主题里面的属性的具体的值(例如:android.R.attr.actionBarSize),内容的值最后会被填充到 typeValue 里面,
如果 resolveRefs 为true 资源将会被引用,为 false outValue可能是TYPE_REFERENCE,在任何情况下都不会是TYPE_ATTRIBUTE。
返回true 说明 属性(attribute)被找到了,而且typeValue (tv)是有效的.
返回false说明 属性没有被找到,或者typeValue (tv)无效(不正确).
2.1 TypedValue.complexToDimension() / getDimension()是基于当前DisplayMetrics进行转换,获取指定资源id对应的尺寸。文档里并没说这里返回的就是像素,要注意这个函数的返回值是float,像素肯定是int。
2.2 TypedValue.complexToDimensionPixelSize()/getDimensionPixelSize()与getDimension()功能类似,
不同的是将结果转换为int,并且小数部分四舍五入。
2.3 TypedValue.complexToDimensionPixelOffset()/getDimensionPixelOffset()与getDimension()功能类似,
不同的是将结果转换为int,并且偏移转换(offset conversion,函数命名中的offset是这个意思)是直接截断小数位,即取整(其实就是把float强制转化为int)。
2.1 使用getIdentifier()方法可以获各应用包下的指定资源ID。
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
方式一:第一个参数格式是:包名 + : + 资源文件夹名 + / +资源名;是这种格式 然后其他的可以为null
int indentify = getResources().getIdentifier(com.xxx.xxx:drawable/icon",null,null); if(indentify>0){ icon = resources.getDrawable(indentify); }
方式二: 第一个参数为ID名,第二个为资源属性是ID或者是Drawable,第三个为包名。
Resources resources = context.getResources();
int indentify= getResources().getIdentifier("icon", "drawable", "com.xxx.xxx");
2.2 大牛用反射写的
private int getStatusBarHeight(){
Class<?> c;
Object obj ;
Field field ;
int x, sbar;
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());
sbar = getResources().getDimensionPixelSize(x);
} catch(Exception e1) {
sbar = 0;
Log.d("PopupListView","getStatusBarHeight error ="+e1);
e1.printStackTrace();
}
return sbar;
Float storkeWidth = TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 2, getResources().getDisplayMetrics());
http://blog.csdn.net/imyfriend/article/details/8564781 学习博客的地址
注意:view.getLocationInWindow(),view.getLocationOnScreen() 都包含了状态栏的高度,上面有具体的获取的方法。
// 获取相对在它父窗口里的坐标。
View.getLeft() , View.getTop(), View.getBottom(), View.getRight()