有没有办法以编程方式将 View 插入 LinearLayout 中,其现有元素具有权重而不影响这些权重?

Is there any way to programatically insert a View into a LinearLayout whose existing elements have weights and not have it affect those weights?

我目前有一个包含三个元素的 LinearLayout,每个元素的权重为 1:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_marginTop="16dp"
    android:layout_weight="1"
    android:gravity="center_vertical"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/happy_text"
        style="@style/TextAppearance.AppCompat.Subhead"
        android:layout_width="65sp"
        android:layout_height="wrap_content"
        android:maxLines="1"
        tools:text="Unhappy" />

    <SeekBar
        android:id="@+id/happiness_seekbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="100"
        android:theme="@style/happinessSeekbarTheme" />

</LinearLayout>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:gravity="center_vertical">

    <TextView
        android:id="@+id/stress_text"
        style="@style/TextAppearance.AppCompat.Subhead"
        android:layout_width="65sp"
        android:layout_height="wrap_content"
        android:maxLines="1"
        android:text="@string/stress" />

    <SeekBar
        android:id="@+id/stress_seekbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="100"
        android:theme="@style/stressSeekbarTheme" />
</LinearLayout>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:gravity="center_vertical">

    <TextView
        android:id="@+id/pain_text"
        style="@style/TextAppearance.AppCompat.Subhead"
        android:layout_width="65sp"
        android:layout_height="wrap_content"
        android:maxLines="1"
        android:text="@string/pain" />

    <SeekBar
        android:id="@+id/pain_seekbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="100"
        android:maxHeight="3dp"
        android:theme="@style/painSeekbarTheme" />

</LinearLayout>

看起来像这样:

在我的程序中,我以编程方式创建高度和宽度为 WRAP_CONTENT 的 TextView 并将其插入到根视图中,如下所示:

TextView tView = new TextView(this);

LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);

tView.setLayoutParams(p);

我计算了 SeekBar 拇指上方的 X 和 Y,并将 TextView 的 X 和 Y 设置为这些值。

但是,当我添加 TextView 时,我假设程序所做的是将 TextView 的边距添加到根视图中,因此现有的加权子项可以使用的 space 较少,导致它们看起来被压缩了像这样:

有没有什么方法可以在不影响布局中现有视图权重的情况下插入 TextView?

权重就像百分比一样。三个元素的权重为 1,每个元素将占可用总高度的 33%。没有其他东西可以共享高度,可用高度就是布局的整个高度。但是,如果您在布局中放置另一个占据部分高度的视图,我们的加权视图的可用高度将会减少。他们仍将占据可用总高度的 33%,但现在更少了。

现在我们知道要保持 33% 的高度相同,我们需要保持总可用高度相同。所以,当我们添加一个视图占用一些高度时,我们需要添加到总高度来补偿。

在您的问题的更具体方面,如果您将 LinearLayout 的高度增加到您添加到它的 TextView 的高度,它将使加权视图的总可用高度保持不变。

因此,现在有两个步骤可以完成这项工作。

  1. 计算您要添加的 TextView 的高度
  2. 将 LinearLayout 的高度增加计算出的高度

如果适合我们的问题,我们可以立即使用非常简单的解决方案:固定高度。如果我们将 TextView 设置为预定义的高度,那么我们已经知道要将 LinearLayout 的高度增加多少。

但是,如果我们不知道它的高度,我们需要通过测量来计算。这是一个很好的主题。例如,您可以阅读有关 here.

的更多信息

获得高度后,您将需要增加 LinearLayout 的高度。有几种方法可以做到这一点,但一个简单的方法可能如下所示:

ViewGroup.LayoutParams params = LinearLayout.getLayoutParams();
params.height = params.height + textViewHeight;
linearLayout.setLayoutParams(params);

希望对您有所帮助。