依赖
- android {
- ...
- kotlinOptions {
- jvmTarget = '1.8'
- useIR = true
- }
- buildFeatures {
- ...
- compose true
- }
- composeOptions {
- kotlinCompilerExtensionVersion rootProject.composeVersion
- }
- }
-
- dependencies {
- ...
- // Compose
- implementation "androidx.compose.runtime:runtime:$rootProject.composeVersion"
- implementation "androidx.compose.ui:ui:$rootProject.composeVersion"
- implementation "androidx.compose.foundation:foundation:$rootProject.composeVersion"
- implementation "androidx.compose.foundation:foundation-layout:$rootProject.composeVersion"
- implementation "androidx.compose.material:material:$rootProject.composeVersion"
- implementation "androidx.compose.runtime:runtime-livedata:$rootProject.composeVersion"
- implementation "androidx.compose.ui:ui-tooling:$rootProject.composeVersion"
- implementation "com.google.android.material:compose-theme-adapter:$rootProject.composeVersion"
- ...
- }
用到的版本如下
- /*
- * Copyright 2018 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- buildscript {
- // Define versions in a single place
- ext {
- // Sdk and tools
- compileSdkVersion = 31
- minSdkVersion = 21
- targetSdkVersion = 31
-
- // App dependencies
- appCompatVersion = '1.4.1'
- composeVersion = '1.1.1'
- constraintLayoutVersion = '2.1.3'
- coreTestingVersion = '2.1.0'
- coroutinesVersion = "1.6.0"
- // TODO: Updating to 3.4.0 leads to dependency conflicts
- espressoVersion = '3.3.0'
- fragmentVersion = '1.4.1'
- glideVersion = '4.12.0'
- gradleVersion = '7.2.0'
- gsonVersion = '2.8.6'
- junitVersion = '4.13.2'
- kotlinVersion = '1.6.10'
- ktlintVersion = '0.37.2'
- ktxVersion = '1.7.0'
- lifecycleVersion = '2.4.0'
- materialVersion = '1.5.0'
- materialComposeAdapterVersion = '1.1.5'
- navigationVersion = '2.5.0-alpha01'
- recyclerViewVersion = '1.2.1'
- roomVersion = '2.4.1'
- runnerVersion = '1.0.1'
- truthVersion = '1.1.2'
- testExtJunit = '1.1.3'
- uiAutomatorVersion = '2.2.0'
- viewPagerVersion = '1.0.0'
- workVersion = '2.7.1'
- }
-
- repositories {
- google()
- mavenCentral()
- }
-
- dependencies {
- classpath "com.android.tools.build:gradle:$gradleVersion"
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
- classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$navigationVersion"
- }
- }
-
- plugins {
- id "com.diffplug.spotless" version "5.12.4"
- }
-
- allprojects {
- repositories {
- google()
- mavenCentral()
- }
- }
-
- spotless {
- kotlin {
- target "**/*.kt"
- targetExclude("$buildDir/**/*.kt")
- targetExclude('bin/**/*.kt')
- ktlint(ktlintVersion)
- }
- }
这次我们修改 原生布局为Compse
这些布局为
ConstraintLayout 且里面有四个TextView
- <androidx.constraintlayout.widget.ConstraintLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_margin="@dimen/margin_normal">
-
- <TextView
- android:id="@+id/plant_detail_name"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_marginStart="@dimen/margin_small"
- android:layout_marginEnd="@dimen/margin_small"
- android:gravity="center_horizontal"
- android:text="@{viewModel.plant.name}"
- android:textAppearance="?attr/textAppearanceHeadline5"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- tools:text="Apple" />
-
- <TextView
- android:id="@+id/plant_watering_header"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_marginStart="@dimen/margin_small"
- android:layout_marginTop="@dimen/margin_normal"
- android:layout_marginEnd="@dimen/margin_small"
- android:gravity="center_horizontal"
- android:text="@string/watering_needs_prefix"
- android:textColor="?attr/colorAccent"
- android:textStyle="bold"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@id/plant_detail_name" />
-
- <TextView
- android:id="@+id/plant_watering"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_marginStart="@dimen/margin_small"
- android:layout_marginEnd="@dimen/margin_small"
- android:gravity="center_horizontal"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@id/plant_watering_header"
- app:wateringText="@{viewModel.plant.wateringInterval}"
- tools:text="every 7 days" />
-
- <TextView
- android:id="@+id/plant_description"
- style="?android:attr/textAppearanceMedium"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_marginStart="@dimen/margin_small"
- android:layout_marginTop="@dimen/margin_small"
- android:layout_marginEnd="@dimen/margin_small"
- android:minHeight="@dimen/plant_description_min_height"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@id/plant_watering"
- app:renderHtml="@{viewModel.plant.description}"
- tools:text="Details about the plant" />
-
- </androidx.constraintlayout.widget.ConstraintLayout>
我们注释掉这些布局并替换为
- <androidx.compose.ui.platform.ComposeView
- android:id="@+id/compose_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- </androidx.compose.ui.platform.ComposeView>
ComposeView

找到这个view的Id并对其进行设置
整个Compose的代码如下
- /*
- * Copyright 2020 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- package com.google.samples.apps.sunflower.plantdetail
-
- import android.content.res.Configuration
- import android.text.method.LinkMovementMethod
- import android.widget.TextView
- import androidx.compose.foundation.layout.*
- import androidx.compose.material.MaterialTheme
- import androidx.compose.material.Surface
- import androidx.compose.material.Text
- import androidx.compose.runtime.Composable
- import androidx.compose.runtime.getValue
- import androidx.compose.runtime.livedata.observeAsState
- import androidx.compose.ui.Alignment
- import androidx.compose.ui.Modifier
- import androidx.compose.ui.platform.LocalContext
- import androidx.compose.ui.res.dimensionResource
- import androidx.compose.ui.res.stringResource
- import androidx.compose.ui.text.font.FontWeight
- import androidx.compose.ui.tooling.preview.Preview
- import androidx.compose.ui.unit.dp
- import androidx.compose.ui.viewinterop.AndroidView
- import androidx.core.text.HtmlCompat
- import androidx.core.widget.TextViewCompat
- import com.google.android.material.composethemeadapter.MdcTheme
- import com.google.samples.apps.sunflower.R
- import com.google.samples.apps.sunflower.data.Plant
- import com.google.samples.apps.sunflower.viewmodels.PlantDetailViewModel
- import kotlin.math.min
-
- @Composable //Stateful :opinionated
- fun PlantDetailDescription(plantDetailViewModel: PlantDetailViewModel) {
- val currentPlant by plantDetailViewModel.plant.observeAsState()
-
- currentPlant?.let { plant ->
- PlantDetailDescription(plant)
- }
-
- }
-
- @Composable //Stateless:Preview+reusable
- private fun PlantDetailDescription(plant: Plant) {
- Surface {
- Column(modifier = Modifier
- .padding(dimensionResource(id = R.dimen.margin_normal))) {
- PlantName(plant.name)
- //Watering
- PlantWatering(plant.wateringInterval)
- //PlantDescription
- PlantDescription(description = plant.description)
- }
- }
-
- }
-
- @Composable
- fun PlantWatering(wateringInterval: Int) {
- Column(horizontalAlignment = Alignment.CenterHorizontally,
- modifier = Modifier
- .padding(horizontal = dimensionResource(id = R.dimen.margin_normal)
- )
- .fillMaxWidth()
- ) {
- Text(text = stringResource(id = R.string.watering_needs_prefix),
- modifier = Modifier
- .padding(top = dimensionResource(id = R.dimen.margin_normal)),
- color = MaterialTheme.colors.primaryVariant,
- fontWeight = FontWeight.Bold
- )
-
- val resources = LocalContext.current.resources
- val quantityString = resources.getQuantityString(
- R.plurals.watering_needs_suffix,
- wateringInterval, wateringInterval
- )
- Text(text = quantityString)
- }
- }
-
- @Composable
- fun PlantDescription(description: String) {
- AndroidView(factory = { context ->
- TextView(context).apply {
- movementMethod = LinkMovementMethod.getInstance()
- TextViewCompat.setTextAppearance(this, android.R.style.TextAppearance_Medium)
- }
- },
- update = { tv ->
- tv.text = HtmlCompat.fromHtml(description, HtmlCompat.FROM_HTML_MODE_COMPACT)
- },
- modifier =
- Modifier
- .padding(horizontal = dimensionResource(id = R.dimen.margin_small))
- .padding(top = dimensionResource(id = R.dimen.margin_small))
- .heightIn(min = dimensionResource(id = R.dimen.plant_description_min_height))
- )
-
- }
-
-
- @Composable
- fun PlantName(name: String) {
- Text(text = name,
- modifier = Modifier
- .padding(horizontal = dimensionResource(id = R.dimen.margin_small))
- .fillMaxWidth()
- .wrapContentWidth(Alignment.CenterHorizontally),
- style = MaterialTheme.typography.h5
- )
- }
-
- @Preview
- @Composable
- fun PlantNamePreview() {
- PlantName(name = "狗蛋")
- }
- @Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
- @Preview
- @Composable
- fun PlantDetailDescriptionPreview() {
- val fakePlant = Plant("asd", "asdas", "dasdahjskdhjasdj", 1, 3, "")
- MdcTheme() {
- PlantDetailDescription(plant = fakePlant)
- }
- }
-
-
-
在第四个的TextView用到了spnner 也就是html文本
其实。这个时候compose是暂时不支持的
我们要切换到原生view
大家看到这个了吗
PlantDescription
-
- @Composable
- fun PlantDescription(description: String) {
- AndroidView(factory = { context ->
- TextView(context).apply {
- movementMethod = LinkMovementMethod.getInstance()
- TextViewCompat.setTextAppearance(this, android.R.style.TextAppearance_Medium)
- }
- },
- update = { tv ->
- tv.text = HtmlCompat.fromHtml(description, HtmlCompat.FROM_HTML_MODE_COMPACT)
- },
- modifier =
- Modifier
- .padding(horizontal = dimensionResource(id = R.dimen.margin_small))
- .padding(top = dimensionResource(id = R.dimen.margin_small))
- .heightIn(min = dimensionResource(id = R.dimen.plant_description_min_height))
- )
-
- }
对其进行设置 就可以了。 而不是引入textView xml了。
这就要求我们充分的使用Compose咯