223

I'm trying to dynamically create TableRow objects and add them to a TableLayout. The TableRow objects has 2 items, a TextView and a CheckBox. The TextView items need to have their layout weight set to 1 to push the CheckBox items to the far right.

I can't find documentation on how to programmatically set the layout weight of a TextView item.

canova
  • 3,965
  • 2
  • 22
  • 39
eugene
  • 2,519
  • 3
  • 17
  • 5

12 Answers12

365

You have to use TableLayout.LayoutParams with something like this:

TextView tv = new TextView(v.getContext());
tv.setLayoutParams(new TableLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));

The last parameter is the weight.

Dorje
  • 1,067
  • 2
  • 9
  • 9
Macarse
  • 91,829
  • 44
  • 175
  • 230
  • 15
    I didn't mention this before, so I'm sorry. But I tried this prior to asking my question. It makes the TextView disappear from the layout. But, on a positive note, I found that setting the stretch_columns property of the TableLayout to 0 causes the effect I'm looking for (TextView's on the left, CheckBoxes on the right). Thanks for the help. – eugene Jul 12 '10 at 00:35
  • 8
    If you are importing an XML layout and you are not creating your layout dynamically, you can grab it like this: `TextView tv = (TextView) findViewById(R.id.your_textview_inside_the_linearlayout); tv.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0.1f));` – Eric Leschinski Apr 13 '12 at 20:51
  • 7
    To set the layout weight programmatically, `TableRow.LayoutParams` should be used instead of `TableLayout.LayoutParams`. See @Dorje's answer. – Halil Aug 28 '14 at 12:56
  • import android.widget.LinearLayout; import android.widget.TableLayout; – Prakash Nov 17 '15 at 19:53
  • 1
    Note that most people would use 0 as first or second parameter (depending if horizontal or vertical) and not WRAP_CONTENT since what they are looking for is to set the weight. – FlorianB Nov 14 '16 at 18:36
  • table.setStretchAllColumns(true); – Hack06 Oct 13 '17 at 08:38
101

The answer is that you have to use TableRow.LayoutParams, not LinearLayout.LayoutParams or any other LayoutParams.

TextView tv = new TextView(v.getContext());
LayoutParams params = new TableRow.LayoutParams(0, LayoutParams.WRAP_CONTENT, 1f);
tv.setLayoutParams(params);

The different LayoutParams are not interchangeable and if you use the wrong one then nothing seems to happen. The text view's parent is a table row, hence:

http://developer.android.com/reference/android/widget/TableRow.LayoutParams.html

Dorje
  • 1,067
  • 2
  • 9
  • 9
41

In the earlier answers weight is passed to the constructor of a new SomeLayoutType.LayoutParams object. Still in many cases it's more convenient to use existing objects - it helps to avoid dealing with parameters we are not interested in.

An example:

// Get our View (TextView or anything) object:
View v = findViewById(R.id.our_view); 

// Get params:
LinearLayout.LayoutParams loparams = (LinearLayout.LayoutParams) v.getLayoutParams();

// Set only target params:
loparams.height = 0;
loparams.weight = 1;
v.setLayoutParams(loparams);
sberezin
  • 3,266
  • 23
  • 28
  • loparams could be NULL so make sure you check that before calling setLayoutParams() – AAgg Jul 09 '15 at 16:19
  • @AAgg, not in a practical situation. View wouldn't have inflated if it hadn't width and height set. But I agree - it's a good practice to check when there're doubts about null. – sberezin Jul 10 '15 at 07:34
17
TextView txtview = new TextView(v.getContext());
LayoutParams params = new LinearLayout.LayoutParams(0, LayoutParams.WRAP_CONTENT, 1f);
txtview.setLayoutParams(params);

1f is denotes as weight=1; you can give 2f or 3f, views will move accoding to the space

13

just set layout params in that layout like

create param variable

 android.widget.LinearLayout.LayoutParams params = new android.widget.LinearLayout.LayoutParams(
            LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, 1f);

1f is weight variable

set your widget or layout like

 TextView text = (TextView) findViewById(R.id.text);
 text.setLayoutParams(params);
Android Killer
  • 18,174
  • 13
  • 67
  • 90
Manikandan
  • 844
  • 15
  • 31
  • where do you get this information that 1f means the weight variable ? Can you provide a link please ? – hayonj Sep 25 '13 at 04:31
  • @hayonj just check sources of `LinearLayout.LayoutParams` constructor. 3rd parameter is weight. Or [documentation](http://developer.android.com/reference/android/widget/LinearLayout.LayoutParams.html) – mente Oct 25 '13 at 15:01
11
TextView text = new TextView(v.getContext());
text.setLayoutParams(new TableLayout.LayoutParams(LayoutParams.WRAP_CONTENT, 
                                                LayoutParams.WRAP_CONTENT, 1f));

(OR)

TextView tv = new TextView(v.getContext());
LayoutParams params = new TableRow.LayoutParams(0, LayoutParams.WRAP_CONTENT, 1f);
tv.setLayoutParams(params);

1f is refered as weight=1; according to your need you can give 2f or 3f, views will move accoding to the space. For making specified distance between views in Linear layout use weightsum for "LinearLayout".

LinearLayout ll_Outer= (LinearLayout ) view.findViewById(R.id.linearview);
LinearLayout llInner = new LinearLayout(this);
            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FillParent, LinearLayout.LayoutParams.WrapContent);
            llInner.Orientation = Orientation.Horizontal;
            llInner.WeightSum = 2;
            ll_Outer.AddView(llInner);
anand krish
  • 4,281
  • 4
  • 44
  • 47
10

This should works to you

LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT LayoutParams.MATCH_PARENT);

param.weight=1.0f;
Ashok Reddy M
  • 330
  • 3
  • 9
7

You can also give weight separately like this ,

LayoutParams lp1 = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);

 lp1.weight=1;
kiran boghra
  • 3,662
  • 2
  • 18
  • 23
6

This work for me, and I hope it will work for you also

Set the LayoutParams for the parent view first:

myTableLayout.setLayoutParams(new TableLayout.LayoutParams(TableLayout.LayoutParams.FILL_PARENT,
                TableLayout.LayoutParams.FILL_PARENT));

then set for the TextView (child):

 TableLayout.LayoutParams textViewParam = new TableLayout.LayoutParams
     (TableLayout.LayoutParams.WRAP_CONTENT,
     TableLayout.LayoutParams.WRAP_CONTENT,1f);
     //-- set components margins
     textViewParam.setMargins(5, 0, 5,0);
     myTextView.setLayoutParams(textViewParam); 
andrewsi
  • 10,807
  • 132
  • 35
  • 51
Najem1234
  • 69
  • 1
  • 1
2

After strugling for 4 hours. Finally, This code worked for me.

3 Columns are there in a row.

  TextView serialno = new TextView(UsersActivity.this);
  TextView userId = new TextView(UsersActivity.this);
  TextView name = new TextView(UsersActivity.this);

  serialno.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT, 1f));
  userId.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT, 1f));
  name.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT, 1f));
Gulshan Yadav
  • 424
  • 5
  • 13
1

There is another way to do this. In case you need to set only one parameter, for example 'height':

TextView textView = (TextView)findViewById(R.id.text_view);
ViewGroup.LayoutParams params = textView.getLayoutParams();
params.height = ViewGroup.LayoutParams.WRAP_CONTENT;
textView.setLayoutParams(params);
Dmitry
  • 2,766
  • 1
  • 18
  • 17
-1

I had a fair amount of difficulty with a solution something very similar to this: trying to have two buttons in a TableRow, with each being half the screen width. For whatever reason, the left button would always be about 70% of the width, and the right button 30%. Calling table_layout.setStretchAllColumns(true) had no effect, nor did setting the button's width to half the screen, nor setting their layout weight.

The solution I ended up with was nesting a LinearLayout in the TableRows, which did take into account the value of the buttons' width.

    TableLayout layout = new TableLayout(this);
    TableRow top_row = new TableRow(this);
    left_button = styleButton();
    right_button = styleButton();
    LinearLayout toprow_layout = new LinearLayout (this);
    toprow_layout.setOrientation(LinearLayout.HORIZONTAL);
    toprow_layout.addView (left_button);
    toprow_layout.addView(right_button);
    toprow.addView(top_layout);
    layout.addView(top_row)

    private Button styleButton() {
            Button btn = new Button (this);
            android.view.Display display = ((android.view.WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();      
            btn.setWidth((int)(display.getWidth()/2));    // set width to half
            btn.setHeight(((int)display.getHeight()/6));  // set height to whatevs
            btn.setText("foo");
            return btn;
        }
joseph_morris
  • 705
  • 6
  • 13
  • 1
    Just so you know for the future, the solution is to set the TableRow, Button1, and Button2 to all have `layout_width=fill_parent`, and after doing that, set the `layout_weight=1` for both button1 and button2. All elements with fill_parent and a layout_weight=1 will be given an equal size upon inflation. – edthethird Mar 02 '12 at 18:00