ImageView
Android development
programmatic layout
margin setting
Android UI coding

How to set margin of ImageView using code, not xml

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Setting margins in Android code is mostly about choosing the correct layout parameters for the view's parent. An ImageView does not own its own margin model, so you update the margin fields on the LayoutParams instance attached to that view.

How Android Margins Work

Margins are defined by ViewGroup.MarginLayoutParams, and most common parent layouts expose a subclass of that type. That detail matters because the object returned by imageView.layoutParams must match the container that holds the view. If the parent is a LinearLayout, use LinearLayout.LayoutParams. If the parent is a ConstraintLayout, use ConstraintLayout.LayoutParams.

A reliable pattern is:

  1. Create or obtain the ImageView.
  2. Read its current layout params.
  3. Cast them to a margin-capable type.
  4. Set the margins in pixels.
  5. Assign the params back or call requestLayout().

If you are adding the view entirely in code, you can build the params up front.

Setting Margins In Kotlin

The following example adds an ImageView to a LinearLayout and sets a start and top margin in density-independent units.

kotlin
1import android.os.Bundle
2import android.util.TypedValue
3import android.widget.ImageView
4import android.widget.LinearLayout
5import androidx.appcompat.app.AppCompatActivity
6
7class MainActivity : AppCompatActivity() {
8    override fun onCreate(savedInstanceState: Bundle?) {
9        super.onCreate(savedInstanceState)
10
11        val container = LinearLayout(this).apply {
12            orientation = LinearLayout.VERTICAL
13        }
14
15        val imageView = ImageView(this).apply {
16            setImageResource(android.R.drawable.ic_menu_camera)
17        }
18
19        val params = LinearLayout.LayoutParams(
20            LinearLayout.LayoutParams.WRAP_CONTENT,
21            LinearLayout.LayoutParams.WRAP_CONTENT
22        )
23
24        val margin = dpToPx(16)
25        params.setMargins(margin, margin, 0, 0)
26
27        imageView.layoutParams = params
28        container.addView(imageView)
29        setContentView(container)
30    }
31
32    private fun dpToPx(value: Int): Int {
33        return TypedValue.applyDimension(
34            TypedValue.COMPLEX_UNIT_DIP,
35            value.toFloat(),
36            resources.displayMetrics
37        ).toInt()
38    }
39}

The setMargins call expects pixel values. Converting from dp keeps spacing visually consistent across devices.

Updating An Existing ImageView

If the view already exists in the hierarchy, retrieve the current params and update them instead of creating a new ImageView. This is common when reacting to state changes.

kotlin
1val imageView = findViewById<ImageView>(R.id.avatar)
2val params = imageView.layoutParams as ViewGroup.MarginLayoutParams
3val horizontal = dpToPx(12)
4val vertical = dpToPx(8)
5
6params.marginStart = horizontal
7params.topMargin = vertical
8imageView.layoutParams = params
9imageView.requestLayout()

Using ViewGroup.MarginLayoutParams is often enough when you only need margins, but you still need a parent layout that actually produced a compatible subclass.

Java Example

If your project is still using Java, the same rule applies.

java
1ImageView imageView = findViewById(R.id.avatar);
2ViewGroup.MarginLayoutParams params =
3        (ViewGroup.MarginLayoutParams) imageView.getLayoutParams();
4
5int margin = (int) TypedValue.applyDimension(
6        TypedValue.COMPLEX_UNIT_DIP,
7        20,
8        getResources().getDisplayMetrics());
9
10params.setMargins(margin, margin, margin, margin);
11imageView.setLayoutParams(params);
12imageView.requestLayout();

The important part is not the language. It is the type of layout params and the conversion from dp to pixels.

Parent-Specific Cases

Some layouts add extra positioning rules on top of margin support.

For ConstraintLayout, margins apply only after you define constraints. An image with margins but no constraints may still appear in an unexpected position.

kotlin
1val params = ConstraintLayout.LayoutParams(
2    ConstraintLayout.LayoutParams.WRAP_CONTENT,
3    ConstraintLayout.LayoutParams.WRAP_CONTENT
4).apply {
5    startToStart = ConstraintLayout.LayoutParams.PARENT_ID
6    topToTop = ConstraintLayout.LayoutParams.PARENT_ID
7    marginStart = dpToPx(24)
8    topMargin = dpToPx(16)
9}
10
11imageView.layoutParams = params

For FrameLayout, margins work, but there is no sibling flow like in LinearLayout. You usually combine margins with gravity if you want the image anchored to a corner.

Common Pitfalls

Using the wrong LayoutParams type is the most common failure. Casting to LinearLayout.LayoutParams when the parent is actually a ConstraintLayout throws ClassCastException. Inspect the parent or use ViewGroup.MarginLayoutParams when appropriate.

Another issue is passing raw integers and assuming they mean dp. Android interprets those values as pixels, so spacing looks tiny on high-density screens. Always convert display units with TypedValue.applyDimension or a utility extension.

It is also easy to forget that margins belong to the child within the parent. Padding affects the inside of the ImageView, not the distance outside it. If the goal is to create space between the image and surrounding views, use margins, not padding.

Finally, changing params without reassigning them can fail on some code paths. Updating the object and then setting imageView.layoutParams = params makes the intent explicit and avoids stale layout behavior.

Summary

  • Margins on an ImageView are controlled by the view's LayoutParams, not by the ImageView itself.
  • Use a params type that matches the parent layout, such as LinearLayout.LayoutParams or ConstraintLayout.LayoutParams.
  • Convert dp values to pixels before calling setMargins or setting topMargin, marginStart, and related fields.
  • For existing views, update the current params and call requestLayout() after reassignment.
  • Distinguish margins from padding so spacing changes affect the correct part of the layout.

Course illustration
Course illustration

All Rights Reserved.