当前位置:   article > 正文

Android Compose(新式声明性界面工具包)体验_android @composable

android @composable

开发环境
教程
深入详解 Jetpack Compose | 实现原理

实际开发体验和flutter很像,但是实际原理好像不同,flutter中组件都是widget对象,比较容易理解
而compose中组件并没有返回值,编译器会对@Composable的方法进行处理,具体原理需要深入了解

@Composable官方说明

关于@Composable,有几点值得注意:

  • 此函数带有 @Composable 注释。所有可组合函数都必须带有此注释;此注释可告知 Compose 编译器:此函数旨在将数据转换为界面。
  • 此函数接受数据。可组合函数可以接受一些参数,这些参数可让应用逻辑描述界面。在本例中,我们的微件接受一个 String,因此它可以按名称问候用户。
  • 此函数可以在界面中显示文本。为此,它会调用 Text() 可组合函数,该函数实际上会创建文本界面元素。可组合函数通过调用其他可组合函数来发出界面层次结构。
  • 此函数不会返回任何内容。发出界面的 Compose 函数不需要返回任何内容,因为它们描述所需的屏幕状态,而不是构造界面微件。
  • 此函数快速、幂等且没有副作用。
    • 使用同一参数多次调用此函数时,它的行为方式相同,并且它不使用其他值,如全局变量或对 random() 的调用。
    • 此函数描述界面而没有任何副作用,如修改属性或全局变量。
      一般来说,出于重组部分所述的原因,所有可组合函数都应使用这些属性来编写。

依赖

dependencies {

    def lifecycle_version = "2.3.1"
    def compose_version = '1.0.0-beta01'
    // ViewModel
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
    // LiveData
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
    // Jetpack Compose Integration for ViewModel
    implementation "androidx.lifecycle:lifecycle-viewmodel-compose:1.0.0-alpha04"

    implementation "androidx.constraintlayout:constraintlayout-compose:1.0.0-alpha03"
    implementation 'androidx.core:core-ktx:1.3.2'
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.2.1'
    implementation "androidx.compose.ui:ui:$compose_version"
    implementation "androidx.compose.material:material:$compose_version"
    implementation "androidx.compose.ui:ui-tooling:$compose_version"
    implementation "androidx.compose.runtime:runtime-livedata:$compose_version"
    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.0-rc01'
    implementation 'androidx.activity:activity-compose:1.3.0-alpha02'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
    androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

View

package com.example.composeapplication

import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.constraintlayout.compose.ConstraintLayout
import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.composeapplication.ui.theme.ComposeApplicationTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ComposeApplicationTheme {
                // 学过flutter的应该很熟悉,基本的 Material 布局
                Scaffold(
                    topBar = {
                        TopAppBar(title = { Text(text = "计数器") })
                    },
                ) {
                    ConstraintLayoutContent()
                }

            }
        }
    }
}

@Composable
fun ConstraintLayoutContent() {
    // 获取viewModel
    val viewModel: MainViewModel = viewModel()
    ConstraintLayout(
        modifier = Modifier.fillMaxSize(), //充满父组件
    ) {
        val (fab, text) = createRefs()

        val count = viewModel.count.observeAsState()
        Text(
            text = count.value.toString(),
            modifier = Modifier.constrainAs(text) {
                centerTo(parent)
            },
            fontSize = 20.sp,
        )

        FloatingActionButton(
            modifier = Modifier.constrainAs(fab) {
                bottom.linkTo(parent.bottom, margin = 16.dp)
                end.linkTo(parent.end, margin = 16.dp)
            },
            onClick = {
                viewModel.add()
            },
        ) {
            Icon(
                painter = painterResource(id = R.drawable.ic_baseline_add_24),
                contentDescription = "add",
                tint = Color.White
            )
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77

ViewModel

package com.example.composeapplication

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel

class MainViewModel : ViewModel() {
    private val _count = MutableLiveData(0)
    val count: LiveData<Int> = _count

    fun add() {
        _count.value = _count.value?.plus(1)
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

截图

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/254189
推荐阅读
相关标签
  

闽ICP备14008679号