Matt
Matt

Reputation: 3912

Set weight of Views in LinearLayout

Below is what I want to achieve.

enter image description here

Each rounded-corner View is a LinearLayout. The 3 Views inside of the LinearLayout are supposed to each have a weight of 1. Right now, when I run the below code nothing is displayed. Only the background is showing but none of the Views.

LinearLayout.LayoutParams params2 = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT);
params1.weight = 1;

LinearLayout.LayoutParams params3 = new LinearLayout.LayoutParams(0, 75);
params1.weight = 1;

LinearLayout.LayoutParams params4 = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT);
params1.weight = 1;

ll.addView(levelTV, params4);
ll.addView(recordTV, params2);
ll.addView(image, params3);
linearlayout.addView(ll, params1);

When setting weights, aren't you supposed to set the widths to zero? When I change the widths to LinearLayout.LayoutParams.MATCH_PARENT, all I see are the numbers (1, 2, 3, etc.) but nothing else. How can I get my desired layout?

Upvotes: 1

Views: 1162

Answers (1)

Submersed
Submersed

Reputation: 8870

There are a lot of ways of doing this, it's just a matter of preference on how you handle it. Most of the time keeping your layout's creation in XML is preferred, as it keeps your view creation logic separate from your application logic, leading to cleaner code. Also, once you get used to XML its the easiest in my opinion. I'll show a couple of ways to handle your issue...

border.xml

<?xml version="1.0" encoding="UTF-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android"> 
<solid android:color="#ffffffff"/>    

<stroke android:width="3dp"
        android:color="#ff000000"
        />

<padding android:left="1dp"
         android:top="1dp"
         android:right="1dp"
         android:bottom="1dp"
         /> 

<corners android:bottomRightRadius="7dp" 
         android:bottomLeftRadius="7dp" 
         android:topLeftRadius="7dp"
         android:topRightRadius="7dp"/> 
</shape>

row_view.xml - not perfect, but easily modified.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/border"
    android:layout_margin="2dp" >

    <TextView
        android:id="@+id/text_number"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="16dp"
        android:paddingTop="16dp"
        android:paddingBottom="16dp"
        android:text="1"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:layout_alignParentLeft="true" />

    <TextView
        android:id="@+id/text_record"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Record: ###"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:layout_centerInParent="true" />

    <CheckBox
        android:id="@+id/checkBox1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:paddingRight="8dp"
        android:checked="true"/>

</RelativeLayout>

From here, you could go about this a few different ways -- the first, would be to use the include statement in another XML and just use that layout, then traverse all of the views in order to set up your view. This is kind of dirty, so I don't really prefer it, but the XML would look like:

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

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


</LinearLayout>

Then you could just inflate this XML in your activity, and traverse your views. The other option, is to inflate and add. Here's a quick example of each, just change the current_type field to see the result of each...:

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class MainActivity extends Activity {

    private static final int NUMBER_OF_ROWS = 3;

    private static final int XML_TRAVERSAL = 1;
    private static final int ADD_VIEW = 2;

    private static int current_type = ADD_VIEW;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if(current_type == XML_TRAVERSAL){
            setUpUsingTraversal();
        } else {
            setUpByInflating();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }


    private void setUpUsingTraversal(){
        setContentView(R.layout.container_view);

        LinearLayout main_view = (LinearLayout) findViewById(R.id.main_view);

        int count = main_view.getChildCount();
        for(int i = 0; i < count ; i++){
            RelativeLayout layout = (RelativeLayout) main_view.getChildAt(i);
            setTextOnViews(layout, i);      
        }

    }

    private void setUpByInflating() {       
        LinearLayout layout = new LinearLayout(this);
        layout.setOrientation(LinearLayout.VERTICAL);
        layout.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

        for(int x = 0; x < NUMBER_OF_ROWS ; x++){
            RelativeLayout row = (RelativeLayout) getLayoutInflater().inflate(R.layout.row_view, layout, false);
            setTextOnViews(row,x);
            layout.addView(row);
        }

        setContentView(layout);
    }

    private void setTextOnViews(ViewGroup view, int position){
        ((TextView)view.getChildAt(0)).setText(Integer.toString(position));
        ((TextView)view.getChildAt(1)).setText("Record: " + Integer.toString(position));    
    }

}

Finally, the other route you could take (which you mentioned being too verbose) would be to make one xml file that already contains the correct values, and just inflate and be done.

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

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="2dp"
        android:background="@drawable/border" >

        <TextView
            android:id="@+id/text_number1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:paddingBottom="16dp"
            android:paddingLeft="16dp"
            android:paddingTop="16dp"
            android:text="1"
            android:textAppearance="?android:attr/textAppearanceLarge" />

        <TextView
            android:id="@+id/text_record1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="Record: ###"
            android:textAppearance="?android:attr/textAppearanceSmall" />

        <CheckBox
            android:id="@+id/checkBox1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:checked="true"
            android:paddingRight="8dp" />
    </RelativeLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="2dp"
        android:background="@drawable/border" >

        <TextView
            android:id="@+id/text_number2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:paddingBottom="16dp"
            android:paddingLeft="16dp"
            android:paddingTop="16dp"
            android:text="2"
            android:textAppearance="?android:attr/textAppearanceLarge" />

        <TextView
            android:id="@+id/text_record2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="Record: ###"
            android:textAppearance="?android:attr/textAppearanceSmall" />

        <CheckBox
            android:id="@+id/checkBox2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:checked="true"
            android:paddingRight="8dp" />
    </RelativeLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="2dp"
        android:background="@drawable/border" >

        <TextView
            android:id="@+id/text_number3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:paddingBottom="16dp"
            android:paddingLeft="16dp"
            android:paddingTop="16dp"
            android:text="3"
            android:textAppearance="?android:attr/textAppearanceLarge" />

        <TextView
            android:id="@+id/text_record3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="Record: ###"
            android:textAppearance="?android:attr/textAppearanceSmall" />

        <CheckBox
            android:id="@+id/checkBox3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:checked="true"
            android:paddingRight="8dp" />
    </RelativeLayout>


</LinearLayout>

EDIT:

Also, if you want to achieve this with a LinearLayout rather than a RelativeLayout the xml would look like this:

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

    <TextView
        android:id="@+id/text_number"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="16dp"
        android:text="1"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <TextView
        android:id="@+id/text_record"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center"
        android:text="Record: ###"
        android:textAppearance="?android:attr/textAppearanceSmall" />

    <CheckBox
        android:id="@+id/checkBox1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:checked="true"
        android:paddingRight="8dp" />

</LinearLayout>

So, if you were doing this programmatically, you would set the following layout params:

LinearLayout.LayoutParams forNumberAndCheckBox = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

LinearLayout.LayoutParams forRecord = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, 1);

Upvotes: 2

Related Questions