custom view
resize views
programmatically
mobile development
UI design

How to resize a custom view programmatically?

Master System Design with Codemia

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

Introduction

To resize a custom view programmatically, modify its layout parameters or constraints. On Android, update LayoutParams and call requestLayout(). On iOS, modify Auto Layout constraints or set the frame directly. Both platforms support animated resizing. The approach depends on whether the view uses Auto Layout/ConstraintLayout or manual frame-based positioning.

Android: Using LayoutParams

kotlin
1// Get the view's current layout params and modify
2val view = findViewById<View>(R.id.customView)
3val params = view.layoutParams
4
5params.width = 500   // pixels
6params.height = 300  // pixels
7view.layoutParams = params  // Triggers re-layout
8
9// Using dp instead of pixels
10fun Int.dpToPx(context: Context): Int =
11    (this * context.resources.displayMetrics.density).toInt()
12
13params.width = 200.dpToPx(this)
14params.height = 150.dpToPx(this)
15view.layoutParams = params

ConstraintLayout Specific

kotlin
1import androidx.constraintlayout.widget.ConstraintLayout
2
3val view = findViewById<View>(R.id.customView)
4val params = view.layoutParams as ConstraintLayout.LayoutParams
5
6// Set size
7params.width = ConstraintLayout.LayoutParams.MATCH_CONSTRAINT  // 0dp
8params.height = 200.dpToPx(this)
9
10// Set constraints
11params.startToStart = ConstraintLayout.LayoutParams.PARENT_ID
12params.topToTop = ConstraintLayout.LayoutParams.PARENT_ID
13params.matchConstraintPercentWidth = 0.5f  // 50% of parent
14
15view.layoutParams = params

Match Parent and Wrap Content

kotlin
1val params = view.layoutParams
2
3// Match parent
4params.width = ViewGroup.LayoutParams.MATCH_PARENT
5params.height = ViewGroup.LayoutParams.WRAP_CONTENT
6view.layoutParams = params
7
8// Specific size constants
9params.width = ViewGroup.LayoutParams.MATCH_PARENT   // -1
10params.height = ViewGroup.LayoutParams.WRAP_CONTENT   // -2

Animated Resize on Android

kotlin
1import android.animation.ValueAnimator
2
3fun animateResize(view: View, targetWidth: Int, targetHeight: Int) {
4    val startWidth = view.width
5    val startHeight = view.height
6
7    val animator = ValueAnimator.ofFloat(0f, 1f)
8    animator.duration = 300
9
10    animator.addUpdateListener { animation ->
11        val fraction = animation.animatedFraction
12        val params = view.layoutParams
13        params.width = (startWidth + (targetWidth - startWidth) * fraction).toInt()
14        params.height = (startHeight + (targetHeight - startHeight) * fraction).toInt()
15        view.layoutParams = params
16    }
17
18    animator.start()
19}
20
21// Usage
22animateResize(customView, 400.dpToPx(this), 300.dpToPx(this))

iOS: Using Auto Layout Constraints

swift
1import UIKit
2
3class ViewController: UIViewController {
4    let customView = UIView()
5    var widthConstraint: NSLayoutConstraint!
6    var heightConstraint: NSLayoutConstraint!
7
8    override func viewDidLoad() {
9        super.viewDidLoad()
10
11        customView.backgroundColor = .systemBlue
12        customView.translatesAutoresizingMaskIntoConstraints = false
13        view.addSubview(customView)
14
15        widthConstraint = customView.widthAnchor.constraint(equalToConstant: 200)
16        heightConstraint = customView.heightAnchor.constraint(equalToConstant: 200)
17
18        NSLayoutConstraint.activate([
19            customView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
20            customView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
21            widthConstraint,
22            heightConstraint
23        ])
24    }
25
26    func resizeView(width: CGFloat, height: CGFloat) {
27        widthConstraint.constant = width
28        heightConstraint.constant = height
29        view.layoutIfNeeded()  // Apply immediately
30    }
31}

Animated Resize on iOS

swift
1func animateResize(width: CGFloat, height: CGFloat) {
2    widthConstraint.constant = width
3    heightConstraint.constant = height
4
5    UIView.animate(withDuration: 0.3, delay: 0,
6                   options: .curveEaseInOut) {
7        self.view.layoutIfNeeded()
8    }
9}
10
11// With spring animation
12func springResize(width: CGFloat, height: CGFloat) {
13    widthConstraint.constant = width
14    heightConstraint.constant = height
15
16    UIView.animate(withDuration: 0.5, delay: 0,
17                   usingSpringWithDamping: 0.6,
18                   initialSpringVelocity: 0.5,
19                   options: []) {
20        self.view.layoutIfNeeded()
21    }
22}

Frame-Based Resizing (No Auto Layout)

swift
1// Direct frame modification
2customView.frame = CGRect(x: 50, y: 100, width: 300, height: 200)
3
4// Resize only (keep position)
5customView.frame.size = CGSize(width: 300, height: 200)
6
7// Animated frame resize
8UIView.animate(withDuration: 0.3) {
9    self.customView.frame = CGRect(x: 50, y: 100, width: 400, height: 300)
10}

SwiftUI

swift
1import SwiftUI
2
3struct ResizableView: View {
4    @State private var width: CGFloat = 200
5    @State private var height: CGFloat = 200
6
7    var body: some View {
8        VStack {
9            Rectangle()
10                .fill(Color.blue)
11                .frame(width: width, height: height)
12                .animation(.spring(), value: width)
13
14            Button("Resize") {
15                width = width == 200 ? 300 : 200
16                height = height == 200 ? 150 : 200
17            }
18        }
19    }
20}

Android Jetpack Compose

kotlin
1@Composable
2fun ResizableBox() {
3    var expanded by remember { mutableStateOf(false) }
4    val size by animateDpAsState(
5        targetValue = if (expanded) 300.dp else 150.dp,
6        animationSpec = spring(dampingRatio = 0.5f)
7    )
8
9    Box(
10        modifier = Modifier
11            .size(size)
12            .background(Color.Blue)
13            .clickable { expanded = !expanded }
14    )
15}

Resize Based on Content

kotlin
1// Android: measure and resize to fit content
2val view = findViewById<TextView>(R.id.textView)
3view.measure(
4    View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
5    View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
6)
7val params = view.layoutParams
8params.width = view.measuredWidth
9params.height = view.measuredHeight
10view.layoutParams = params
swift
1// iOS: size to fit content
2customView.sizeToFit()
3
4// Or with intrinsic content size
5let intrinsicSize = customView.intrinsicContentSize
6widthConstraint.constant = intrinsicSize.width
7heightConstraint.constant = intrinsicSize.height

Common Pitfalls

  • Setting frame on a view that uses Auto Layout (iOS): If translatesAutoresizingMaskIntoConstraints is false, setting frame directly is overridden by constraints on the next layout pass. Modify constraint constants instead of the frame when using Auto Layout.
  • Forgetting to call requestLayout() or layoutParams = params (Android): Simply modifying the LayoutParams object without reassigning it to the view does not trigger a re-layout. Always call view.layoutParams = params or view.requestLayout().
  • Animating constraints without calling layoutIfNeeded() (iOS): Changing constraint constants inside UIView.animate does nothing visible. You must call self.view.layoutIfNeeded() inside the animation block to animate the layout change.
  • Using pixel values instead of dp on Android: Hardcoding pixel values produces different results on different screen densities. Always convert dp to pixels using density * dp or use dimension resources.
  • Resizing before the view is laid out: Accessing view.width or view.height in onCreate / viewDidLoad returns 0 because layout has not occurred yet. Use view.post { ... } (Android) or viewDidLayoutSubviews (iOS) to read or modify sizes after the initial layout pass.

Summary

  • Android: Modify view.layoutParams (width/height) and reassign to trigger re-layout
  • iOS Auto Layout: Modify constraint constants and call layoutIfNeeded()
  • iOS Frame: Set view.frame or view.bounds directly (only without Auto Layout)
  • Animate resizes with ValueAnimator (Android) or UIView.animate (iOS)
  • Use dp (Android) and points (iOS) instead of raw pixels for density-independent sizing

Course illustration
Course illustration

All Rights Reserved.