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

发布于 2024-11-11 15:42:38 字数 109 浏览 4 评论 0 原文

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

〆一缕阳光ご 2024-11-18 15:42:38

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文