如何使固定布局控制区域与FrameLayout和ImageView一起工作



我对ADT和Eclipse中的Layout支持有点失望。又是摇摆舞了。基本上,我试图实现一个简单的布局,如下所示:RelativeLayout

+----------------+
|                |
| FrameLayout    |
|    ImageView   |
|                |
|                |
|                |
+----------------+
| LinearLayout   |
|    TextView    |
|    Buttons     |
+----------------+

RelativeLayout和FrameLayout与ImageView一起用于我编写的一些平移/缩放侦听器支持。

我遇到的问题是,无论我尝试什么,LinearLayout(底部控件)都不会在窗口底部显示。我将粘贴下面的内容。请注意,FieldView是ImageView的扩展。图像显示良好,它是LinearLayout,希望显示在FrameLayout的顶部。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fieldcontainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
android:orientation="vertical" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.test.FieldView
android:id="@+id/field"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
<LinearLayout
android:id="@+id/controls"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<Button
android:id="@+id/buttonAddNode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add node" />
<TextView
android:id="@+id/textViewNodeInfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>
</RelativeLayout>

提前谢谢你的建议。也许我在以前的尝试中误用了RelativeLayout参数。

更新感谢您的快速响应!我无法用下面的代码发表评论,所以这里是我尝试过的更新:

<FrameLayout
...
android:layout_above="@+id/controls">

之前,我在运行时得到以下异常:

Unable to start activity ComponentInfo{com.test.MainActivity}:
java.lang.ClassCastException: android.widget.LinearLayout

引发异常的行在我的MainActivity.OnCreate():中

view = (FieldView) findViewById(R.id.field);

添加layout_below似乎导致ID不匹配?查找R.id.field会返回错误LinearLayout的id,我自然无法投射。

请注意,如果没有上面的layout_ave,这就不会有任何问题,只是一个坏的布局。同样,FieldView只是ImageView的扩展。我把我的触听器和其他一些东西放在那里。

您只需将其全部封装在一个相对布局中,并使用将线性布局锚定到底部。android:layout_alignParentBottom="true"

为了防止控件被上面的东西过度运行,请使用android:layout_above="@id/controls"将它们布置在上面。

类似:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fieldcontainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false" >
<!-- Your other stuff -->
<LinearLayout
android:id="@+id/controls"
android:layout_width="match_parent"
android:layout_height="wrap_contgnt"
android:orientation="horizontal"
android:layout_alignParentBottom="true">
<!-- Your control stuff -->
</linearlayout>
</relativelayout>

请注意,您必须定义一个id(@+),然后才能简单地引用(@)。因此,您可以将控件视图移动到XML文件中,然后再执行其他操作,或者在第一个位置引用中使用"@+",然后在视图定义中使用@。

所以你会有android:layout_above="@+id/controls",然后另一行是android:id="@id/controls"

除非你改变了布局,否则改变布局不会对id在其中的存在产生影响。

android:layout_alignParentBottom="true"属性添加到布局中的LinearLayout。如果你想让FrameLayout不在LinearLayout之下,那么你的布局应该是这样的:

<RelativeLayout>
<LinearLayout  android:id="@+id/ll" android:layout_alignParentBottom="true" />
<FrameLayout android:layout_above="@id/ll" android:layout_alignParentTop="true"/>
</RelativeLayout>

您使用的是RelativeLayout,但没有使用它的任何属性来控制定位。

正如您所拥有的,您还可以使用垂直的LinearLayout。您还将FrameLayout和LinearLayout的高度设置为match_parent,这意味着您已将布置这些视图组的所有责任移交给父视图RelativeLayout。

当安卓布局时,它会进行两次自上而下的传球。首先,父母问孩子们想要多大。父母会把自己的尺寸传给孩子们。因此,FrameLayout和LinearLayout中的每一个都会说它们希望与父对象的大小相同。RelativeLayout没有规则来确定这些控件应该如何相互关联,因此考虑到控件的内容,将尽量使每个控件尽可能大。当父对象告诉每个子对象使自己有多大并渲染布局时,第二个过程是自上而下的。

所以,为了解决你的问题,我会使用两种方法中的一种(有更多的方法,但对于这样的简单布局,你不应该需要它们)。

  • 将RelativeLayout与layout_below一起使用,可以强制LinearLayout始终位于FrameLayout下方,无论大小如何,也可以使用各种父对齐属性中的任何一个。

  • 为了获得更精确的控制,请使用具有布局权重的LinearLayout来定位每个子项并精确调整其大小。如果采用这种方法,请记住将高度设置为0dip,并使用视图"支柱"进行定位。

我个人更喜欢使用LLs,因为我发现它们坚如磐石,很容易获得精确的布局大小和定位(尽管我有时不得不扩展它们,并破坏它们的onMeasure()方法,但这是一个Android碎片问题,与此无关)。

android:layout_weight是什么意思?

最新更新