0

I currently have a LinearLayout with three elements, each with a weight of one:

<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>

And it looks like this:

enter image description here

In my program, I'm programatically creating and inserting a TextView with height & width WRAP_CONTENT into the root view like so:

TextView tView = new TextView(this);

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

tView.setLayoutParams(p);

I calculate the X & Y above the SeekBar's thumb and set the TextView's X & Y to those values.

However, when I add the TextView, I assume what the program does is add the TextView's margins to the root view and so the existing weighted childs have less space to work with, causing them to look compressed like so:

enter image description here

Is there any way to insert the TextViews without affecting the weights of the existing views in the layout?

damememan
  • 592
  • 7
  • 14

1 Answers1

2

Weights are just like percentages. With three elements having weight of 1, each is going to have 33% of the total height available. With nothing else to share the height with, the available height is the whole height of the layout. But, if you put another view inside the layout which takes up some of that height, there's going to be less available height for our weighted views. They're still going to be taking 33% of the total height available, but there's less of that now.

Now we know that to keep 33% being the same height, we need to keep the total available height the same. So, when we add a view to take up some if that height, we need to add to the total height to compensate.

In more specific terms of your problem, if you increase the height of the LinearLayout by the height of the TextView you're adding to it, it will keep the total available height the same for the weighted views.

So, there are now two steps to follow to make this work.

  1. Calculate the height of the TextView you're adding
  2. Increase the height of the LinearLayout by the calculated height

There is really easy solution that we can use right away if it suits our problem: a fixed height. If we set the TextView to a predefined height then we already know how much to increase the height of the LinearLayout.

However, if we don't know how much height it's going to have we need to calculate it by measuring it. This is a pretty well covered topic. For instance, you can read more about that here.

Once you've got the height, you will need to increase the height of the LinearLayout. There are a few ways to do this, but a straightforward approach might look like this:

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

Hope this helps.

Community
  • 1
  • 1
DanielLaneDC
  • 1,731
  • 11
  • 9
  • Thank you, I will try doing this. About the code snippet you provided: setting layout params with the textViewHeight add the textViewHeight to the existing height or replace it entirely? – damememan Feb 23 '17 at 13:25