Ita*_*ski 19 android android-layout android-relativelayout android-framelayout
RelativeLayout
当你将视图与布局的一侧(任何一侧)对齐并且在同一方向上有一个大的边距时,我注意到了一种奇怪的行为.
我有2个RelativeLayouts
,每个都包含一个简单的视图.在一个布局中,视图与顶部和左侧对齐,在另一个布局中与底部和右侧对齐:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RelativeLayout
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_marginTop="110dp"
android:layout_gravity="center"
android:background="#ff555555" >
<View
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:background="#aa8711" />
</RelativeLayout>
<RelativeLayout
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_marginBottom="110dp"
android:layout_gravity="center"
android:background="#ff555555" >
<View
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="#998877" />
</RelativeLayout>
</FrameLayout>
Run Code Online (Sandbox Code Playgroud)
它看起来像这样:
我在父对齐的每个方向上添加了130dp的边距.这意味着视图应该只在布局中部分可见.这是发生的事情:
正如您所看到的,视图现在小于原始大小,因为它被推到了布局的"墙"上.接下来我试图给出一个比布局更大的边距,所以我在对齐的方向上给了它们151dp的边距.它看起来像这样:
右下方对齐的视图现在"突破"布局,并且再次与原来的大小相同.另一方面,左上角对齐的视图也是原始大小,但完全在布局内部而不是在其外部.
我已经单独尝试了这个并且在每个排列的对齐中得到了相同的结果.
问题一:任何人都可以解释这种不一致的行为吗?
我尝试了同样的事情,这次将行为与a的行为进行比较FrameLayout
.初始设置:
并且在保证金之后:
将FrameLayout
保持在所有时间的原始大小视图和简单地让视图"退出"了.我尝试在至少应该在视图之外的视图的大小的相反方向给出负边距,RelativeLayout
并且看到与FrameLayout
默认情况下发生的行为相同的行为.
问题2:任何人都可以解释行为上的差异和相反的负边际效应吗?
为什么它只能部分可见?
我在父对齐的每个方向上添加了 130dp 的边距。这意味着视图在布局中应该仅部分可见
盒子变得越来越小,因为人们优先考虑不惜一切代价将其保留在父布局内,同时仍然应用边距。由于较小的子视图是 50dp,因此您添加了边距130dp
,它需要的总宽度是180dp
,但父视图本身只有150dp
宽度。也就是说130dp + 50dp > 150dp
,子项加上边距无法放入父项内。
这是“愚蠢的输入”,XML 解释器正在尽力呈现某些内容。它最终做出的决定是它可以改变子框的宽度并仍然遵守边距约束。或者数学上
130dp + 20dp == 150dp
Run Code Online (Sandbox Code Playgroud)
基本上,它会缩小内部框的宽度,使其能够在添加边距的50dp
情况20dp
下适合父级。如果你看一下正方形的大小,20dp
看起来就差不多了。它小了 60%。
这是解释器的聪明行为,因为随着屏幕尺寸的变化,它会遇到这样的问题,它应该始终保留与宽度约束相反的边距约束。
总之,解释器正在尽最大努力适应盒子及其父级内部的边距,为此,它正在使盒子变小。它选择在给定的宽度上保留给定的边距 - 可能是因为最顶层的父布局。
当您说“这应该部分可见”时,我假设您认为子级将渲染一半在父级边界内,一半在父级边界外,类似于 Windows 窗体开发。但事实并非如此,因为在大多数布局中它总是试图将子项保持在父项的范围内。
所做的选择也取决于最顶层的父布局,某些布局可能更愿意保留子框的宽度而不是边距,甚至将框呈现在父边界之外。
在第二种情况下:
所以我在对齐方向上给了它们 151dp 的边距。
你已经超出了解释器可以缩小图像的范围。它不能将图像缩小到负1。即
50dp + 151dp > 150dp
Run Code Online (Sandbox Code Playgroud)
它无法满足您给它的边距约束,因此行为相当不可预测。我猜测它知道它不能将两个图像及其边距保留在父级内部。所以它只是渲染一个内部和一个外部。
再说一遍,这是愚蠢的输入,解释器正在尽力呈现您想要的内容。
谁能解释行为上的差异和相反的负边际效应?
负边距将根据其父级中的布局类型执行不同的操作,并且它也是对齐的。在框架布局中,它的行为与相对布局不同。通常,如果您正在查看负布局,那么您选择了错误的父容器,并且您正在尝试破解它以使其看起来正确。
我不知道您到底想做什么,但也许您只需要稍微调整一下您的思维过程,并考虑一下试图理解您提供的 XML 的糟糕解释。
您不会是第一个对 Android 的 XML 布局完全困惑的人。在布局中嵌套布局总是令人困惑,并且行为的变化取决于许多因素,例如边距、对齐方式、宽度等。我认识的大多数人只是简单地摆弄它,直到它正确为止,并尝试不同的容器布局类型以获得正确的设计。
简而言之,避免使用边距(例如 flash 或 winform),并且不使用布局类型,而是将内容放在您想要的位置。
希望有帮助,对不起,tl;博士。
归档时间: |
|
查看次数: |
2579 次 |
最近记录: |