Android获取Menu的绘制位置、状态栏和标题栏的高度

Android获取Menu的绘制位置

  • 第一种方式,使用Compat兼容包,通过setActionView
1
2
3
4
5
6
7
public boolean onCreateOptionsMenu(final Menu menu) {
this.menu = menu;
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_activity_actions, menu);
final ImageView iv = new ImageView(this);
iv.setImageResource(R.drawable.home_history_btn_selector);
MenuItemCompat.setActionView(menu.findItem(R.id.action_history), iv);

然后通过getActionView获取到图片,进而获取位置

1
2
3
4
5
6
View view = MenuItemCompat.getActionView(menu.findItem(R.id.action_history));
if(view == null){
return;
}
int location[] = new int[2];
view.getLocationInWindow(location);

但这个方式比较坑的一点是,MenuItemCompat.setActionView后,改MenuItem不能相应点击事件了,只能通过给ImageView设置监听的方式响应事件;而且menu的响应和正常的menu样式不一样,长按效果消失。

  • 第二种方式比较简单,因为menu在Android中最终绘制为View,所以可以通过findViewById的方式获取到对应的View.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {

    View view = findViewById(R.id.action_history);
    if (view != null) {
    int[] location = new int[2];
    view.getLocationInWindow(location);
    Log.d(TAG, "x=" + location[0] + " y=" + location[1]);
    getWindow().getDecorView().getViewTreeObserver().removeGlobalOnLayoutListener(this);
    }
    });

获取状态栏的高度

1
2
3
Rect frame = new Rect();
getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
int statusBarHeight = frame.top;

获取标题栏的高度

1
2
3
int contentTop = getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
//statusBarHeight是上面所求的状态栏的高度
int titleBarHeight = contentTop - statusBarHeight; (statusBarHeight见上)