如何使水平线性布局的子项自适应其内容?

3
正如标题所述,我的情况下子视图是一个带有一些内容的TextView,我想让它每行一个。
所以把layout_width设置为0dp并添加layout_weight 1无效,我认为是因为它是其行中唯一的一个,所以1是最高权重...不确定。
这是xml:
    <LinearLayout
        android:id="@+id/tagsVerticalLineup"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:orientation="vertical"
        android:gravity="center_horizontal">

        <TextView 
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
         />

        <TextView 
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
         />

        <TextView 
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
         />

    </LinearLayout>

最终,我希望它们一个接一个地垂直排列(每行一个),水平大小为它们的文本长度(内容)。
使用线性布局是否可能实现这一点?
谢谢。
编辑: 正如@Ajil O的回答是有效的,我的问题仍然存在。我分离了主要区别。
在我的项目中,我使用Inflate从代码中添加TextViews,因为我有默认样式。
充气代码:
    final LinearLayout tagAreaView = (LinearLayout) findViewById(R.id.tagsVerticalLineup);
    TextView tag = (TextView) getLayoutInflater().inflate(R.layout.answer_tag, null);

    int tagId = someListArray.size();
    tag.setId(tagId);
    tag.setText(someChangingObject.text);
    tagAreaView.addView(tag, tagId);

文本视图 answer_tag:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    style="@style/SelectedTagAnswer" />
<style name="SelectedTagAnswer">
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:layout_marginStart">8dp</item>
    <item name="android:layout_marginEnd">16dp</item>
    <item name="android:background">@drawable/selected_answer</item>
    <item name="android:drawablePadding">8dp</item>
    <item name="android:gravity">center_horizontal</item>
    <item name="android:drawableStart">@drawable/ic_cross_round</item>
    <item name="android:elevation">3dp</item>
    <item name="android:paddingBottom">8dp</item>
    <item name="android:paddingEnd">25dp</item>
    <item name="android:paddingStart">15dp</item>
    <item name="android:paddingTop">8dp</item>
</style>

注意:

在xml中插入一个使用相同样式的简单Text View时,它的工作方式与@Ajil O的答案相同。在充气过程中有一些东西会搞砸它。


请使用width参数和wrap_content来设置大小。但随着文本限制的增加,它的水平尺寸也会增加。 - Umair
您希望文本长度水平增长,但文本应该保持在一行中吗? - Umair
1
@darthydarth,我已经尝试了你的代码,现在我有三个垂直对齐的文本视图,并且它们的大小随着长度的增加而水平增加。我发现你的问题相当令人困惑 ;) - Umair
1
不明白你的问题?如果你想让TextView只有一行,使用maxLines=1。 - Jerin A Mathews
@Mahozad,这个问题似乎与那个不同。这是一个垂直布局,可以包裹其子元素的水平大小,而不是在没有足够空间时将子元素换行到另一行。 - Ryan M
显示剩余4条评论
5个回答

1
LinearLayout 的宽度设置为 match_parent,高度设置为 wrap_content
<LinearLayout
    android:id="@+id/tagsVerticalLineup"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:gravity="center_horizontal">

    <TextView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
     />

    <TextView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
     />

    <TextView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
     />

</LinearLayout>

如果您想让 TextView 只占用一行,请使用 android:maxLines="1" 属性。

enter image description here

现在,TextView都是彩色的了。您可以看到TextView与其内容一样宽。
容器LinearLayout被浅紫色遮蔽。此LinearLayout必须至少与最长的TextView一样宽,否则视图(或其内容)将被裁剪。
<LinearLayout
    android:id="@+id/tagsVerticalLineup"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:gravity="center"
    android:background="#AAAAFF"
    android:layout_gravity="center">

    <TextView
        android:layout_margin="8dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#080"
        android:text="small text"
        android:textColor="#FFF"
        android:textSize="18sp"
        android:maxLines="1"/>

    <TextView
        android:layout_margin="8dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Slightly longer text"
        android:background="#400"
        android:textColor="#FFF"
        android:textSize="18sp"
        android:maxLines="1"/>

    <TextView
        android:layout_margin="8dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="loooooooooooooooooong text"
        android:background="#008"
        android:textColor="#FFF"
        android:textSize="18sp"
        android:maxLines="1"/>

</LinearLayout>

@darthydarth 如果是这样,我不明白为什么Umair的答案对你不起作用。在我的答案中,TextView不会扩展到LinearLayout的宽度(除非文本很长)。 - Ajil O.
在这个答案中,“Text View”仍然会拉伸到全宽。在Umair的答案中,它们都会拉伸到“Text View”的宽度大小,即最长的文本,这也不好。也许使用“线性布局”没有好的解决方案,但我不能使用约束...感觉很绝望。 - Blue Bot
假设文本(内容)的宽度为Ajil O。我们可以假设它不超过2-4个短单词,以简化问题。 - Blue Bot
@darthydarth,我已经在答案中添加了一张图片。TextView的宽度确实与其内容一样宽。我不明白你的要求是什么。 - Ajil O.
1
@darthydarth 如果您提供更详细的信息,很有可能会有人能够提供帮助。 - Ajil O.
显示剩余6条评论

1

最终找到了解决方案,原来Android不会刷新使用wrap_content的视图布局一旦它被显示出来。

如在此答案中所述 动态添加视图后WRAP_CONTENT无效

所以我的问题是先填充视图然后再添加内容(文本)。

为了克服这个问题,我重新设置了高度和宽度,如下所示:

    tag.setLayoutParams(new ViewGroup.LayoutParams(
            ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT));

现在,如果所有来自Ajil O的答案都被实施了,它就可以工作了!
希望这个边缘情况将来对某人有用。

0

只需在android:layout_width中使用wrap_content参数,你就可以了。你现在正在使用0dp

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="@+id/tagsVerticalLineup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal"
xmlns:android="http://schemas.android.com/apk/res/android">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"

    />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    />

</LinearLayout>

这个没问题,但是在我的情况下,我需要Text View自动换行以适应它们的内容,否则它们的大小将取决于最长的文本。 - Blue Bot
@darthydarth,你有两个选择:要么给TextView设置固定的宽度,当文本大小增加时,文本会自动换行;如果你还想保持文本显示在一行内,可以同时使用maxlines="1"和固定宽度。 - Umair

0

试一下

  • 设置父布局的Height and Width=match_parent
  • textView宽度设置为match_parent,以便您可以使用textalignment=center或者使用gravity=center

<LinearLayout
    android:id="@+id/tagsVerticalLineup"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center_horizontal">

    <TextView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"/>

    <TextView 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"     />

    <TextView 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"/>

</LinearLayout>

谢谢,我已经解决了,可以看答案https://dev59.com/xKbja4cB1Zd3GeqPjKH6#47207341 - Blue Bot

0

最好使用ContrainstLayout,您可以操纵任何事件来获得所需的尺寸。


你说得完全正确,但在这种情况下我做不到,因为我正在以编程方式添加和删除“文本视图”,所以约束条件很快就会混乱。 - Blue Bot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接