Android
Programmatically
Width and Height
dp Units
Development

Android and setting width and height programmatically in dp units

Master System Design with Codemia

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

Introduction

In Android code, layout width and height are applied in pixels, even though designers and XML layouts usually describe sizes in dp. That means runtime resizing always starts with a unit conversion step. The important part is not just changing layoutParams, but doing it with the right density calculation and the right parameter type for the parent layout.

Convert dp to Pixels Correctly

A dp value is density-independent. layoutParams.width and layoutParams.height are not. To bridge that gap, convert dp to pixels using the device display metrics.

In Kotlin, a compact helper looks like this:

kotlin
1import android.content.Context
2import android.util.TypedValue
3
4fun dpToPx(context: Context, dp: Float): Int {
5    return TypedValue.applyDimension(
6        TypedValue.COMPLEX_UNIT_DIP,
7        dp,
8        context.resources.displayMetrics
9    ).toInt()
10}

Using Android's built-in conversion avoids mistakes such as hard-coding a density multiplier or assuming all screens map 1dp to the same pixel count.

Update Layout Params at Runtime

Once you have pixel values, modify the view's layoutParams and assign them back to the view.

kotlin
1import android.os.Bundle
2import android.widget.Button
3import androidx.appcompat.app.AppCompatActivity
4
5class MainActivity : AppCompatActivity() {
6    override fun onCreate(savedInstanceState: Bundle?) {
7        super.onCreate(savedInstanceState)
8        setContentView(R.layout.activity_main)
9
10        val button = findViewById<Button>(R.id.myButton)
11        val params = button.layoutParams
12
13        params.width = dpToPx(this, 160f)
14        params.height = dpToPx(this, 48f)
15
16        button.layoutParams = params
17    }
18}

That is enough for simple size changes. Android will request layout again after the updated parameters are applied.

Use the Correct LayoutParams Subclass

If you only need width and height, the generic ViewGroup.LayoutParams fields are enough. If you also need margins, gravity, or constraint rules, the actual parent layout starts to matter.

For example, margins require a subclass that supports them:

kotlin
1import android.view.ViewGroup
2import android.widget.ImageView
3
4val image = findViewById<ImageView>(R.id.avatar)
5val params = image.layoutParams as ViewGroup.MarginLayoutParams
6
7params.width = dpToPx(this, 72f)
8params.height = dpToPx(this, 72f)
9params.marginStart = dpToPx(this, 16f)
10params.topMargin = dpToPx(this, 8f)
11
12image.layoutParams = params

If the parent is a ConstraintLayout, LinearLayout, or FrameLayout, each has its own parameter class for layout-specific behavior. Width and height may still work on the base type, but anything more advanced usually needs the correct subclass.

Know When to Use Layout Constants Instead

Not every dimension should be expressed as dp. Sometimes the correct runtime value is MATCH_PARENT or WRAP_CONTENT, just as it would be in XML.

kotlin
1import android.view.ViewGroup
2import android.widget.TextView
3
4val textView = findViewById<TextView>(R.id.message)
5val params = textView.layoutParams
6
7params.width = ViewGroup.LayoutParams.MATCH_PARENT
8params.height = ViewGroup.LayoutParams.WRAP_CONTENT
9
10textView.layoutParams = params

This matters because developers sometimes over-convert everything to pixels when the real layout rule is about relationship to content or parent size, not fixed physical size.

Timing Matters for Some Layout Changes

If you are setting a fixed dp size, changing layout params in onCreate often works fine. If the new size depends on measured width, measured height, or the final parent layout, run the code later using post, a layout listener, or another callback that fires after measurement.

kotlin
1button.post {
2    val params = button.layoutParams
3    params.width = button.width / 2
4    button.layoutParams = params
5}

This is a different case from dp conversion, but it often appears in the same code path and causes confusion if the view has not been measured yet.

Prefer XML for Static Sizes

Programmatic resizing is appropriate when the dimension depends on runtime logic such as feature flags, user interaction, downloaded content, or dynamically created views. If the size is fixed for all users, XML is usually the better place because it is easier to inspect and maintain.

A good rule is: if the size never changes after layout inflation, put it in XML. If it truly depends on code-time decisions, set it programmatically.

Common Pitfalls

The most common mistake is assigning a dp number directly to layoutParams.width or layoutParams.height. Android interprets that number as pixels, so the view ends up too small or too large depending on screen density.

Another problem is casting to the wrong LayoutParams class. A cast that does not match the parent layout will fail at runtime or will hide the fields you actually need.

Developers also forget to reassign the modified params back to the view. Updating the local params object alone is not enough.

Summary

  • Android layout params use pixels at runtime, not dp.
  • Convert dp to pixels with TypedValue.applyDimension or an equivalent helper.
  • Update the view's layoutParams and assign them back to the view.
  • Use the correct LayoutParams subclass when you need margins or layout-specific rules.
  • Prefer XML for fixed sizes and runtime code only when the size really depends on runtime behavior.

Course illustration
Course illustration

All Rights Reserved.