Exploring Jetpack Compose: Android View

E

When it comes to building our UI in jetpack compose, for a lot of applications it will come at a time when our UIs are already build using a mixture of existing solutions – be it XML layouts or custom views. It may even be the case that we have custom views in our current Android project that aren’t quite ready to be converted over to compose just yet, or maybe it doesn’t feel very pragmatic to do so. Regardless which of the above is the case, there are solutions in side of the jetpack compose API that aim to help out in this area.


If you’re enjoying my posts on Jetpack Compose, check out some details on the book I’ll be writing on Compose!


To begin with we have the AndroidView component which allows us to inflate an XML layout as a composable instance:

fun AndroidView(
    @LayoutRes resId: Int, 
    postInflationCallback: (View) -> Unit = { _ -> }
) {
    AndroidViewHolder(
        postInflationCallback = postInflationCallback,
        resId = resId
    )
}

We can see here that there are two available properties that we can pass to the AndroidView function:

  • resId – the id of the layout which we wish to inflate. This is required
  • postInflationCallback – a callback for when the view has been inflated

With the above in mind, we can inflate a layout into our compose UI like so:

AndroidView(resId = R.layout.view_demo)

To see this in action, let’s make use of this AndroidView inside of a composed layout:

Surface(
    modifier = Modifier.padding(16.dp),
    color = Color.White,
    shape = RoundedCornerShape(CornerSize(4.dp))
) {

    Column(modifier = Modifier.padding(16.dp)) {
        AndroidView(resId = R.layout.view_demo)
    }
}

Alongside using the AndroidView component to inflate our XML layouts as composable, we can also embed custom view classes directly within our compose UI. For example, let’s say we have the following custom view class:

class MyCustomView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : AppCompatTextView(context, attrs, defStyleAttr) {

    init {
        layoutParams = ViewGroup.LayoutParams(MATCH_PARENT, WRAP_CONTENT)
        text = "Hello there!"
    }

}

We can then embed that view directly within our compose layout, similar to how we previously would have done when added views to our layouts programatically:

Surface(
    modifier = Modifier.padding(16.dp),
    color = Color.White,
    shape = RoundedCornerShape(CornerSize(4.dp))
) {

    Column(modifier = Modifier.padding(16.dp)) {
        MyCustomView(context = ContextAmbient.current)
    }
}

In this post we’ve taken a quick dive into embedded Custom Android Views and XML layouts inside of our existing composables. Stay tuned for the next post and in the meantime, subscribe to updates on my Jetpack Compose book 🙂

About the author

hitherejoe

Add Comment