Michael Anderson
Michael Anderson

Reputation: 41

Linear Layout weights not working inside of Relative Layout

Myself and a few friends are making a game for android that has a field of play. In front of a portion of the field of play, I want to place buttons. Like so:

enter image description here

In order to put one set of xml in front of another, I believe we need to use a Relative Layout. So far we have been doing this inline (programatically) but now I want to do this using XML. I think I have a pretty good understand of how weighting works. I am doing this using linear layouts inside of one another. The intended result is to have the buttons only cover a small portion of the screen.

Unfortunately, when I add my linear layout to my relative layout, the weighting functionality doesn't seem to work anymore.

For clarity, I have added two rows of buttons and weighted the second row to be larger than the first. Here is the Android Studio preview of what the layout should look like:

enter image description here

Here is what it is actually coming out as:

enter image description here

The two rows are being displayed as the same size. I am hoping someone can give me an answer as to why this is happening, and if possible, a solution as to how to fix the problem.

Here is my code adding the linear layout to the Relative layout:

RelativeLayout relativeLayout = (RelativeLayout)this.findViewById(R.id.testLayout);
View  view = LayoutInflater.from(this).inflate(R.layout.testgameplay_wrapper, null);
relativeLayout.addView(view);

Here is the relevant XML. I have created a wrapper class to simplify things:

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

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayout1"
    android:layout_weight=".25"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:orientation="horizontal">

    <include layout="@layout/testgameplay_buttondisplay"></include>

    </LinearLayout>

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayout2"
    android:layout_weight="1"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:orientation="horizontal">

    <include layout="@layout/testgameplay_buttondisplay"></include>

</LinearLayout>

EDIT:

testgamplaybutton_buttondisplay.xml as requested:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
    android:id="@+id/testScreenButtonDisplay"
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">

        <LinearLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/linearLayoutInnermost1"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="horizontal">

            <include
                layout="@layout/defend_screen_buttons"></include>

        </LinearLayout>

        <LinearLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/linearLayoutInnermost2"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="horizontal">


            <include
                layout="@layout/test_screen_buttons"></include>

        </LinearLayout>

test_screen_buttons.xml as will likely be requested:

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

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayout1"
    android:layout_weight=".25"
    android:layout_height="match_parent"
    android:layout_width="0dp"
    android:orientation="horizontal">
<Button
    android:id="@+id/spawnCreepButton"
    android:textColor="@android:color/white"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerInParent="true"
    android:background="@drawable/basic_button"
    android:text="Spawn Creep"
    android:onClick="RunProjectileTest"/>

</LinearLayout>

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayout2"
    android:layout_weight=".25"
    android:layout_height="match_parent"
    android:layout_width="0dp"
    android:orientation="horizontal">

<Button
    android:id="@+id/sendCreepsButton"
    android:gravity="center"
    android:textColor="@android:color/white"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:background="@drawable/basic_button"
    android:text="Send Creeps"
    android:onClick="StartSendCreepsScreen"/>

</LinearLayout>

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayout3"
    android:layout_weight=".25"
    android:layout_height="match_parent"
    android:layout_width="0dp"
    android:orientation="horizontal">
<Button
    android:id="@+id/replayButton"
    android:gravity="center"
    android:textColor="@android:color/white"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:background="@drawable/basic_button"
    android:text="Replay"
    android:onClick="StartReplayScreen"/>

</LinearLayout>

defend_screen_buttons.xml as will likely be requested:

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

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayout1"
    android:layout_weight=".25"
    android:layout_height="match_parent"
    android:layout_width="0dp"
    android:orientation="horizontal">

<Button
    android:id="@+id/startButton"
    android:textColor="@android:color/white"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerInParent="true"
    android:textSize="20sp"
    android:background="@drawable/basic_button"
    android:text="Start" />

    </LinearLayout>


<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayout2"
    android:layout_weight=".25"
    android:layout_height="match_parent"
    android:layout_width="0dp"
    android:orientation="horizontal">

<Button
    android:id="@+id/sendButton"
    android:gravity="center"
    android:textColor="@android:color/white"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:background="@drawable/basic_button"
    android:text="Prepare Attack!" />

</LinearLayout>

Now you see why I tried to simplify it XD

Thanks for your time and expertise!

Upvotes: 1

Views: 1494

Answers (4)

Blessing Charumbira
Blessing Charumbira

Reputation: 733

I had the same problem with relative layouts that were inside a linear layout and the deviation from the center can be a problem. I check all the solutions and I did not see anyone who used match_parent on layout_width for the child of the linear view. Change 0dp and wrap_content to match_parent. Here is a before and after in my problem: enter image description here

Upvotes: 1

Michael Anderson
Michael Anderson

Reputation: 41

I believe I have found an answer to my problem.

Here is my old code which was creating the LinearLayout and adding it to the RelativeLayout:

RelativeLayout relativeLayout = (RelativeLayout)this.findViewById(R.id.testLayout);
View  view = LayoutInflater.from(this).inflate(R.layout.testgameplay_wrapper, null);
relativeLayout.addView(view);

Here is my new code:

    //Now using LinearLayout instead of View     
    LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    LinearLayout linearLayout = (LinearLayout)inflater.inflate(R.layout.testgameplay_buttondisplay, null);

    //convert dp to pixels
    int height = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100, getResources().getDisplayMetrics());

    //Set the height of the layout in newly calculated pixels
    RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, height);
    rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP);
    linearLayout.setLayoutParams(rlp);

    relativeLayout.addView(linearLayout);

As you can see, I am making use of LayoutParams and adding them to my linearLayout. The buttons now appear on the screen as I want them to and their size varies depending on the pixel height I indicate. Thanks to all those who gave their input!

Upvotes: 0

Sameer Khan
Sameer Khan

Reputation: 637

In your outermost LinearLayout tag, control the android:layout_height attribute. Because it is set to match_parent for now, it takes the entire screen. Set it to some absolute number (e.g. 200dp) and you should see the difference.

Upvotes: 1

Denny K. Schuldt
Denny K. Schuldt

Reputation: 179

In order to use the layout_weight property in a child View, you need to specify the weightSum of the parent View. This works with LinearLayouts. In the example below, I've declared a root LinearLayout, with a weightSum of 1, and a child view which layout_weight equals .5, so that this will fill half of the screen. This child view (wrapper) has a weightSum of 1.5, and inside of it has two child views, one with a layout_weight equals .5, and the other one width a layout_weight equals 1. Note that these LinearLayouts have a weightSum equals 1, so that each button inside should have a layout_weight equals .2, for an evenly distribution.

Hope this helps!

<LinearLayout
    android:id="@+id/root"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:weightSum="1">

    <!-- Wrapper id View fills half of the screen, 0.5 and has a weightSum of 1.5-->
    <LinearLayout
        android:id="@+id/wrapper"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.5"
        android:weightSum="1.5"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight=".5"
            android:weightSum="1">
            <Button
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight=".2"/>
            <Button
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight=".2"/>
            <Button
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight=".2"/>
            <Button
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight=".2"/>
            <Button
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight=".2"/>
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1">
            <Button
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight=".2"/>
            <Button
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight=".2"/>
            <Button
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight=".2"/>
            <Button
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight=".2"/>
            <Button
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight=".2"/>
        </LinearLayout>

    </LinearLayout>

</LinearLayout>

Upvotes: -1

Related Questions