Topic: 7 Understanding Custom View Layout

This is our seventh topic from learn android from basic to advance series

Topic: 7 Understanding Custom View Layout

Hello devs, Today we talked about Custom View Layouts in Android Kotlin. They let us create unique, visually stunning and super functional UIs that are tailored to our app's style. With Custom Views, we can reuse our favourite design elements across different screens, create interactive and eye-catching components, and make our app stand out.

Custome view layout

Custom view layouts refer to the ability to create specialized user interface components beyond what the standard Android framework offers. Instead of relying solely on pre-built widgets like buttons or text views, custom view layouts allow developers to design and implement their own UI elements with unique functionalities and appearances.

Here's a breakdown of what custom view layouts entail:

  1. Creation of Custom UI Components: With custom view layouts, developers can create custom UI components such as complex graphs, interactive charts, custom progress indicators, or animated elements that are not readily available in the standard Android toolkit.

  2. Reusability Across Screens: Custom views promote reusability by encapsulating specific UI elements into modular components. These components can then be reused across multiple screens within the app, reducing redundancy and making code maintenance more manageable.

  3. Enhanced User Interaction: Custom view layouts enable developers to implement advanced user interactions beyond simple taps or swipes. For example, creating a custom swipe-to-refresh layout with custom animations or designing a draggable view with complex touch handling.

  4. Optimized Performance: Well-designed custom view layouts contribute to optimized app performance by minimizing the view hierarchy complexity, efficiently handling view rendering, and optimizing resource utilization for UI elements.

  5. Brand Consistency: Custom views can be styled and themed to align with the app's branding guidelines, ensuring a consistent and cohesive user experience throughout the application. This helps in maintaining brand identity and visual appeal.

  6. Learning and Experimentation: Building custom view layouts provides opportunities for developers to deepen their understanding of Android's UI capabilities, explore advanced concepts such as custom drawing, touch event handling, and view animations, and expand their skill set as Android developers.

Let's create a custom view layout example by implementing a circular countdown timer with customizable attributes such as timer duration, timer color, and background color. This custom view will display a countdown animation as the timer progresses.

  1. Create a new Kotlin file for your custom countdown timer, let's name it CircularCountdownTimer.kt:

     import android.content.Context
     import android.graphics.Canvas
     import android.graphics.Color
     import android.graphics.Paint
     import android.graphics.RectF
     import android.util.AttributeSet
     import android.view.View
    
     class CircularCountdownTimer(context: Context, attrs: AttributeSet) : View(context, attrs) {
    
         private var timerDuration = 0L // Duration of the countdown timer in milliseconds
         private var timerColor = Color.BLUE // Color of the countdown timer arc
         private var backgroundColor = Color.LTGRAY // Background color of the timer
         private var currentTime = 0L // Current time elapsed in milliseconds
         private var timerProgress = 0f // Progress of the timer arc (0 to 1)
    
         private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
         private val rectF = RectF()
    
         init {
             val typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircularCountdownTimer)
             timerDuration = typedArray.getInt(R.styleable.CircularCountdownTimer_timerDuration, 60).toLong() * 1000 // Convert seconds to milliseconds
             timerColor = typedArray.getColor(R.styleable.CircularCountdownTimer_timerColor, Color.BLUE)
             backgroundColor = typedArray.getColor(R.styleable.CircularCountdownTimer_backgroundColor, Color.LTGRAY)
             typedArray.recycle()
         }
    
         override fun onDraw(canvas: Canvas) {
             super.onDraw(canvas)
    
             val width = width.toFloat()
             val height = height.toFloat()
             val centerX = width / 2
             val centerY = height / 2
             val radius = Math.min(width, height) / 2
    
             // Draw background circle
             paint.color = backgroundColor
             canvas.drawCircle(centerX, centerY, radius, paint)
    
             // Draw timer arc
             paint.color = timerColor
             rectF.set(centerX - radius, centerY - radius, centerX + radius, centerY + radius)
             canvas.drawArc(rectF, -90f, 360f * timerProgress, true, paint)
         }
    
         fun startTimer() {
             // Start the countdown timer
             currentTime = 0L
             post(timerRunnable)
         }
    
         private val timerRunnable = object : Runnable {
             override fun run() {
                 currentTime += TIMER_INTERVAL // Increment timer interval
                 timerProgress = currentTime.toFloat() / timerDuration.toFloat() // Calculate timer progress
    
                 invalidate() // Redraw the view
    
                 if (currentTime < timerDuration) {
                     postDelayed(this, TIMER_INTERVAL) // Schedule the next iteration
                 } else {
                     // Timer has finished
                     timerProgress = 1f
                     invalidate() // Redraw the view
                 }
             }
         }
    
         companion object {
             private const val TIMER_INTERVAL = 100L // Interval for updating timer progress (100 milliseconds)
         }
     }
    
    1. Attributes Initialization:

      • timerDuration: Represents the duration of the countdown timer in milliseconds. It defaults to 0L.

      • timerColor: Specifies the color of the countdown timer arc. The default color is blue.

      • backgroundColor: Sets the background color of the timer. By default, it's light gray.

      • currentTime: Keeps track of the current time elapsed in milliseconds.

      • timerProgress: Indicates the progress of the timer arc, ranging from 0 to 1.

    2. Paint and RectF:

      • paint: An instance of Paint with anti-aliasing enabled, used for drawing shapes and colors.

      • rectF: An instance of RectF used to define the rectangular bounds for drawing the timer arc.

    3. Initialization Block:

      • In the init block, custom attributes (timerDuration, timerColor, backgroundColor) are initialized using values provided in XML layout files (attrs).
    4. onDraw() Method:

      • Overrides the onDraw method to draw the circular countdown timer.

      • Draws a background circle using backgroundColor.

      • Draws a timer arc using timerColor to indicate the progress of the countdown.

    5. startTimer() Method:

      • Initiates the countdown timer by setting currentTime to 0 and posting a Runnable (timerRunnable) for periodic updates.
    6. timerRunnable:

      • Implements a Runnable object that runs periodically to update the timer progress (timerProgress) based on TIMER_INTERVAL.

      • Invalidates the view to trigger a redraw after each update.

      • Stops updating when currentTime reaches timerDuration, indicating that the timer has finished.

    7. Companion Object:

      • Contains a constant TIMER_INTERVAL (100 milliseconds) used as the interval for updating the timer progress.
  2. Define custom attributes for the circular countdown timer in res/values/attrs.xml:

     <declare-styleable name="CircularCountdownTimer">
         <attr name="timerDuration" format="integer"/>
         <attr name="timerColor" format="color"/>
         <attr name="backgroundColor" format="color"/>
     </declare-styleable>
    
    1. timerDuration:

      • Format: integer

      • Description: This attribute defines the duration of the countdown timer in seconds. It specifies the time it takes for the timer to complete its countdown.

    2. timerColor:

      • Format: color

      • Description: This attribute specifies the color of the countdown timer arc. It allows developers to customize the visual appearance of the timer's progress indicator.

    3. backgroundColor:

      • Format: color

      • Description: This attribute sets the background color of the circular countdown timer. It allows customization of the timer's background to suit the application's design or theme.

By defining these attributes within a <declare-styleable> block, developers can easily access and apply these custom attributes to instances of the CircularCountdownTimer view in XML layout files. This provides a convenient way to customize the appearance and behaviour of the countdown timer directly from layout XML files without modifying Java/Kotlin code.

  1. Use your custom countdown timer (CircularCountdownTimer) in your layout XML file (activity_main.xml for example) and customize its attributes:

     <com.yourpackage.CircularCountdownTimer
         android:id="@+id/countdownTimer"
         android:layout_width="200dp"
         android:layout_height="200dp"
         app:timerDuration="60"
         app:timerColor="#FF5722"
         app:backgroundColor="#CCCCCC"
         android:layout_margin="16dp" />
    

    This XML code snippet demonstrates how to integrate the CircularCountdownTimer custom view into an Android layout, and configure its attributes such as duration, colors, size, and margins, allowing developers to create visually appealing and functional countdown timers in their Android applications.

  2. In your activity or fragment, start the countdown timer programmatically:

     val countdownTimer = findViewById<CircularCountdownTimer>(R.id.countdownTimer)
    
     // Start the countdown timer when needed
     countdownTimer.startTimer()
    

This code example demonstrates how to create a custom circular countdown timer with customizable attributes such as timer duration, timer color, and background color in Android Kotlin. The timer will animate as it progresses, providing a visually appealing countdown experience. Adjust the attributes and customize the appearance to fit your app's design and functionality requirements.

It's time to wrap up this topic and end this blog post. I hope you found it helpful so far. I will be back soon with the next topic in this series where we can discuss about Canvas. Looking forward to catching up with you then!


Connect with Me:

Hey there! If you enjoyed reading this blog and found it informative, why not connect with me on LinkedIn? 😊 You can also follow my Instagram page for more mobile development-related content. πŸ“²πŸ‘¨β€πŸ’» Let’s stay connected, share knowledge and have some fun in the exciting world of app development! 🌟

Check out my Instagram page

Check out my LinkedIn

Β