简体   繁体   中英

How to migrate my custom view to Jetpack Compose?

I have a custom view created the traditional way: subclassing from the View class.

Specifically, my custom view has many custom attributes (and their corresponding Kotlin properties) that can be assigned in the XML layout:

<com.example.MyCustomView
    app:myCustomAttr1 = "..."
    app:myCustomAttr2 = "..."/>

How to provide a View version of my composable so users can use it in XML?

Besides using AndroidView class to load a conventional Android view in Jetpack Compose, how can I convert my view to be a "true" Compose component?

Should I provide a separate composable for every part of my custom view? For example, a composable for the pie, another composable for the legend box?

Android developer documentation does not mention how to transform custom views to Compose.

Assuming I have created a composable version of my view like this:

@Composable fun MyComposable(title: String) {
    Text(title)
}

to use that composable like a regular View (with the ability to specify its attributes in XML), we should create a custom view subclassing from AbstractComposeView :

// Do not forget these two imports for the delegation (by) to work
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue

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

    var myProperty by mutableStateOf("A string")

    init {
        // See the footnote
        context.withStyledAttributes(attrs, R.styleable.MyStyleable) {
            myProperty = getString(R.styleable.MyStyleable_myAttribute)
        }
    }

    // The important part
    @Composable override fun Content() {
        MyComposable(title = myProperty)
    }
}

And this is how we would use it just like a regular view in XML:

<my.package.name.MyCustomView
    android:id="@+id/myView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:myAttribute="Helloooooooooo!" />

and/or in an activity:

val myCustomView = findViewById<MyCustomView>(R.id.myView)
myCustomView.myProperty = "Woohoo!"

Thanks to ProAndroidDev for this article .

Footnote

To define your own custom attributes for your view, see this post .
Also, make sure to use -ktx version of the AndroidX Core library to be able to access useful Kotlin extension functions like Context::withStyledAttributes :

implementation("androidx.core:core-ktx:1.6.0")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM