JetpackCompose 之 状态学习

该博客围绕Android开发展开,介绍了无状态组件,包括导入依赖和数据类相关内容,还涉及重组、MutableState、软键盘、输入框背景、编辑模式以及状态恢复等方面,提及了相关的文件和开发要点,如使用parcelize需插件。

1.无状态组件

1.1导入依赖

    implementation("androidx.core:core-ktx:1.9.0")
    implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.1")
    implementation("androidx.activity:activity-compose:1.7.0")
    implementation(platform("androidx.compose:compose-bom:2023.03.00"))
    implementation("androidx.compose.ui:ui")
    implementation("androidx.compose.ui:ui-graphics")
    implementation("androidx.compose.ui:ui-tooling-preview")
    implementation("androidx.compose.material3:material3")

    implementation("com.google.android.material:material:1.11.0")
    implementation("androidx.compose.material:material-icons-extended:1.5.4")
    implementation("androidx.compose.runtime:runtime-livedata:1.5.4")
    implementation("androidx.compose.runtime:runtime:1.5.4")



    testImplementation("junit:junit:4.13.2")
    androidTestImplementation("androidx.test.ext:junit:1.1.5")
    androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
    androidTestImplementation(platform("androidx.compose:compose-bom:2023.03.00"))
    androidTestImplementation("androidx.compose.ui:ui-test-junit4")
    debugImplementation("androidx.compose.ui:ui-tooling")
    debugImplementation("androidx.compose.ui:ui-test-manifest")

strings.xml

<resources>
    <string name="app_name">JetpackComposeState</string>
    <string name="cd_expand">Expand</string>
    <string name="cd_collapse">Collapse</string>
    <string name="cd_crop_square">Crop</string>
    <string name="cd_done">Done</string>
    <string name="cd_event">Event</string>
    <string name="cd_privacy">Privacy</string>
    <string name="cd_restore">Restore</string>d
</resources>

themes.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <style name="Theme.JetpackComposeState" parent="android:Theme.Material.Light.NoActionBar" />
    <style name="Theme.JetpackComposeState.NoActionBar">
        <item name="android:windowActionBar">false</item>
        <item name="android:windowNoTitle">true</item>

    </style>
</resources>

1.2 数据类

package com.jetpackcomposestate.todo

import androidx.annotation.StringRes
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.CropSquare
import androidx.compose.material.icons.filled.Done
import androidx.compose.material.icons.filled.Event
import androidx.compose.material.icons.filled.PrivacyTip
import androidx.compose.material.icons.filled.RestoreFromTrash
import androidx.compose.material.icons.filled.Square
import androidx.compose.ui.graphics.vector.ImageVector
import com.tiger.jetpackcomposestate.R
import java.util.UUID

data class TodoItem(val task:String,val icon:TodoIcon = TodoIcon.Default,val id:UUID=UUID.randomUUID())


enum class TodoIcon(
    val imageVector: ImageVector,
    @StringRes val contentDescription: Int
){
    //使用了 Material Design 的图标
    Square(Icons.Default.CropSquare, R.string.cd_expand),
    Done(Icons.Default.Done, R.string.cd_done),
    Event(Icons.Default.Event, R.string.cd_event),
    Privacy(Icons.Default.PrivacyTip, R.string.cd_privacy),
    Trash(Icons.Default.RestoreFromTrash, R.string.cd_restore);

    companion object {
        val Default = Square
    }


}
package com.jetpackcomposestate.todo.one

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.tiger.jetpackcomposestate.todo.TodoItem

@Composable
fun TodoScreen(
    items:List<TodoItem>
){

    Column() {
        LazyColumn(
            modifier = Modifier.weight(1f),//优先修饰 列表的布局
            contentPadding = PaddingValues(top = 8.dp)

        ){
            items(items){
                TodoRow(todo = it, modifier = Modifier.fillParentMaxWidth())
            }
        }
        Button(onClick = {

        },
            modifier = Modifier
                .padding(16.dp)
                .fillMaxWidth()

        ) {
        Text(text = "Add random item" )

        }
    }

}


@Composable
fun TodoRow(
    todo: TodoItem,
    modifier: Modifier = Modifier
){

    Row(
        modifier = modifier
            .padding(horizontal = 16.dp, vertical = 8.dp),
        horizontalArrangement = Arrangement.SpaceBetween  //子元素水平均匀分布
    ) {
        Text(text = todo.task)
        Icon(imageVector = todo.icon.imageVector
            ,contentDescription = stringResource(id = todo.icon.contentDescription))//stringResource去到strings.xml文件里去找到对应的字符串 描述
    }



}
package com.jetpackcomposestate.todo.one

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.runtime.Composable
import com.tiger.jetpackcomposestate.todo.TodoIcon
import com.tiger.jetpackcomposestate.todo.TodoItem
import com.tiger.jetpackcomposestate.ui.theme.JetpackComposeStateTheme

class TodoActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            JetpackComposeStateTheme {

                TodoActivityScreen()
            }
        }
    }

    @Composable
    private fun TodoActivityScreen() {
        val items = listOf(
            TodoItem(task = "Learn compose", icon = TodoIcon.Event),
            TodoItem(task = "Take the codelab"),
            TodoItem(task = "Apply state", icon = TodoIcon.Done),
            TodoItem(task = "Build dynamic UIs", icon = TodoIcon.Square),
        )

        TodoScreen(items)
    }
}

 

TodoViewModel.kt

package com.jmj.jetpackcomposestate.todo.one

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.jmj.jetpackcomposestate.todo.TodoItem

class TodoViewModel:ViewModel(){

    private var _todoItems = MutableLiveData(listOf<TodoItem>())  //这是一个状态

    val  todoItems:LiveData<List<TodoItem>> = _todoItems

    fun addItem(item:TodoItem){
        //添加
        _todoItems.value = _todoItems.value!! + listOf(item)
    }


    fun removeItem(item:TodoItem){
        //删除
        _todoItems.value =_todoItems.value!!.toMutableList().also {
            it.remove(item)
        }

    }
}

 TodoScreen.kt

package com.jmj.jetpackcomposestate.todo.one

import androidx.compose.foundation.clickable
import com.jmj.jetpackcomposestate.todo.TodoItem


import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.jmj.jetpackcomposestate.util.generateRandomTodoItem


@Composable
fun TodoScreen(
    items:List<TodoItem>,
    onAddItem: (TodoItem) ->Unit,
    onRemoveItem: (TodoItem) ->Unit
){

    Column() {
        LazyColumn(
            modifier = Modifier.weight(1f),//优先修饰 列表的布局
            contentPadding = PaddingValues(top = 8.dp)

        ){
            items(items){
                TodoRow(todo = it, modifier = Modifier.fillParentMaxWidth(), onItemClicked = {onRemoveItem(it)})
            }
        }
        Button(onClick = {
                onAddItem(generateRandomTodoItem())
        },
            modifier = Modifier
                .padding(16.dp)
                .fillMaxWidth()

        ) {
            Text(text = "Add random item" )

        }
    }

}


@Composable
fun TodoRow(
    todo: TodoItem,
    onItemClicked:(TodoItem) -> Unit,
    modifier: Modifier = Modifier,

){

    Row(
        modifier = modifier
            .clickable{
                onItemClicked(todo)
            }
            .padding(horizontal = 16.dp, vertical = 8.dp),
        horizontalArrangement = Arrangement.SpaceBetween  //子元素水平均匀分布
    ) {
        Text(text = todo.task)
        Icon(imageVector = todo.icon.imageVector
            ,contentDescription = stringResource(id = todo.icon.contentDescription))//stringResource去到strings.xml文件里去找到对应的字符串 描述
    }



}

TodoAcitivity.kt

package com.jmj.jetpackcomposestate.todo.one

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import com.jmj.jetpackcomposestate.todo.TodoIcon
import com.jmj.jetpackcomposestate.todo.TodoItem
import com.jmj.jetpackcomposestate.ui.theme.JetpackComposeStateTheme


class TodoActivity : ComponentActivity() {

    private val todoViewModel by viewModels<TodoViewModel>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            JetpackComposeStateTheme {

                TodoActivityScreen()
            }
        }
    }

    @Composable
    private fun TodoActivityScreen() {
//        val items = listOf(
//            TodoItem(task = "Learn compose", icon = TodoIcon.Event),
//            TodoItem(task = "Take the codelab"),
//            TodoItem(task = "Apply state", icon = TodoIcon.Done),
//            TodoItem(task = "Build dynamic UIs", icon = TodoIcon.Square),
//        )
//
//        TodoScreen(items)
        val items:List<TodoItem> by todoViewModel.todoItems.observeAsState(initial = listOf())



        TodoScreen(
            items=items,
            onAddItem = {  todoViewModel.addItem(it) },
            onRemoveItem = {todoViewModel.removeItem(it)}
            )

    }
}

2.重组

 

package com.jmj.jetpackcomposestate.todo.one


import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.co
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值