获取actionBar 的高度,状态栏高度,view.getLocationxxx()的总结

来源:互联网 发布:天刀最丑捏脸数据下载 编辑:程序博客网 时间:2024/06/07 08:46

最近在写控件的时候,需要获取view 距离顶部的位置,一般view.getLocationOnScreen(p) 但是这个是全屏的获取坐标,需要减去actionbar 的高度和状态栏的高度,有时候会存在偏差,直接view.getTop()就可以直接获取到准确的值,所以总结记录下。


1.获取actionBar 的高度的方法

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();}

相关代码说明:

  • 1.context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)

// 参数: 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.TypedValue.complexToDimension() /array.getDimension()

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.获取状态栏的高度:

2.1 使用getIdentifier()方法可以获各应用包下的指定资源ID。

int result = 0;int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");if (resourceId > 0) {    result = getResources().getDimensionPixelSize(resourceId);}
  • getIdentifier() 使用方法

方式一:第一个参数格式是:包名 + : + 资源文件夹名 + / +资源名;是这种格式 然后其他的可以为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;

3.获取xml中 dip对应的像素:

Float storkeWidth = TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 2, getResources().getDisplayMetrics());

4.view.getLocationInWindow(),view.getLocationOnScreen(),view.getTop()..

http://blog.csdn.net/imyfriend/article/details/8564781 学习博客的地址

注意:view.getLocationInWindow(),view.getLocationOnScreen() 都包含了状态栏的高度,上面有具体的获取的方法。
// 获取相对在它父窗口里的坐标。
View.getLeft() , View.getTop(), View.getBottom(), View.getRight()

1 0