简体   繁体   English

如何将我的自定义视图迁移到 Jetpack Compose?

[英]How to migrate my custom view to Jetpack Compose?

I have a custom view created the traditional way: subclassing from the View class.我有一个以传统方式创建的自定义视图:从View类继承。

Specifically, my custom view has many custom attributes (and their corresponding Kotlin properties) that can be assigned in the XML layout:具体来说,我的自定义视图有许多可以在 XML 布局中分配的自定义属性(及其相应的 Kotlin 属性):

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

How to provide a View version of my composable so users can use it in XML?如何提供我的可组合的视图版本,以便用户可以在 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?除了使用AndroidView类在 Jetpack Compose 中加载传统的 Android 视图之外,如何我的视图转换为“真正的”Compose 组件?

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. Android 开发者文档没有提到如何将自定义视图转换为 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 :要像常规View一样使用该可组合组件(能够在 XML 中指定其属性),我们应该从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:这就是我们将如何使用它,就像 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 .感谢 ProAndroidDev 提供这篇文章

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 :此外,请确保使用AndroidX Core库的-ktx版本,以便能够访问有用的 Kotlin 扩展函数,例如Context::withStyledAttributes

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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