将自定义视图与 Jetpack Compose 结合使用
Using Custom Views with Jetpack Compose
假设我正在使用一些旨在提供一些 UI 小部件的库。
假设这个库提供了一个名为 FancyButton
.
的按钮小部件
另一方面,我有一个使用 Android Studio 4 创建的新项目,它允许我使用 Empty Compose Activity
.
创建一个新项目
问题是:
我应该如何将此 FancyButton
添加到视图堆栈? 可能吗?或者对于 Jetpack Compose,我只能使用专门为 Jetpack Compose 开发的组件。在这种情况下,AFAIK 我只能使用 Android 标准组件(Text
、MaterialTheme
等)。
如果我尝试使用这样的东西:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MaterialTheme {
Greeting("Android")
FancyButton(context, "Some text")
}
}
}
然后我得到这个错误:
e: Supertypes of the following classes cannot be resolved. Please make sure you have the required dependencies in the classpath.
目前(截至0.1.0-dev04
),没有很好的解决方案。将来,您可以简单地将其称为 FancyButton("Some text")
(不需要 context
)。
您可以在 Compose 代码中看到它的外观演示 here。
在alpha 06
中更新
可以在可组合项中导入 Android View 个实例。
使用 ContextAmbient.current
作为视图的 context
参数。
Column(modifier = Modifier.padding(16.dp)) {
// CustomView using Object
MyCustomView(context = ContextAmbient.current)
// If the state updates
AndroidView(viewBlock = ::CustomView, modifier = modifier) { customView ->
// Modify the custom view
}
// Using xml resource
AndroidView(resId = R.layout.view_demo)
}
您可以将自定义视图包装在 AndroidView composable:
@Composable
fun RegularTextView() {
AndroidView(
factory = { context ->
TextView(context).apply {
text = "RegularTextView"
textSize = 34.dp.value
}
},
)
}
下面是如何在重组期间使用更新参数更新您的自定义视图:
@Composable
fun RegularTextView() {
var string by remember {
mutableStateOf("RegularTextView")
}
Column(horizontalAlignment = Alignment.CenterHorizontally) {
AndroidView(
factory = { context ->
TextView(context).apply {
textSize = 34.dp.value
}
},
update = { textView ->
textView.text = string
}
)
Spacer(modifier = Modifier.height(8.dp))
Button(
onClick = {
string = "Button clicked"
},
) {
Text(text = "Update text")
}
}
}
@Composable
fun ButtonType1(text: String, onClick: () -> Unit)
{
Button (
modifier=Modifier.fillMaxWidth().height(50.dp),
onClick = onClick,
shape = RoundedCornerShape(5.dp),
border = BorderStroke(3.dp, colorResource(id = R.color.colorPrimaryDark)),
colors = ButtonDefaults.buttonColors(contentColor = Color.White, backgroundColor = colorResource(id = R.color.colorPrimaryDark))
)
{
Text(text = text , color = colorResource(id = R.color.white),
fontFamily = montserrat,
fontWeight = FontWeight.Normal,
fontSize = 15.sp
)
}
}
假设我正在使用一些旨在提供一些 UI 小部件的库。
假设这个库提供了一个名为 FancyButton
.
另一方面,我有一个使用 Android Studio 4 创建的新项目,它允许我使用 Empty Compose Activity
.
问题是:
我应该如何将此 FancyButton
添加到视图堆栈? 可能吗?或者对于 Jetpack Compose,我只能使用专门为 Jetpack Compose 开发的组件。在这种情况下,AFAIK 我只能使用 Android 标准组件(Text
、MaterialTheme
等)。
如果我尝试使用这样的东西:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MaterialTheme {
Greeting("Android")
FancyButton(context, "Some text")
}
}
}
然后我得到这个错误:
e: Supertypes of the following classes cannot be resolved. Please make sure you have the required dependencies in the classpath.
目前(截至0.1.0-dev04
),没有很好的解决方案。将来,您可以简单地将其称为 FancyButton("Some text")
(不需要 context
)。
您可以在 Compose 代码中看到它的外观演示 here。
在alpha 06
可以在可组合项中导入 Android View 个实例。
使用 ContextAmbient.current
作为视图的 context
参数。
Column(modifier = Modifier.padding(16.dp)) {
// CustomView using Object
MyCustomView(context = ContextAmbient.current)
// If the state updates
AndroidView(viewBlock = ::CustomView, modifier = modifier) { customView ->
// Modify the custom view
}
// Using xml resource
AndroidView(resId = R.layout.view_demo)
}
您可以将自定义视图包装在 AndroidView composable:
@Composable
fun RegularTextView() {
AndroidView(
factory = { context ->
TextView(context).apply {
text = "RegularTextView"
textSize = 34.dp.value
}
},
)
}
下面是如何在重组期间使用更新参数更新您的自定义视图:
@Composable
fun RegularTextView() {
var string by remember {
mutableStateOf("RegularTextView")
}
Column(horizontalAlignment = Alignment.CenterHorizontally) {
AndroidView(
factory = { context ->
TextView(context).apply {
textSize = 34.dp.value
}
},
update = { textView ->
textView.text = string
}
)
Spacer(modifier = Modifier.height(8.dp))
Button(
onClick = {
string = "Button clicked"
},
) {
Text(text = "Update text")
}
}
}
@Composable
fun ButtonType1(text: String, onClick: () -> Unit)
{
Button (
modifier=Modifier.fillMaxWidth().height(50.dp),
onClick = onClick,
shape = RoundedCornerShape(5.dp),
border = BorderStroke(3.dp, colorResource(id = R.color.colorPrimaryDark)),
colors = ButtonDefaults.buttonColors(contentColor = Color.White, backgroundColor = colorResource(id = R.color.colorPrimaryDark))
)
{
Text(text = text , color = colorResource(id = R.color.white),
fontFamily = montserrat,
fontWeight = FontWeight.Normal,
fontSize = 15.sp
)
}
}