208

I am programatically adding custom views to a vertical LinearLayout, and I would like there to be some space between the views. I have tried adding: setPadding(0, 1, 0, 1) to my CustomView constructor, but this doesn't seem to have any effect. Any advice?

*It was pointed out that I should use margins. Since I am dynamically adding views, I need to set the margins from code (not in xml). I believe the way to do this is below, but it isn't working.

public class MyView extends View
{
    public MyView (Context context)
    {
        super(context);

        MarginLayoutParams params = new MarginLayoutParams(LayoutParams.WRAP_CONTENT,  LayoutParams.WRAP_CONTENT);
        params.setMargins(0, 10, 0, 10);
        setLayoutParams(params);

*Edit. I also tried using MarginLayoutParams as a parameter while adding the views to the Linear layout (as below). This also did not work:

MarginLayoutParams params = new MarginLayoutParams(linearLayout.getLayoutParams());
linearLayout.setMargins(0, 10, 0, 10);
linearLayout.addView(view, params);
A-Sharabiani
  • 17,750
  • 17
  • 113
  • 128
ab11
  • 19,770
  • 42
  • 120
  • 207

12 Answers12

252

The API >= 11 solution:

You can integrate the padding into divider. In case you were using none, just create a tall empty drawable and set it as LinearLayout's divider:

    <LinearLayout
            android:showDividers="middle"
            android:divider="@drawable/empty_tall_divider"
...>...</LinearLayout>

empty_tall_divider.xml:

<?xml version="1.0" encoding="utf-8"?>

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <size
            android:height="40dp"
            android:width="0dp"/>
</shape>
riwnodennyk
  • 8,140
  • 4
  • 35
  • 37
  • 1
    You can use it on API<11 , if you use LinearLayoutCompat : https://developer.android.com/reference/android/support/v7/widget/LinearLayoutCompat.html – android developer Feb 23 '15 at 11:06
  • 7
    if you make the shape like a square, you can use it in vertical and horizontal LinearLayouts without the need to create a new one which has width. – WarrenFaith Jul 06 '15 at 18:43
  • 2
    Here's an excellent blog post about it: [Grid Spacing on Android by Cyril Mottier](http://cyrilmottier.com/2014/11/17/grid-spacing-on-android/) – Richard Le Mesurier Mar 04 '16 at 12:02
  • 2
    This is much better if you have a set of views and turn some of them `GONE`. By specifying `android:showDividers="middle"`you'll only get the space where you actually need it. – DariusL Dec 02 '16 at 06:11
  • @DariusL I cannot find this showDividers attribute in d.android.com, are you sure we can use this? – Henry May 27 '19 at 08:57
  • @Henry I am not certain, not developing Android right now. If it's deprecated, it should be marked as such in the IDE. It **was** an exposed attribute at some point. If you're not sure, you can programatically set it (setShowDividers()) or read the sources. – DariusL May 28 '19 at 11:12
  • This solution doesn't support RTL – Yat3s Dec 29 '20 at 06:45
  • Note that this only works for horizontal layouts in LTR, RTL is broken. As a workaround for transparent dividers, you can set the dividers to show at the start, middle, and end then subtract the excess spacing at the start and end from elsewhere. – Wes Alvaro Aug 02 '21 at 03:35
  • The only correct answer, after 2 decades :) thanks ... – Fattie Jun 17 '22 at 21:16
168

You should android:layout_margin<Side> on the children. Padding is internal.

Thomas
  • 3,603
  • 1
  • 18
  • 23
  • You can define the view in XML with the desired margins and add the predefined views procedurally, applying the content in Java code as well. – Mike Yockey Nov 23 '10 at 19:04
  • I'm not really clear on what you mean by this. I should define the customview in xml? But I will need to dynamically create an arbitrary number of custom views, which I will then add to my LinearLayout. – ab11 Nov 23 '10 at 19:14
  • 2
    Try just using LayoutParams not MarginLayoutParams. – Thomas Nov 23 '10 at 19:40
  • 1
    What attribute would I set in LinearLayout.LayoutParams? That class doesn't seem to have "margins" or "padding" or anything similar? – ab11 Nov 23 '10 at 20:11
  • @Thomas what do you mean by "Padding is internal". Should I be applying margin in each of the components, which I am kind of trying to avoid so as to minimize duplicate codes (as I have equal spacing to be used between my child components) – OmGanesh Mar 14 '18 at 17:52
  • But it I margin_ is ignored if (child element's) height is `match_content`. That's why I came here. I'm confused – O-9 Aug 29 '19 at 11:23
  • What does `android:layout_margin` mean? A little explanation? – ataravati Aug 17 '21 at 16:49
  • @ataravati It means that you can follow `layout_margin` with the side where you want to apply it. Possibilities are: `Bottom`, `End`, `Horizontal`, `Left`, `Right`, `Start`, `Top` and `Vertical`. Eg: `layout_marginBottom` – luismiguelss Aug 19 '21 at 06:40
  • @luismiguelss I misunderstood the OP's question. I was looking for a way to implement justify-between in a LinearLayout. I didn't realize the question was just for adding margin. Thanks! – ataravati Aug 19 '21 at 11:54
42

Android now supports adding a Space view between views. It's available from 4.0 ICS onwards.

Jonas Czech
  • 12,018
  • 6
  • 44
  • 65
worked
  • 5,762
  • 5
  • 54
  • 79
  • 13
    Apparently the Android-Fairy listened to you and created a "Space" view in API 14 :) (http://developer.android.com/reference/android/widget/Space.html) – shaylh May 06 '12 at 16:09
  • LOL! It was only a matter of time. – worked May 08 '12 at 14:34
  • 10
    but you need to at a space per view, which is not the same as declare a gap for all views. – Lay González Oct 27 '14 at 19:21
  • ^ Very true. However if you're using a LinearLayout, you can a add divider which will be applied to each child view. See here: http://developer.android.com/reference/android/widget/LinearLayout.html#setDividerPadding(int) – worked Dec 02 '15 at 04:07
  • 2
    This isn't an answer. – Stealth Rabbi Mar 03 '16 at 18:02
  • If you use Space, and you remove/hide one of the children near it, the space is still shown, so this is a bad alternative to a divider, because it might take space that isn't between children. – android developer Dec 12 '17 at 08:42
  • @worked The divider padding is not a solution for the size of the divider, because it's on the opposite coordinates. Even in the docs you can see it. For example, if your LinearLayout has vertical orientation, the padding you get is on the LEFT and RIGHT sides of the dividers. Not above and below it. – android developer Dec 12 '17 at 08:44
26

The sample below just does what you need programatically. I have used a fixed size of (140,398).

LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(140, 398);
        layoutParams.setMargins(24, 0, 24, 0);
        layout.addView(button,layoutParams);
Gorky
  • 1,393
  • 19
  • 21
  • I was doing it with one more additional step like below LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(140, 398); layoutParams.setMargins(24, 0, 24, 0); and then button1.setLayoutParams(layoutParams); layout.addView(button,layoutParams); .. Thanks for letting know that addview can take 2 arguments. – png Mar 15 '12 at 06:40
9

Since API Level 14 you can just add a (transparent) divider drawable:

android:divider="@drawable/divider"
android:showDividers="middle"

and it will handle the rest for you!

teh.fonsi
  • 3,040
  • 2
  • 27
  • 22
  • 1
    Do you need to specify a divider drawable first or can you just use it with nothing else? – Tim Kist Sep 08 '16 at 10:24
  • `8dp` where this came from? – Yousha Aleayoub Sep 21 '16 at 02:15
  • 1
    @TimKist you can use it with nothing else I think – teh.fonsi Jun 23 '17 at 12:45
  • This answer is incorrect because android:dividerPadding does not affect the distance between linear layout children. It applies padding to the sides of the divider that do not face the children (eg left and right padding on a divider in a vertical LinearLayout). Android documentation: https://developer.android.com/reference/android/widget/LinearLayout.html#setDividerPadding(int) – leorleor Aug 16 '17 at 20:45
  • 2
    @leorleor You are right. The best way is probably to use a divider drawable which is transparent. I updated my answer accordingly. – teh.fonsi Sep 12 '17 at 13:08
  • 1
    ... which means the answer to @TimKist 's question is now: No you cannot just use this with nothing else. When you add the line with "divider" in Android Studio it will ask if you want to create a file. Do create one, then copy/paste the rectangle spacer from leorlor's comment above. – Rhubarb Nov 15 '20 at 19:59
  • user changed name in the meantime I guess, the rectangle spacer should be the one in [this answer](https://stackoverflow.com/a/18538656/540776) – superjos May 26 '23 at 15:35
6

You just need to wrap items with linear layouts which have layout_weight. To have items horizontally separated, use this

<LinearLayout
    ...
    ...
  <LinearLayout
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_weight="1"
      android:gravity="center">

      // your item

  </LinearLayout>
</LinearLayout>
Sinan Aktepe
  • 142
  • 1
  • 2
  • If I'm not mistaken the children need to have layout:width="match_parent" and layout_weight="x" (x is arbitrary, just needs to be the same.) You can then actually omit the layout_weight of the linear layout. – Hamburg is nice Mar 04 '21 at 20:57
5

Try to add Space widget after adding view like this:

layout.addView(view)
val space = Space(context)
space.minimumHeight = spaceInterval
layout.addView(space)
Oleg Nekrasov
  • 61
  • 1
  • 1
4

Using padding in the layout of Child View.

layout.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_margin="5dp"
          android:background="@drawable/backage_text"
          android:textColor="#999999"
           >

</TextView>

backage_text.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="@color/white"/>
    <corners android:radius="2dp"/>
    <stroke
        android:width="1dp"
        android:color="#999999"/>
    <padding
        android:bottom="5dp"
        android:left="10dp"
        android:right="10dp"
        android:top="5dp" />
</shape>
Francis Bacon
  • 4,080
  • 1
  • 37
  • 48
3

If you use ActionBarSherlock, you can use com.actionbarsherlock.internal.widget.IcsLinearLayout :

<com.actionbarsherlock.internal.widget.IcsLinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:divider="@drawable/list_view_divider"
        android:dividerPadding="2dp"
        android:showDividers="middle" >
...
</com.actionbarsherlock.internal.widget.IcsLinearLayout>
android developer
  • 114,585
  • 152
  • 739
  • 1,270
3

Use LinearLayout.LayoutParams instead of MarginLayoutParams. Here's the documentation.

Chris Fei
  • 1,327
  • 8
  • 11
  • What attribute would I set in LinearLayout.LayoutParams? That class doesn't seem to have "margins" or "padding" or anything similar? – ab11 Nov 23 '10 at 20:10
  • `LinearLayout.LayoutParams` extends `MarginLayoutParams` and it inherits the same `setMargins()` method you were using above... – Chris Fei Nov 23 '10 at 23:05
  • Ohhhhh, thank you! I was looking at: android.view.ViewGroup.LayoutParams – ab11 Nov 24 '10 at 15:01
3

You can use android:layout_weight="1"

Like This: enter image description here

  • 4
    The question is about the vertical gap between the programmatically created views but your answer doesn't provide any solutions to that. You can review and improve your answer. – aytek Jun 13 '22 at 17:06
1

You can get the LayoutParams of parent LinearLayout and apply to the individual views this way:

LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
lp.setMargins(8,8,8,8);
  • Take care that setMargins() take pixels as int data type.So, convert to dp before adding values
  • Above code will set height and width to wrap_content. you can customise it.
Barry Michael Doyle
  • 9,333
  • 30
  • 83
  • 143
Harish Rana
  • 484
  • 3
  • 8