当前位置:网站首页>Kotlin compose and native nesting

Kotlin compose and native nesting

2022-07-05 09:57:00 Ango can't move

rely on

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"
    ...
}

The versions used are as follows

/*
 * 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)
    }
}

This time we modify The original layout is Compse

These layouts are  

ConstraintLayout   And there are four 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>

We annotate these layouts and replace them with

    <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

  To find the view Of Id And set it

Whole Compose The code for is as follows

/*
 * 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 = " The dog egg ")
}
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Preview
@Composable
fun PlantDetailDescriptionPreview() {
    val fakePlant = Plant("asd", "asdas", "dasdahjskdhjasdj", 1, 3, "")
    MdcTheme() {
        PlantDetailDescription(plant = fakePlant)
    }
}



In the fourth TextView Yes spnner That is to say html Text

Actually . This is the time compose Is temporarily unsupported

We need to switch to native view

Have you seen this

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))
    )

}

Set it up That's all right. . Instead of introducing textView xml 了 .

This requires us to make full use of Compose Slightly

原网站

版权声明
本文为[Ango can't move]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/186/202207050935348237.html