204

I want to add an unknown number of ImageView views to my layout with margin. In XML, I can use layout_margin like this:

<ImageView android:layout_margin="5dip" android:src="@drawable/image" />

There is ImageView.setPadding(), but no ImageView.setMargin(). I think it's along the lines of ImageView.setLayoutParams(LayoutParams), but not sure what to feed into that.

Does anyone know?

Ahmed Salman Tahir
  • 1,783
  • 1
  • 17
  • 26
Bruce Lee
  • 3,049
  • 3
  • 20
  • 13

16 Answers16

403

android.view.ViewGroup.MarginLayoutParams has a method setMargins(left, top, right, bottom). Direct subclasses are: FrameLayout.LayoutParams, LinearLayout.LayoutParams and RelativeLayout.LayoutParams.

Using e.g. LinearLayout:

LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
lp.setMargins(left, top, right, bottom);
imageView.setLayoutParams(lp);

MarginLayoutParams

This sets the margins in pixels. To scale it use

context.getResources().getDisplayMetrics().density

DisplayMetrics

Ahmed Salman Tahir
  • 1,783
  • 1
  • 17
  • 26
Key
  • 6,986
  • 1
  • 23
  • 15
  • 21
    Note that this sets margin size in PIXELS, is not the same as the dpi unit in the xml of this question. – aromero Jan 13 '12 at 12:41
  • How can we use a dpi value instead of pixel? – Pascal Piché Mar 07 '12 at 17:19
  • 10
    You can scale the px value using context.getResources().getDisplayMetrics().density http://developer.android.com/reference/android/util/DisplayMetrics.html#density – Key Mar 09 '12 at 14:03
  • 1
    Note, that there can be problems with `FrameLayout.LayoutParams` and maybe with other: http://stackoverflow.com/questions/5401952/framelayout-margin-not-working – Dmitry Zaytsev Aug 21 '12 at 09:34
  • in case we wanted to set only the bottom margin of the image view which is `android:layout_centerHorizontal = "true"` and `android:layout_alignParentBottom = "true"` in waht way I could accomplish this? – ssrp Nov 29 '12 at 10:53
  • What if the Parent is a TabHost? – Syed Arsalan Kazmi Feb 24 '16 at 12:22
  • Didn't work with a radiobutton, any idea about this? – Ali Obeid Jun 11 '17 at 15:01
53
    image = (ImageView) findViewById(R.id.imageID);
    MarginLayoutParams marginParams = new MarginLayoutParams(image.getLayoutParams());
    marginParams.setMargins(left_margin, top_margin, right_margin, bottom_margin);
    RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(marginParams);
    image.setLayoutParams(layoutParams);
Kevin Wadera
  • 529
  • 4
  • 3
  • 5
    What's the deal w/ the last 2 lines? clone the margin params into another params variable? I can confirm it's required :) – Adam Rabung Sep 01 '11 at 13:06
  • 1
    in case we wanted to set only the bottom margin of the image view which is `android:layout_centerHorizontal = "true"` and `android:layout_alignParentBottom = "true"` in waht way I could accomplish this? – ssrp Nov 29 '12 at 11:04
  • layoutparams.addRule(RelativeLayout.CENTER_HORIZONTAL); – cwhsu May 19 '14 at 13:06
  • Creating another layout params is required. Thanks :) – Muzaffer Dec 02 '15 at 11:56
51

All the above examples will actually REPLACE any params already present for the View, which may not be desired. The below code will just extend the existing params, without replacing them:

ImageView myImage = (ImageView) findViewById(R.id.image_view);
MarginLayoutParams marginParams = (MarginLayoutParams) image.getLayoutParams();
marginParams.setMargins(left, top, right, bottom);
Kelevandos
  • 7,024
  • 2
  • 29
  • 46
  • 2
    This is the first solution in this list that worked for me. The others screwed up the other params that I had set in the XML, including RelativeLayout params for positioning. – Chris Dutrow May 18 '17 at 02:57
22

Kevin's code creates redundant MarginLayoutParams object. Simpler version:

ImageView image = (ImageView) findViewById(R.id.main_image);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(image.getLayoutParams());
lp.setMargins(50, 100, 0, 0);
image.setLayoutParams(lp);
Adam Stelmaszczyk
  • 19,665
  • 4
  • 70
  • 110
  • 1
    Weirdly enough I then get "Cannot resolve method setmargins()" which is why I googled for this question and landed here. – user2875404 Aug 06 '15 at 08:30
14

If you want to change imageview margin but leave all other margins intact.

  1. Get MarginLayoutParameters of your image view in this case: myImageView

     MarginLayoutParams marginParams = (MarginLayoutParams) myImageView.getLayoutParams();
    
  2. Now just change the margin you want to change but leave the others as they are:

     marginParams.setMargins(marginParams.leftMargin, 
                             marginParams.topMargin, 
                             150, //notice only changing right margin
                             marginParams.bottomMargin); 
    
CommonSenseCode
  • 23,522
  • 33
  • 131
  • 186
10

Answer from 2020 year :

dependencies {
    implementation "androidx.core:core-ktx:1.2.0"
}

and cal it simply in your code

view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
   setMargins(5)
}
i30mb1
  • 3,894
  • 3
  • 18
  • 34
9

I use simply this and works great:

ImageView imageView = (ImageView) findViewById(R.id.image_id);
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) imageView.getLayoutParams();
layoutParams.setMargins(left, top, right, bottom);
imageView.setLayoutParams(layoutParams);

setMargins()'s unit is pixel not dp. If you want to set margin in dp, just inside your values/dimens.xml file create your dimensions like:

<resources>
    <dimen name="right">16dp</dimen>
    <dimen name="left">16dp</dimen>    
</resources>

and access like:

getResources().getDimension(R.dimen.right);
Elnoor
  • 3,401
  • 4
  • 24
  • 39
9

If you use kotlin, this can be simplified by creating an extension function

fun View.setMarginExtensionFunction(left: Int, top: Int, right: Int, bottom: Int) {
  val params = layoutParams as ViewGroup.MarginLayoutParams
  params.setMargins(left, top, right, bottom)
  layoutParams = params
}

Now all you need is a view, and this extension function can be used anywhere.

val imageView = findViewById(R.id.imageView)
imageView.setMarginExtensionFunction(0, 0, 0, 0)
enyciaa
  • 1,982
  • 1
  • 14
  • 24
  • 1
    this works for `left` and `right` margins, but if you have relative margins (`start` and `end`) it doesn't work. I wrote a gist with a 'improved' version of your code: https://gist.github.com/Grohden/f40c53bf86c5395638f7a44bf90e732d (the `setMarginsRelative` function) - could you include that in your answer? – Gabriel Rohden Mar 15 '19 at 18:02
8

You can use this method, in case you want to specify margins in dp:

private void addMarginsInDp(View view, int leftInDp, int topInDp, int rightInDp, int bottomInDp) {
    DisplayMetrics dm = view.getResources().getDisplayMetrics();
    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    lp.setMargins(convertDpToPx(leftInDp, dm), convertDpToPx(topInDp, dm), convertDpToPx(rightInDp, dm), convertDpToPx(bottomInDp, dm));
    view.setLayoutParams(lp);
}

private int convertDpToPx(int dp, DisplayMetrics displayMetrics) {
    float pixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, displayMetrics);
    return Math.round(pixels);
}
divonas
  • 992
  • 1
  • 10
  • 11
4

create layout dynamically and set its parameter as setmargin() will not work directly on an imageView

ImageView im;
im = (ImageView) findViewById(R.id.your_image_in_XML_by_id);
 RelativeLayout.LayoutParams layout = new RelativeLayout.LayoutParams(im.getLayoutParams());
                        layout.setMargins(counter*27, 0, 0, 0);//left,right,top,bottom
                        im.setLayoutParams(layout);
                        im.setImageResource(R.drawable.yourimage)
ExploringAI
  • 451
  • 9
  • 12
4

For me this worked:

int imgCarMarginRightPx = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, definedValueInDp, res.getDisplayMetrics());

MarginLayoutParams lp = (MarginLayoutParams) imgCar.getLayoutParams();
lp.setMargins(0,0,imgCarMarginRightPx,0);
imgCar.setLayoutParams(lp);
Wahib Ul Haq
  • 4,185
  • 3
  • 44
  • 41
2

sample code is here ,its very easy

LayoutParams params1 = (LayoutParams)twoLetter.getLayoutParams();//twoletter-imageview
                params1.height = 70;
                params1.setMargins(0, 210, 0, 0);//top margin -210 here
                twoLetter.setLayoutParams(params1);//setting layout params
                twoLetter.setImageResource(R.drawable.oo);
Sydroid
  • 509
  • 1
  • 8
  • 16
2

In Kotlin you can write it in more pleasant way

myView.layoutParams = LinearLayout.LayoutParams(
                RadioGroup.LayoutParams.MATCH_PARENT, RadioGroup.LayoutParams.WRAP_CONTENT
            ).apply {
                setMargins(12, 12, 12, 12)
            }
anil
  • 2,083
  • 21
  • 37
1

Here is an example to add 8px Margin on left, top, right, bottom.


ImageView imageView = new ImageView(getApplicationContext());

ViewGroup.MarginLayoutParams marginLayoutParams = new ViewGroup.MarginLayoutParams(
    ViewGroup.MarginLayoutParams.MATCH_PARENT,
    ViewGroup.MarginLayoutParams.WRAP_CONTENT
);

marginLayoutParams.setMargins(8, 8, 8, 8);

imageView.setLayoutParams(marginLayoutParams);

Md. Zubaer Ahammed
  • 931
  • 11
  • 13
0

Using a method similar to this might save you some headaches in some situations. If you have two passes of programmatical tinkering with margins it is safer to check if there are already some layoutParams set. If there are some margins already one should increase them and not replace them:

public void addMargins(View v, int left, int top, int right, int bottom) {
    LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) v.getLayoutParams();
    if (params == null)
        params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                                               ViewGroup.LayoutParams.WRAP_CONTENT);
    int oldLeft = params.leftMargin;
    int oldTop = params.topMargin;
    int oldRight = params.rightMargin;
    int oldBottom = params.bottomMargin;
    params.setMargins(oldLeft + left, oldTop + top, oldRight + right, oldBottom + bottom);
    v.setLayoutParams(params);
}
GA1
  • 1,568
  • 2
  • 19
  • 30
0

We can create Linear LayoutParams & use resources.getDimensionPixelSize for dp value.

    val mContext = parent.context
    val mImageView = AppCompatImageView(mContext)
    mImageView.setBackgroundResource(R.drawable.payment_method_selector)

    val height = mContext.resources.getDimensionPixelSize(R.dimen.payment_logo_height)
    val width = mContext.resources.getDimensionPixelSize(R.dimen.payment_logo_width)
    val padding = mContext.resources.getDimensionPixelSize(R.dimen.spacing_small_tiny)
    val margin = mContext.resources.getDimensionPixelSize(R.dimen.spacing_small)

    mImageView.layoutParams = LinearLayout.LayoutParams(width, height).apply {
        setMargins(margin, margin, 0, 0)
    }
    mImageView.setPadding(padding, padding, padding, padding)
Shihab Uddin
  • 6,699
  • 2
  • 59
  • 74