Android 全屏应用程序,布局按通知栏高度向下移动

Android 全屏应用程序,布局按通知栏高度向下移动,android,Android,我有一个应用程序,在屏幕底部有一个工具栏,其余的都是自定义视图(见下面的xml)。现在,当我让应用程序全屏显示时(我尝试了所有的可能性,通过编程和Manifest.xml),当它启动时,整个布局似乎向下移动了大约通知栏的高度。工具栏中的按钮仅在中间可见。有时,在几秒钟后,或者当我单击工具栏上的按钮时,所有的图标都会向上移动 我很确定,这是我的自定义视图的一个问题,因为如果我用按钮之类的东西替换它,我不会得到这种效果。我想这一定和onMeasure方法有关。我真的不知道如何实现它,我的版本如下所

我有一个应用程序,在屏幕底部有一个工具栏,其余的都是自定义视图(见下面的xml)。现在,当我让应用程序全屏显示时(我尝试了所有的可能性,通过编程和Manifest.xml),当它启动时,整个布局似乎向下移动了大约通知栏的高度。工具栏中的按钮仅在中间可见。有时,在几秒钟后,或者当我单击工具栏上的按钮时,所有的图标都会向上移动

我很确定,这是我的自定义视图的一个问题,因为如果我用按钮之类的东西替换它,我不会得到这种效果。我想这一定和onMeasure方法有关。我真的不知道如何实现它,我的版本如下所示。自定义视图用于内部绘制,因此基本上它希望尽可能大

任何帮助都将不胜感激。我已经找了好几个小时了,但还没有找到线索

layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" 
    android:orientation="vertical">
    <com.example.MyCanvasView 
        android:id="@+id/canvas" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content"
        android:layout_weight="1" 
         />
    <!-- Buttonbar -->
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingTop="4dp"
        android:orientation="horizontal"
        android:background="@android:drawable/bottom_bar"
        >
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="1"
        />
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="2"
        />
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="3"
        />
    </LinearLayout>
</LinearLayout>

设置测量值时,没有考虑模式

a的模式可以是
MeasureSpec.确切地
MeasureSpec.至多
,或
MeasureSpec.未指定
。简单地接受尺寸组件,并将测量尺寸设置为适合
的尺寸,但对于其他人来说,这通常不是正确的选择

由于您试图在此自定义视图上使用
layout\u weight
以及
wrap\u content
的高度,因此发生了以下情况:

您的自定义视图是线性布局的第一个子视图,高度为
wrap\u content
,因此
LinearLayout
会对其进行测量。由于
LinearLayout
已被
LayoutParams
告知它应该
wrap\u content
,因此它最多使用
MeasureSpec
模式和整个可用空间的大小来测量您的自定义视图

但您的自定义视图是贪婪的。它决定占用所有可用空间。本质上,您已经实现了您的度量,将
wrap\u内容
视为
match\u parent

现在已经没有空间了。下面的按钮栏会相应地进行测量,但还没有完成,有一个孩子有体重。在
线性布局中
所有正常测量完成后剩余的任何空间都将根据加权子对象的权重值在加权子对象之间划分。这不是你想要的行为


当您使用权重填充可用的垂直空间时,就像您在此布局中所做的那样,您通常希望将
布局高度设置为
0dip
。这将使
LinearLayout
跳过该子级的第一次测量过程,仅使用加权测量过程测量视图,从而为视图提供剩余的可用空间。

我找到了所述行为的原因。我已通过
onCreate()
方法中的
setFocusableInTouchMode(true)
将视图设置为可在触摸模式下聚焦。我一拆下这个,它就可以正常工作了。多亏了adamp——您对布局和测量过程的描述非常有趣


但这给我留下了一个问题,我不再收到任何按键/按钮点击:-(

您是否将应用程序或特定活动的样式设置为没有标题栏/没有通知栏的样式?我尝试了这两种方法。在清单文件中设置NoTitle.Fullscreen主题,并以编程方式设置if。这两种方法都是一样的。只要没有显示标题栏,并且通知栏消失,它就可以工作owards the top.你有没有可能发布它的屏幕截图?你是在使用模拟器还是设备?@Treebranch,我添加了屏幕截图。谢谢你的解释。这听起来合乎逻辑,但对我的问题没有帮助。你看,视图的高度是正确的,但整个窗口似乎都向下移动了。此外,当我在我的自定义视图中添加
按钮
,并设置
布局高度
布局重量
,就像在my layout.xml中一样,一切都很好。很有趣!我可以在姜饼上的一个小测试应用程序中重现这一点。我下周必须检查一下,但您可能发现了一个框架错误。您想用key做什么/按钮事件?这可能是可以解决的。嗯,几乎让我有点骄傲,因为我可能发现了一个bug:-)事实上,我太愚蠢了,我尝试在这个视图中获取关键事件。我只是想听到后退按钮来做一些撤销。我只是将其移动到onKeyEvent()实际活动的方法,就是这样:-)太好了,很高兴你们能找到一个适合你们的应用程序的解决方案
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int width = MeasureSpec.getSize(widthMeasureSpec);
    int height = MeasureSpec.getSize(heightMeasureSpec);
    setMeasuredDimension(width, height);
}