Search code examples
androidxmllayouttogglebuttonprogrammatically-created

How to dynamically add Buttons to View so that layout width works correctly?


I am trying to dynamically add several buttons, ToggleButtons to be precise, to a view. If I represent the buttons directly in the xml they look correct when displayed. But when when the same buttons are inflated from xml and inserted with addView(View, index) I get a different representation when the activity is drawn.

There are two screenshots below. I am trying to programmatically reproduce what you see in the first one, but am getting the second. Notice that the LinearLayout that the ToggleButton objects are being added to already has two View objects, both of which have a yellow background color, and the toggle buttons are being inserted between them. The View objects are normally invisible and necessary so I can define the spacing on the ends as a percentage, hence the 0dp layout_width.

The xml and code is also below. Why are the screens not rendered identically since I am using the same xml in both cases? Any help is appreciated since I must add these buttons programmatically since their number is not known at runtime (json-driven, from a server).

What is displayed when the 4 toggle buttons are defined in the xml between the 2 (yellow) View objects:

enter image description here

But when the 4 toggle buttons are inserted programmatically between the two (yellow) View objectrs:

enter image description here

The xml for the screen that renders correctly (as desired):

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:gravity="center"
    android:id="@+id/linLytRubCard"
    >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="5dp"
        android:background="@color/ail_blue"
        >

        <ImageButton
            android:id="@+id/btnExpandDummy"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight=".10"
            android:padding="5dp"
            android:background="?android:attr/selectableItemBackground"
             />

        <TextView
            android:id="@+id/tvCardTitle"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight=".80"
            android:textColor="@color/black"
            android:textSize="16sp"
            android:gravity="center"
            android:layout_gravity="center_vertical"
            android:text="This-is-title"
            />

        <ImageButton
            android:id="@+id/btnExpandCollapse"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight=".10"
            android:padding="5dp"
            android:background="?android:attr/selectableItemBackground"
            android:src="@drawable/down_arrow_expand_rubric" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="5dp"
        android:id="@+id/linlytSegControl"
        >

        <View
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight=".10"
            android:background="@color/yellow"
            />

        <ToggleButton
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight=".20"
            android:gravity="center"
            android:paddingTop="8dp"
            android:paddingBottom="8dp"
            android:textOn="0"
            android:textOff="0"
            android:text="0"
            android:textSize="16dp"
            android:checked="false"
            android:background="@drawable/selector_leftmost_button_state"
            />

        <ToggleButton
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight=".20"
            android:gravity="center"
            android:paddingTop="8dp"
            android:paddingBottom="8dp"
            android:textOn="2"
            android:textOff="2"
            android:text="2"
            android:textSize="16dp"
            android:background="@drawable/selector_middle_button_state"
            android:checked="false"
            />

        <ToggleButton
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight=".20"
            android:gravity="center"
            android:paddingTop="8dp"
            android:paddingBottom="8dp"
            android:textOn="3"
            android:textOff="3"
            android:text="3"
            android:textSize="16dp"
            android:background="@drawable/selector_middle_button_state"
            android:checked="false"
            />

        <ToggleButton
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight=".20"
            android:gravity="center"
            android:paddingTop="8dp"
            android:paddingBottom="8dp"
            android:textOn="4"
            android:textOff="4"
            android:text="4"
            android:textSize="16dp"
            android:checked="false"
            android:background="@drawable/selector_rightmost_button_state"
            />

        <View
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight=".10"
            android:background="@color/yellow"
            />

    </LinearLayout>

I am creating and adding the toggle buttons in a loop so:

LinearLayout linLytSegCtrl = (LinearLayout) this.findViewById(R.id.linlytSegControl);

for (int x = 0; x < m_arrRubItemPointVals.size(); x++)
{
    ToggleButton tbn = (ToggleButton) View.inflate(m_context, R.layout.segmented_button_rubric, null);

    String sTitle = String.valueOf(x);
    tbn.setText(sTitle);
    tbn.setTextOn(sTitle);
    tbn.setTextOff(sTitle);
    linLytSegCtrl.addView(tbn, x+1); // inserts AFTER first yellow View in xml and before the second one
}

The xml for the individual toggle buttons read at run time:

<ToggleButton
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight=".20"
    android:gravity="center"
    android:paddingTop="8dp"
    android:paddingBottom="8dp"
    android:textSize="16dp"
    android:background="@drawable/selector_middle_button_state"
    android:checked="false"
    />

Yes, when I insert the buttons at run-time I remove them from the xml and just leave the two View objects.


Solution

  • You probably need to set the parent in your call to view.inflate: View.inflate(m_context, R.layout.segmented_button_rubric, linLytSegCtrl);.

    The documentation for View.Inflate states that the third parameter is "Used to properly inflate the layout_* parameters": https://developer.android.com/reference/android/view/View.html#inflate(android.content.Context,%20int,%20android.view.ViewGroup)