如何在启动时确定非全屏活动窗口大小?

时间:2011-06-03 15:38:49

标签: android size startup

我有一个非全屏活动(系统通知栏可见)。为了创建我的视图层次结构,我需要知道我的活动占用的屏幕大小(即显示器的大小减去了系统通知栏的大小)。如何在onCreate方法中确定?

2 个答案:

答案 0 :(得分:4)

这在onCreate()中是未知的。您应该做的是正确参与视图层次结构布局过程。您不在onCreate()中进行布局,而是使用布局管理器在视图层次结构中进行布局。如果你有一些你无法使用标准布局管理器实现的特殊布局,那么编写自己的布局很简单 - 只需实现一个ViewGroup子类,它在onMeasure()和onLayout()中执行相应的操作。

这是唯一正确的方法,因为如果可用的显示大小发生更改,则onCreate()将不会再次运行,但视图层次结构将通过其布局过程来确定正确的新位置来定位其视图。屏幕尺寸可能因此而改变有多种原因 - 例如,当Xoom平板电脑插入HDMI输出时,它会使系统条变大,以便当它将显示器镜像到720p时屏幕应用程序的底部不会被切断。

例如,这是一个实现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));
}

注意最后一行是从API 11开始实现测量的最佳方法,因为它允许您传播“布局不适合”等状态,可以用来确定对话框需要的大小是。您可能不需要担心这些事情,在这种情况下,您可以将其简化为适用于所有平台版本的表单:

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

还有一个API演示,用于稍微复杂的布局:

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

答案 1 :(得分:0)