Android 如果同级视图较大,则匹配\u父级;如果同级视图较小,则包装\u内容
我在一个布局中有两个视图。 我将分别称它们为Android 如果同级视图较大,则匹配\u父级;如果同级视图较小,则包装\u内容,android,android-layout,Android,Android Layout,我在一个布局中有两个视图。 我将分别称它们为视图A和视图B ┌──────┐ │┌─┐┌─┐│ ││A││B││ │└─┘└─┘│ └──────┘ 父布局(包括视图A和视图B)的高度为包裹内容 这里,视图B的高度是包裹内容。也就是说,其高度可以根据其内容进行更改 我想做的是 如果查看A的内容比查看B的内容短,则将查看A的高度设置为查看B的高度 如果查看A的内容高于查看B的内容,则将查看A的高度设置为其自身内容的高度 所以 ① 如果视图B的内容更高,则视图A的高度设置为视图B的高度
视图A
和视图B
┌──────┐
│┌─┐┌─┐│
││A││B││
│└─┘└─┘│
└──────┘
父布局(包括视图A
和视图B
)的高度为包裹内容
这里,视图B
的高度是包裹内容
。也就是说,其高度可以根据其内容进行更改
我想做的是
查看A
的内容比查看B
的内容短,则将查看A
的高度设置为查看B
的高度查看A
的内容高于查看B
的内容,则将查看A
的高度设置为其自身内容的高度 ┌──────┐ ┌──────┐
│┌─┐┌─┐│ │┌─┐┌─┐│
││ ││ ││ ││A││ ││
I want ││A││B││, not │└─┘│B││.
││ ││ ││ │ │ ││
│└─┘└─┘│ │ └─┘│
└──────┘ └──────┘
┌──────┐ ┌──────┐
│┌─┐┌─┐│ │┌─┐┌─┐│
││ ││B││ ││A││B││
I want ││A│└─┘│, not │└─┘└─┘│.
││ │ │ └──────┘
│└─┘ │
└──────┘
② 如果视图B
的内容较短,则视图A
的高度为视图A
自身的高度
┌──────┐ ┌──────┐
│┌─┐┌─┐│ │┌─┐┌─┐│
││ ││ ││ ││A││ ││
I want ││A││B││, not │└─┘│B││.
││ ││ ││ │ │ ││
│└─┘└─┘│ │ └─┘│
└──────┘ └──────┘
┌──────┐ ┌──────┐
│┌─┐┌─┐│ │┌─┐┌─┐│
││ ││B││ ││A││B││
I want ││A│└─┘│, not │└─┘└─┘│.
││ │ │ └──────┘
│└─┘ │
└──────┘
如果父对象是线性布局(水平)
,则将查看A
的高度设置为包裹内容将违反案例1,将查看A
的高度设置为匹配父对象将违反案例2
如果父对象是RelativeLayout
,则将视图A
设置为对齐其父对象的顶部和底部将违反RelativeLayout
的条件:
请注意,RelativeLayout的大小与其子对象的位置之间不能存在循环依赖关系。例如,不能将高度设置为“包裹内容”的RelativeLayout和将子项设置为“对齐父项”的RelativeLayout。
如何解决此问题?您需要使用布局参数以编程方式设置视图的尺寸。假设您正在使用线性布局来保存视图,您将执行以下操作:
//the views are called a and b
LinearLayout.LayoutParams aParams = a.getLayoutParams();
LinearLayout.LayoutParams bParams = b.getLayoutParams();
int aWidth = aParams.width;
int aHeight = aParams.height;
int bWidth = bParams.width;
int bHeight = bParams.height;
if (aHeight >= bHeight) {
// do nothing
}
else {
a.setLayoutParams(new LinearLayout.LayoutParams(aWidth, bHeight));
}
当您设置它们的高度时,在进行此修改之前,最初将它们保留为xml中的wrap_内容。有不同的方法来实现这一点,例如,创建您自己的自定义视图组
,可能基于水平线性布局
。然而,我认为最简单的解决方案是在运行时动态设置需求
考虑以下布局,在水平线性布局中只有两个TextView
s:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#f00"
android:padding="10dp" >
<TextView
android:id="@+id/first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#0f0"
android:padding="5dp"
android:text="One line" />
<TextView
android:id="@+id/second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00f"
android:padding="5dp"
android:text="Two\nlines"
android:textColor="#fff" />
</LinearLayout>
“诀窍”是发布到视图的队列中,确保在子对象被测量并具有有效高度之前不会执行逻辑。对于需求2,只有在第二个视图更高时,第一个视图的高度才需要更改,这正是run()
方法中的零件所做的。这可以很容易地解决,只需使用axml即可
将父布局的高度保留为包裹内容,并将每个子视图的高度设置为匹配父视图。这将导致父布局的高度环绕到最高的子视图,并且每个子视图的高度延伸到父视图
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="text" />
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="More\ntext" />
</LinearLayout>
难道没有一种xml方法可以做到这一点吗?否则,我将不得不在适配器中执行此操作,因为我想在动态填充列表中执行类似操作。@BartBurg:自定义ViewGroup
可能是最理想的解决方案。扩展LinearLayout
将是一个良好的开端,并且根据您的特定用例,您可能需要做的只是覆盖onMeasure()
,以考虑上述条件。它会导致动画效果,这可能是不需要的。非常感谢您提供一个自定义视图组示例。@HenriquedeSousa:您是否有机会在容器视图上设置或使用setLayoutTransition()
(另请参见)?如果没有这些,高度的动态变化应该不会很明显。不过,上述解决方案并不理想,定制ViewGroup
确实是一条可行之路。如果我能找到时间,我会很快去做的。