开发者

How to determine non-fullscreen activity window size on startup?

I have a non-fullscreen activity (the system notification bar is visible). In order to create my view hierarchy I need to know the size of the the piece of screen that my activity occupates (that is the size of the display detracted by the size of the system notification bar). How can I determine that within the开发者_开发百科 onCreate method?


This is not known in onCreate(). What you should do is participate correctly in the view hierarchy layout process. You do NOT do your layout in onCreate(), you do it in the view hierarchy with the layout managers. If you have some special layout that you can't implement with the standard layout managers, it is pretty easy to write your own -- just implement a ViewGroup subclasses that does the appropriate things in onMeasure() and onLayout().

This is the only correct way to do this because if the available display size changes, your onCreate() will not run again but the view hierarchy will go through its layout process to determine the correct new place to position its views. There are an arbitrary number of reasons why the screen size could change on you like this -- for example on the Xoom tablet when it is plugged in to an HDMI output it makes the system bar larger so that when it mirrors its display to a 720p screen the bottom of applications do not get chopped off.

For example, here's a layout manager that implements a simple version of FrameLayout:

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    final int childCount = getChildCount();
    for (int i = 0; i < childCount; i++) {
        final View child = getChildAt(i);

        int childRight = getPaddingLeft()
                + child.getMeasuredWidth() - getPaddingRight();
        int childBottom = getPaddingTop()
                + child.getMeasuredHeight() - getPaddingBottom();
        child.layout(getPaddingLeft(), getPaddingTop(), childRight, childBottom);
    }
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    final int count = getChildCount();

    int maxHeight = 0;
    int maxWidth = 0;
    int measuredChildState = 0;

    // Find rightmost and bottom-most child
    for (int i = 0; i < count; i++) {
        final View child = getChildAt(i);
        if (child.getVisibility() != GONE) {
            measureChild(child, widthMeasureSpec, heightMeasureSpec);
            maxWidth = Math.max(maxWidth, child.getMeasuredWidth());
            maxHeight = Math.max(maxHeight, child.getMeasuredHeight());
            measuredChildState = combineMeasuredStates(measuredChildState,
                    child.getMeasuredState());
        }
    }

    // Account for padding too
    maxWidth += getPaddingLeft() + getPaddingRight();
    maxHeight += getPaddingTop + mPaddingBottom();

    // Check against our minimum height and width
    maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
    maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());

    setMeasuredDimension(resolveSizeAndState(maxWidth,
                    widthMeasureSpec, measuredChildState),
            resolveSizeAndState(maxHeight, heightMeasureSpec,
                    measuredChildState<<MEASURED_HEIGHT_STATE_SHIFT));
}

Note the last line there is the best way to implement measurement starting with API 11, since it allows you to propagate states like "layout does not fit" up which can be used to do things like determine the size that dialogs need to be. You likely don't need to worry about such things, in which case you can simplify it to a form that works on all versions of the platform:

    setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
            resolveSize(maxHeight, heightMeasureSpec));

There is also an API demo for a slightly more complicated layout:

http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/animation/FixedGridLayout.html


I can't test it now, but I believe

int h = getWindow().getAttributes().height;

int w = getWindow().getAttributes().width;

API docs:

  • http://developer.android.com/reference/android/app/Activity.html#getWindow%28%29

  • http://developer.android.com/reference/android/view/Window.html#getAttributes%28%29

  • http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html

  • http://developer.android.com/reference/android/view/ViewGroup.LayoutParams.html#height

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜