Introduction
In modern Android app development, Jetpack Compose has gained significant traction as a declarative UI toolkit, enabling developers to create user interfaces more efficiently. One of the standout features of Jetpack Compose is the ability to integrate legacy views, such as those built with View classes from the Android framework, into Compose's declarative system. This is made possible by the AndroidView composable function, which bridges the gap between traditional View components and Jetpack Compose layouts.
In this article, we will explore a practical example that demonstrates the use of the AndroidView modifier in Jetpack Compose. This example integrates a traditional TextView inside a Jetpack Compose UI, wraps it with modern Compose modifiers such as border, background, and clip, and displays it within a Box layout. By the end, you'll understand how to combine classic Android Views with Compose elements seamlessly.
The MainActivity and Scaffold Setup
The application begins with a basic MainActivity class, inheriting from AppCompatActivity, which is the standard setup for most Android apps. The onCreate method calls the setContent function, which sets the entire layout of the activity to be managed by Compose. The layout is composed by the GetScaffold function.
In the GetScaffold function, a Scaffold is used to structure the app. A Scaffold is a common layout component in Jetpack Compose that provides slots for the top bar, bottom bar, floating action buttons, and the main content. In this example, the top bar is defined by the TopAppBar composable, which displays a title with a customized background color. The content section is filled by the MainContent function.
Composing the Main Content with AndroidView
The core of this example lies in the MainContent function. It places an AndroidView inside a Box layout. Box is a composable that stacks its children on top of each other, and in this case, it's set to fill the entire screen using the Modifier.fillMaxSize() modifier. The content is aligned to the center using the contentAlignment parameter set to Alignment.Center.
The AndroidView composable is the key here. It allows the integration of traditional Android Views into a Compose UI. In this example, the AndroidView creates a TextView within its factory parameter. This TextView is then customized with text, text size, and gravity properties, giving it a typical Android look and behavior. The TextView displays the text "TextView AndroidView" with a text size of 24sp and centers the text within the view using Gravity.CENTER.
Applying Modern Compose Modifiers
While the TextView is a traditional view, it is enhanced using Jetpack Compose's powerful Modifier system. These modifiers allow Compose to control how the TextView looks and behaves within the layout.
First, the Modifier.size(250.dp) constrains the view to a specific size, ensuring it remains within a circular area. Then, clip(CircleShape) is used to apply a circular clipping mask to the TextView, transforming it into a circle. After that, a red border with a thickness of 10dp is added using the border modifier, followed by a background color of orange (Color(0xFFED872D)), which fills the circle behind the TextView. The padding(24.dp) modifier adds internal space around the TextView, and wrapContentSize(Alignment.Center) ensures the content inside the TextView stays centered.
Summary
In summary, this example showcases how Jetpack Compose's AndroidView composable can be used to integrate classic Android Views, such as TextView, into a Compose UI, while still applying modern Compose modifiers. The combination of the AndroidView with Compose's modifier system results in a clean and highly customizable UI component that blends the best of both worlds.
This approach is particularly useful when transitioning from traditional Android views to Jetpack Compose or when reusing complex View-based components within new Compose-based applications. With this seamless integration, developers can modernize their UIs without completely rewriting existing components, allowing for a smoother migration to Jetpack Compose.
package com.cfsuman.jetpackcompose
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.Gravity
import android.widget.TextView
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.graphics.Color
import androidx.compose.material.Text
import androidx.compose.material.TopAppBar
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            GetScaffold()
        }
    }
    @Composable
    fun GetScaffold(){
        Scaffold(
            topBar = {
                TopAppBar(
                    title = { Text(
                        text = "Compose - AndroidView Modifier"
                    )},
                    backgroundColor = Color(0xFFC0E8D5),
                )
            },
            content = {MainContent()},
            backgroundColor = Color(0xFFEDEAE0),
        )
    }
    @Composable
    fun MainContent(){
        Box(
            modifier = Modifier.fillMaxSize(),
            contentAlignment = Alignment.Center
        ){
            AndroidView(factory = { context ->
                TextView(context).apply {
                    text = "TextView AndroidView"
                    textSize = 24F
                    gravity = Gravity.CENTER
                }
            },
                modifier = Modifier
                    .size(250.dp)
                    .clip(CircleShape)
                    .border(
                        width = 10.dp,
                        color = Color(0xFFE30022),
                        shape = CircleShape
                    )
                    .background(Color(0xFFED872D))
                    .padding(24.dp)
                    .wrapContentSize(Alignment.Center)
            )
        }
    }
}
- jetpack compose - Row onClick
 - jetpack compose - Row weight
 - jetpack compose - Column weight
 - jetpack compose - Row gravity
 - jetpack compose - Row background
 - jetpack compose - Column align bottom
 - jetpack compose - Box gravity
 - jetpack compose - Card center
 - jetpack compose - Card padding
 - jetpack compose - Card background color
 - jetpack compose - How to use AndroidView
 - jetpack compose - How to update AndroidView
 - jetpack compose - AndroidView click event
 - jetpack compose - How to use bottom navigation