Set margins in a LinearLayout programmatically

366,515

Solution 1

Here is a little code to accomplish it:

LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);

LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
     LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);

layoutParams.setMargins(30, 20, 30, 0);

Button okButton=new Button(this);
okButton.setText("some text");
ll.addView(okButton, layoutParams);

Solution 2

So that works fine, but how on earth do you give the buttons margins so there is space between them?

You call setMargins() on the LinearLayout.LayoutParams object.

I tried using LinearLayout.MarginLayoutParams, but that has no weight member so it's no good.

LinearLayout.LayoutParams is a subclass of LinearLayout.MarginLayoutParams, as indicated in the documentation.

Is this impossible?

No.

it wouldn't be the first Android layout task you can only do in XML

You are welcome to supply proof of this claim.

Personally, I am unaware of anything that can only be accomplished via XML and not through Java methods in the SDK. In fact, by definition, everything has to be doable via Java (though not necessarily via SDK-reachable methods), since XML is not executable code. But, if you're aware of something, point it out, because that's a bug in the SDK that should get fixed someday.

Solution 3

To add margins directly to items (some items allow direct editing of margins), you can do:

LayoutParams lp = ((ViewGroup) something).getLayoutParams();
if( lp instanceof MarginLayoutParams )
{
    ((MarginLayoutParams) lp).topMargin = ...;
    ((MarginLayoutParams) lp).leftMargin = ...;
    //... etc
}
else
    Log.e("MyApp", "Attempted to set the margins on a class that doesn't support margins: "+something.getClass().getName() );

...this works without needing to know about / edit the surrounding layout. Note the "instanceof" check in case you try and run this against something that doesn't support margins.

Solution 4

Due to variation in device screen pixel densities its good to always use DIP unit to set margin programmatically. Like below_

//get resources
Resources r = getResources();
float pxLeftMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, r.getDisplayMetrics());
float pxTopMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, r.getDisplayMetrics());
float pxRightMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, r.getDisplayMetrics());
float pxBottomMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, r.getDisplayMetrics());

//get layout params...
LayoutParams params=new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
params.setMargins(Math.round(pxLeftMargin), Math.round(pxTopMargin), Math.round(pxRightMargin), Math.round(pxBottomMargin));

//set margin...
yourLayoutTOsetMargin.setLayoutParams(params); 

Hope this will help.

Solution 5

I have set up margins directly using below code

LinearLayout layout = (LinearLayout)findViewById(R.id.yourrelative_layout);
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT);            
params.setMargins(3, 300, 3, 3); 
layout.setLayoutParams(params);

Only thing here is to notice that LayoutParams should be imported for following package android.widget.RelativeLayout.LayoutParams, or else there will be an error.

Share:
366,515

Related videos on Youtube

Timmmm
Author by

Timmmm

Updated on July 29, 2021

Comments

  • Timmmm
    Timmmm almost 3 years

    I'm trying to use Java (not XML) to create a LinearLayout with buttons that fill the screen, and have margins. Here is code that works without margins:

    LinearLayout buttonsView = new LinearLayout(this);
    buttonsView.setOrientation(LinearLayout.VERTICAL);
    for (int r = 0; r < 6; ++r) {
        Button btn = new Button(this);
        btn.setText("A");
    
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT); // Verbose!
        lp.weight = 1.0f; // This is critical. Doesn't work without it.
        buttonsView.addView(btn, lp);
    }
    
    ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT);
    setContentView(buttonsView, lp);
    

    So that works fine, but how on earth do you give the buttons margins so there is space between them? I tried using LinearLayout.MarginLayoutParams, but that has no weight member so it's no good. And it doesn't work if you pass it lp in its constructor either.

    Is this impossible? Because it sure looks it, and it wouldn't be the first Android layout task you can only do in XML.

    • DarthestVader
      DarthestVader over 12 years
      developer.android.com/reference/android/view/…, int, int, int) Instead of layoutParams.setMargins(30, 20, 30, 0); you put layoutParams.setMargins(30dp, 20dp, 30dp, 0dp);
    • jyavenard
      jyavenard over 12 years
      setMargins takes int as arguments.. you can only provide "dp" using xml attributtes
  • Timmmm
    Timmmm about 14 years
    Ha, ok I understand now. Was getting a bit lost in the layout system which is rather complicated. I don't think there's anyway to set layout_widgth/height at runtime.
  • Timmmm
    Timmmm about 14 years
    And there's no way to set the style: stackoverflow.com/questions/2016249/…
  • CommonsWare
    CommonsWare about 14 years
    I haven't had a problem with setting width and height at runtime via LayoutPararms. I terms of styles...yeah, well, there's a reason I don't use 'em. :-)
  • Vinayak Bevinakatti
    Vinayak Bevinakatti almost 14 years
    Its possible to give the margins for the widgets in code too.
  • Ludvig A. Norin
    Ludvig A. Norin about 13 years
    In Java you set the layout_width/height XML attributes by creating a layoutparams object and setting the Width and Height on it, then setting it either on the view or when adding your view to another view. The attribute name actually indicates exactly this: layout_width sets set width of the layout (rather than the view object that you give the attribute to).
  • Someone Somewhere
    Someone Somewhere about 13 years
    I want to know why it's such a PITA to programmatically generate a UI
  • Someone Somewhere
    Someone Somewhere about 13 years
    thanks for a to-the-point code sample - way more beneficial than just descriptions
  • Artem Russakovskii
    Artem Russakovskii almost 13 years
    It looks like the margin params are set in pixels. Any way to set them in dps?
  • Ratan
    Ratan over 12 years
    Thanks a lot. It is really helpful !
  • mxcl
    mxcl over 12 years
    @ArtemRussakovskii Like most functions in Android, they take pixels. I suggest a global utility function that converts dips to px. This is what I have done in all my apps. Android API sucks.
  • Artem Russakovskii
    Artem Russakovskii over 12 years
    @MaxHowell That's what I ended up doing. It's incredible that basic things like that are missing sometimes.
  • IAmGroot
    IAmGroot about 12 years
    Took me ages to realise, that infact a few days ago I imported the wrong LayoutParams that didnt support Margins... Reading these answers I decided to remove my import. There are over 10 options D: I went for linearLayout.LayoutParams. Works.
  • Admin
    Admin over 11 years
    Is there a way of setting margin directly on a button e.g. myButton.setMargins(...) instead of having to nest the button in a linear layout?
  • Rise
    Rise about 11 years
    He he.. I loved the last statement!!
  • Gautam
    Gautam almost 11 years
    @ArtemRussakovskii - use TypedValue.applyDimension(...) to convert DIP to PX. See stackoverflow.com/questions/2238883/…
  • Maverick
    Maverick almost 10 years
    it reqires min API 11
  • djdance
    djdance almost 10 years
    Its exactly I looking for.
  • Demwis
    Demwis over 9 years
    I have also used this way to convert dp to pixel: getResources().getDimension(R.dimen.col_2d3), which was declared in dimen.xml like <dimen name="col_2d3">10dp</dimen>. It is converted to 20 pixels on my device.
  • xenteros
    xenteros over 7 years
    “While this code may answer the question, it is better to include the explanation of the code here.
  • Graham
    Graham over 7 years
    If you want your design to scale to any screen you can set the widths of components to some fraction of the screen width. So if you want 4 buttons across the screen, make each of their widths a quarter of the screen width. You can even do this with text.
  • Orlay Garcia Duconge
    Orlay Garcia Duconge over 4 years
    margin_30 = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30, getResources().getDisplayMetrics());