• Kotlin Compose 与原生 嵌套使用


    依赖

    1. android {
    2. ...
    3. kotlinOptions {
    4. jvmTarget = '1.8'
    5. useIR = true
    6. }
    7. buildFeatures {
    8. ...
    9. compose true
    10. }
    11. composeOptions {
    12. kotlinCompilerExtensionVersion rootProject.composeVersion
    13. }
    14. }
    15. dependencies {
    16. ...
    17. // Compose
    18. implementation "androidx.compose.runtime:runtime:$rootProject.composeVersion"
    19. implementation "androidx.compose.ui:ui:$rootProject.composeVersion"
    20. implementation "androidx.compose.foundation:foundation:$rootProject.composeVersion"
    21. implementation "androidx.compose.foundation:foundation-layout:$rootProject.composeVersion"
    22. implementation "androidx.compose.material:material:$rootProject.composeVersion"
    23. implementation "androidx.compose.runtime:runtime-livedata:$rootProject.composeVersion"
    24. implementation "androidx.compose.ui:ui-tooling:$rootProject.composeVersion"
    25. implementation "com.google.android.material:compose-theme-adapter:$rootProject.composeVersion"
    26. ...
    27. }

    用到的版本如下

    1. /*
    2. * Copyright 2018 Google LLC
    3. *
    4. * Licensed under the Apache License, Version 2.0 (the "License");
    5. * you may not use this file except in compliance with the License.
    6. * You may obtain a copy of the License at
    7. *
    8. * https://www.apache.org/licenses/LICENSE-2.0
    9. *
    10. * Unless required by applicable law or agreed to in writing, software
    11. * distributed under the License is distributed on an "AS IS" BASIS,
    12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13. * See the License for the specific language governing permissions and
    14. * limitations under the License.
    15. */
    16. buildscript {
    17. // Define versions in a single place
    18. ext {
    19. // Sdk and tools
    20. compileSdkVersion = 31
    21. minSdkVersion = 21
    22. targetSdkVersion = 31
    23. // App dependencies
    24. appCompatVersion = '1.4.1'
    25. composeVersion = '1.1.1'
    26. constraintLayoutVersion = '2.1.3'
    27. coreTestingVersion = '2.1.0'
    28. coroutinesVersion = "1.6.0"
    29. // TODO: Updating to 3.4.0 leads to dependency conflicts
    30. espressoVersion = '3.3.0'
    31. fragmentVersion = '1.4.1'
    32. glideVersion = '4.12.0'
    33. gradleVersion = '7.2.0'
    34. gsonVersion = '2.8.6'
    35. junitVersion = '4.13.2'
    36. kotlinVersion = '1.6.10'
    37. ktlintVersion = '0.37.2'
    38. ktxVersion = '1.7.0'
    39. lifecycleVersion = '2.4.0'
    40. materialVersion = '1.5.0'
    41. materialComposeAdapterVersion = '1.1.5'
    42. navigationVersion = '2.5.0-alpha01'
    43. recyclerViewVersion = '1.2.1'
    44. roomVersion = '2.4.1'
    45. runnerVersion = '1.0.1'
    46. truthVersion = '1.1.2'
    47. testExtJunit = '1.1.3'
    48. uiAutomatorVersion = '2.2.0'
    49. viewPagerVersion = '1.0.0'
    50. workVersion = '2.7.1'
    51. }
    52. repositories {
    53. google()
    54. mavenCentral()
    55. }
    56. dependencies {
    57. classpath "com.android.tools.build:gradle:$gradleVersion"
    58. classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
    59. classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$navigationVersion"
    60. }
    61. }
    62. plugins {
    63. id "com.diffplug.spotless" version "5.12.4"
    64. }
    65. allprojects {
    66. repositories {
    67. google()
    68. mavenCentral()
    69. }
    70. }
    71. spotless {
    72. kotlin {
    73. target "**/*.kt"
    74. targetExclude("$buildDir/**/*.kt")
    75. targetExclude('bin/**/*.kt')
    76. ktlint(ktlintVersion)
    77. }
    78. }

    这次我们修改 原生布局为Compse

    这些布局为 

    ConstraintLayout  且里面有四个TextView
    1. <androidx.constraintlayout.widget.ConstraintLayout
    2. android:layout_width="match_parent"
    3. android:layout_height="match_parent"
    4. android:layout_margin="@dimen/margin_normal">
    5. <TextView
    6. android:id="@+id/plant_detail_name"
    7. android:layout_width="0dp"
    8. android:layout_height="wrap_content"
    9. android:layout_marginStart="@dimen/margin_small"
    10. android:layout_marginEnd="@dimen/margin_small"
    11. android:gravity="center_horizontal"
    12. android:text="@{viewModel.plant.name}"
    13. android:textAppearance="?attr/textAppearanceHeadline5"
    14. app:layout_constraintEnd_toEndOf="parent"
    15. app:layout_constraintStart_toStartOf="parent"
    16. app:layout_constraintTop_toTopOf="parent"
    17. tools:text="Apple" />
    18. <TextView
    19. android:id="@+id/plant_watering_header"
    20. android:layout_width="0dp"
    21. android:layout_height="wrap_content"
    22. android:layout_marginStart="@dimen/margin_small"
    23. android:layout_marginTop="@dimen/margin_normal"
    24. android:layout_marginEnd="@dimen/margin_small"
    25. android:gravity="center_horizontal"
    26. android:text="@string/watering_needs_prefix"
    27. android:textColor="?attr/colorAccent"
    28. android:textStyle="bold"
    29. app:layout_constraintEnd_toEndOf="parent"
    30. app:layout_constraintStart_toStartOf="parent"
    31. app:layout_constraintTop_toBottomOf="@id/plant_detail_name" />
    32. <TextView
    33. android:id="@+id/plant_watering"
    34. android:layout_width="0dp"
    35. android:layout_height="wrap_content"
    36. android:layout_marginStart="@dimen/margin_small"
    37. android:layout_marginEnd="@dimen/margin_small"
    38. android:gravity="center_horizontal"
    39. app:layout_constraintEnd_toEndOf="parent"
    40. app:layout_constraintStart_toStartOf="parent"
    41. app:layout_constraintTop_toBottomOf="@id/plant_watering_header"
    42. app:wateringText="@{viewModel.plant.wateringInterval}"
    43. tools:text="every 7 days" />
    44. <TextView
    45. android:id="@+id/plant_description"
    46. style="?android:attr/textAppearanceMedium"
    47. android:layout_width="0dp"
    48. android:layout_height="wrap_content"
    49. android:layout_marginStart="@dimen/margin_small"
    50. android:layout_marginTop="@dimen/margin_small"
    51. android:layout_marginEnd="@dimen/margin_small"
    52. android:minHeight="@dimen/plant_description_min_height"
    53. app:layout_constraintEnd_toEndOf="parent"
    54. app:layout_constraintStart_toStartOf="parent"
    55. app:layout_constraintTop_toBottomOf="@id/plant_watering"
    56. app:renderHtml="@{viewModel.plant.description}"
    57. tools:text="Details about the plant" />
    58. </androidx.constraintlayout.widget.ConstraintLayout>

    我们注释掉这些布局并替换为

    1. <androidx.compose.ui.platform.ComposeView
    2. android:id="@+id/compose_view"
    3. android:layout_width="match_parent"
    4. android:layout_height="match_parent">
    5. </androidx.compose.ui.platform.ComposeView>

    ComposeView

     找到这个view的Id并对其进行设置

    整个Compose的代码如下

    1. /*
    2. * Copyright 2020 Google LLC
    3. *
    4. * Licensed under the Apache License, Version 2.0 (the "License");
    5. * you may not use this file except in compliance with the License.
    6. * You may obtain a copy of the License at
    7. *
    8. * https://www.apache.org/licenses/LICENSE-2.0
    9. *
    10. * Unless required by applicable law or agreed to in writing, software
    11. * distributed under the License is distributed on an "AS IS" BASIS,
    12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13. * See the License for the specific language governing permissions and
    14. * limitations under the License.
    15. */
    16. package com.google.samples.apps.sunflower.plantdetail
    17. import android.content.res.Configuration
    18. import android.text.method.LinkMovementMethod
    19. import android.widget.TextView
    20. import androidx.compose.foundation.layout.*
    21. import androidx.compose.material.MaterialTheme
    22. import androidx.compose.material.Surface
    23. import androidx.compose.material.Text
    24. import androidx.compose.runtime.Composable
    25. import androidx.compose.runtime.getValue
    26. import androidx.compose.runtime.livedata.observeAsState
    27. import androidx.compose.ui.Alignment
    28. import androidx.compose.ui.Modifier
    29. import androidx.compose.ui.platform.LocalContext
    30. import androidx.compose.ui.res.dimensionResource
    31. import androidx.compose.ui.res.stringResource
    32. import androidx.compose.ui.text.font.FontWeight
    33. import androidx.compose.ui.tooling.preview.Preview
    34. import androidx.compose.ui.unit.dp
    35. import androidx.compose.ui.viewinterop.AndroidView
    36. import androidx.core.text.HtmlCompat
    37. import androidx.core.widget.TextViewCompat
    38. import com.google.android.material.composethemeadapter.MdcTheme
    39. import com.google.samples.apps.sunflower.R
    40. import com.google.samples.apps.sunflower.data.Plant
    41. import com.google.samples.apps.sunflower.viewmodels.PlantDetailViewModel
    42. import kotlin.math.min
    43. @Composable //Stateful :opinionated
    44. fun PlantDetailDescription(plantDetailViewModel: PlantDetailViewModel) {
    45. val currentPlant by plantDetailViewModel.plant.observeAsState()
    46. currentPlant?.let { plant ->
    47. PlantDetailDescription(plant)
    48. }
    49. }
    50. @Composable //Stateless:Preview+reusable
    51. private fun PlantDetailDescription(plant: Plant) {
    52. Surface {
    53. Column(modifier = Modifier
    54. .padding(dimensionResource(id = R.dimen.margin_normal))) {
    55. PlantName(plant.name)
    56. //Watering
    57. PlantWatering(plant.wateringInterval)
    58. //PlantDescription
    59. PlantDescription(description = plant.description)
    60. }
    61. }
    62. }
    63. @Composable
    64. fun PlantWatering(wateringInterval: Int) {
    65. Column(horizontalAlignment = Alignment.CenterHorizontally,
    66. modifier = Modifier
    67. .padding(horizontal = dimensionResource(id = R.dimen.margin_normal)
    68. )
    69. .fillMaxWidth()
    70. ) {
    71. Text(text = stringResource(id = R.string.watering_needs_prefix),
    72. modifier = Modifier
    73. .padding(top = dimensionResource(id = R.dimen.margin_normal)),
    74. color = MaterialTheme.colors.primaryVariant,
    75. fontWeight = FontWeight.Bold
    76. )
    77. val resources = LocalContext.current.resources
    78. val quantityString = resources.getQuantityString(
    79. R.plurals.watering_needs_suffix,
    80. wateringInterval, wateringInterval
    81. )
    82. Text(text = quantityString)
    83. }
    84. }
    85. @Composable
    86. fun PlantDescription(description: String) {
    87. AndroidView(factory = { context ->
    88. TextView(context).apply {
    89. movementMethod = LinkMovementMethod.getInstance()
    90. TextViewCompat.setTextAppearance(this, android.R.style.TextAppearance_Medium)
    91. }
    92. },
    93. update = { tv ->
    94. tv.text = HtmlCompat.fromHtml(description, HtmlCompat.FROM_HTML_MODE_COMPACT)
    95. },
    96. modifier =
    97. Modifier
    98. .padding(horizontal = dimensionResource(id = R.dimen.margin_small))
    99. .padding(top = dimensionResource(id = R.dimen.margin_small))
    100. .heightIn(min = dimensionResource(id = R.dimen.plant_description_min_height))
    101. )
    102. }
    103. @Composable
    104. fun PlantName(name: String) {
    105. Text(text = name,
    106. modifier = Modifier
    107. .padding(horizontal = dimensionResource(id = R.dimen.margin_small))
    108. .fillMaxWidth()
    109. .wrapContentWidth(Alignment.CenterHorizontally),
    110. style = MaterialTheme.typography.h5
    111. )
    112. }
    113. @Preview
    114. @Composable
    115. fun PlantNamePreview() {
    116. PlantName(name = "狗蛋")
    117. }
    118. @Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
    119. @Preview
    120. @Composable
    121. fun PlantDetailDescriptionPreview() {
    122. val fakePlant = Plant("asd", "asdas", "dasdahjskdhjasdj", 1, 3, "")
    123. MdcTheme() {
    124. PlantDetailDescription(plant = fakePlant)
    125. }
    126. }

    在第四个的TextView用到了spnner 也就是html文本

    其实。这个时候compose是暂时不支持的

    我们要切换到原生view

    大家看到这个了吗

    PlantDescription
    1. @Composable
    2. fun PlantDescription(description: String) {
    3. AndroidView(factory = { context ->
    4. TextView(context).apply {
    5. movementMethod = LinkMovementMethod.getInstance()
    6. TextViewCompat.setTextAppearance(this, android.R.style.TextAppearance_Medium)
    7. }
    8. },
    9. update = { tv ->
    10. tv.text = HtmlCompat.fromHtml(description, HtmlCompat.FROM_HTML_MODE_COMPACT)
    11. },
    12. modifier =
    13. Modifier
    14. .padding(horizontal = dimensionResource(id = R.dimen.margin_small))
    15. .padding(top = dimensionResource(id = R.dimen.margin_small))
    16. .heightIn(min = dimensionResource(id = R.dimen.plant_description_min_height))
    17. )
    18. }

    对其进行设置 就可以了。 而不是引入textView xml了。

    这就要求我们充分的使用Compose咯

  • 相关阅读:
    【组合递归】【StringBuilder】Leetcode 17. 电话号码的字母组合
    React-4 组件知识
    Python编程 字符串介绍以及切片
    [开发|JAVA] dateease编译资料笔记
    SQL教程之性能不仅仅是查询
    map 模拟与用法
    Redis系列:Redis的数据结构
    服务器端请求伪造(SSRF)
    Nginx 高性能架构解析
    呼叫系统使用webRTC网页软电话到底好不好?
  • 原文地址:https://blog.csdn.net/mp624183768/article/details/125591127