当前位置:网站首页>Kotlin compose terminate todo project Click to edit and modify todo
Kotlin compose terminate todo project Click to edit and modify todo
2022-06-25 18:49:00 【Ango cannot move】
Pick up
TodoComponents.kt
package com.anguomob.jecpack.activity.compose.todo.one
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.*
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import com.anguomob.jecpack.activity.compose.todo.bean.ToDoIcon
import com.anguomob.jecpack.activity.compose.todo.bean.TodoItem
// When item When it's chosen An input box will pop up Used to edit the selected ToDoItem Information about
@Composable
fun TodoItemInLineEditor(
item: TodoItem,
onEditItemChange: (TodoItem) -> Unit,
onEditDone: () -> Unit,
onRemoveItem: () -> Unit,
) {
TodoItemInput(
text = item.task,
onTextChange = { onEditItemChange(item.copy(task = it)) },
icon = item.icon,
onIconChange = { onEditItemChange(item.copy(icon = it)) },
iconsVisible = true,
submit = onEditDone,
buttonSlot = {
// Save and delete two icons
Row() {
val shrinkButtons = Modifier.widthIn(20.dp)
TextButton(onClick = onEditDone, modifier = shrinkButtons) {
// In words emoji expression
Text(
text = "\uD83D\uDCBE",
textAlign = TextAlign.End,
)
}
TextButton(onClick = onRemoveItem, modifier = shrinkButtons) {
// In words emoji expression
Text(
text = " Delete ",
textAlign = TextAlign.End,
)
}
}
}
)
}
@Composable
fun ToDoItemInputBackground(
modifier: Modifier = Modifier,
content: @Composable RowScope.() -> Unit,
elevatioon: Boolean
) {
// Display in frame animation Surface Shadow at bottom
val animatedElevation by animateDpAsState(
targetValue = if (elevatioon) 1.dp else 0.dp,
TweenSpec(300)
)
Surface(
color = MaterialTheme.colors.onSurface.copy(alpha = 0.05f),
shape = RectangleShape,
elevation = animatedElevation
) {
Row(modifier = modifier.animateContentSize(animationSpec = TweenSpec(300))) {
content()
}
}
}
// Input box
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun TodoInputText(
text: String,
onTextChanged: (String) -> Unit,
onImeAction: () -> Unit,
modifier: Modifier = Modifier,
) {
val keyboardController = LocalSoftwareKeyboardController.current
TextField(
value = text,
onValueChange = onTextChanged,
modifier = modifier,
colors = TextFieldDefaults.textFieldColors(backgroundColor = Color.Transparent),
maxLines = 1,
// Configure soft keyboard
keyboardOptions = KeyboardOptions.Default.copy(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {
onImeAction()
// Click finish Hidden keyboard
keyboardController?.hide()
})
)
}
@Composable()
fun TodoEditButton(
onClick: () -> Unit,
text: String,
modifier: Modifier = Modifier,
enable: Boolean = true
) {
TextButton(
onClick = onClick,
shape = CircleShape,
colors = ButtonDefaults.buttonColors(),
modifier = modifier,
enabled = enable
) {
Text(text)
}
}
// Top layout
@Composable
fun TodoItemEntryInput(onItemComplete: (TodoItem) -> Unit) {
val (text, setText) = remember {
mutableStateOf("")
}
val (icon, setIcon) = remember {
mutableStateOf(ToDoIcon.Default)
}
//icon Whether it can be one depends on whether the text has content
val iconsVisible = text.isNotBlank()
// Click on add
val submit = {
onItemComplete(TodoItem(text, icon))
setText("")
setIcon(ToDoIcon.Default)
}
TodoItemInput(
text = text,
onTextChange = setText,
icon = icon,
onIconChange = setIcon,
iconsVisible = iconsVisible,
submit = submit,
buttonSlot = {
TodoEditButton(
onClick = submit,
text = " add to ",
enable = text.isNotBlank()
)
}
)
}
// Input box Add other
@Composable
fun TodoItemInput(
text: String,
onTextChange: (String) -> Unit,
icon: ToDoIcon,
onIconChange: (ToDoIcon) -> Unit,
iconsVisible: Boolean,
submit: () -> Unit,
buttonSlot: @Composable () -> Unit
) {
Column {
Row(
Modifier
.padding(horizontal = 16.dp)
.padding(top = 16.dp)
) {
TodoInputText(
text = text,
modifier = Modifier
.weight(1f)
.padding(end = 8.dp),
onTextChanged = onTextChange,
onImeAction = submit
)
Spacer(Modifier.width(8.dp))
Box(modifier = Modifier.align(Alignment.CenterVertically)) {
buttonSlot()
}
}
AnimatedIconRow(
visible = iconsVisible,
icon = icon,
onIconChange = onIconChange,
modifier = Modifier.padding(8.dp)
)
}
}
// Row of icons Depending on whether the text box has content Auto bounce and retract
@Composable
fun AnimatedIconRow(
modifier: Modifier = Modifier,
visible: Boolean,
icon: ToDoIcon,
onIconChange: (ToDoIcon) -> Unit
) {
val enter = remember {
fadeIn(animationSpec = TweenSpec(300, easing = FastOutLinearInEasing))
}
val exit = remember {
fadeOut(animationSpec = TweenSpec(100, easing = FastOutSlowInEasing))
}
// Minimum height 16dp
AnimatedVisibility(visible = visible, enter = enter, exit = exit, modifier = modifier) {
IconRow(icon = icon, onIconChange = onIconChange)
}
}
@Composable
fun IconRow(icon: ToDoIcon, onIconChange: (ToDoIcon) -> Unit, modifier: Modifier = Modifier) {
Row(modifier = modifier) {
for (todoIcon in ToDoIcon.values()) {
SelectableIconButton(
icon = todoIcon.imageVector,
iconContentDescription = todoIcon.contentDescription,
onIconSelect = { onIconChange(todoIcon) },
isSelected = todoIcon == icon
)
}
}
}
@Composable
fun SelectableIconButton(
icon: ImageVector,
iconContentDescription: Int,
onIconSelect: () -> Unit,
isSelected: Boolean,
modifier: Modifier = Modifier
) {
// Icons checked and unchecked The colors are different
val tint = if (isSelected) {
MaterialTheme.colors.primary
} else {
MaterialTheme.colors.onSurface.copy(alpha = 0.6f)
}
val enter = remember {
fadeIn(animationSpec = TweenSpec(300, easing = FastOutLinearInEasing))
}
val exit = remember {
fadeOut(animationSpec = TweenSpec(100, easing = FastOutSlowInEasing))
}
TextButton(onClick = onIconSelect, modifier = modifier) {
Column {
Icon(
imageVector = icon,
tint = tint,
contentDescription = stringResource(id = iconContentDescription)
)
// Minimum height 16dp
AnimatedVisibility(visible = isSelected, enter = enter, exit = exit) {
Box(
Modifier
.padding(top = 3.dp)
.width(icon.defaultWidth)
.height(1.dp)
.background(tint)
)
}
}
}
}
TodoScreen.kt
package com.anguomob.jecpack.activity.compose.todo.one
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import com.anguomob.jecpack.activity.compose.todo.bean.TodoItem
import generateRandomTodoItem
import kotlin.random.Random
@Composable
fun TodoScreen(
items: List<TodoItem>,
currentlyEditing: TodoItem?,
onAddItem: (TodoItem) -> Unit,
onRemove: (TodoItem) -> Unit,
onStartEdit: (TodoItem) -> Unit,
onEditItemChange: (TodoItem) -> Unit,
onEditDone: () -> Unit,
) {
Column() {
val enableTopSection = currentlyEditing == null
// Input box Plus a gray background
ToDoItemInputBackground(content = {
if (enableTopSection) {
TodoItemEntryInput(onItemComplete = onAddItem)
} else {
Text(
text = " Edit entry ",
style = MaterialTheme.typography.h6,
textAlign = TextAlign.Center,
modifier = Modifier
.align(Alignment.CenterVertically)
.padding(16.dp)
.fillMaxWidth()
)
}
}, elevatioon = true)
LazyColumn(
modifier = Modifier
.weight(1f)
) {
items(items) { todo ->
if (currentlyEditing?.id == todo.id) {
TodoItemInLineEditor(
item = currentlyEditing,
onEditItemChange = onEditItemChange,
onEditDone = onEditDone,
onRemoveItem = { onRemove(todo) }
)
}
TodoRow(todo, modifier = Modifier.fillParentMaxWidth(),onItemClick=onStartEdit)
}
}
Button(
onClick = {
onAddItem(generateRandomTodoItem())
},
modifier = Modifier
.padding(16.dp)
.fillMaxWidth()
) {
Text(" newly build TODO")
}
}
}
@Composable
fun TodoRow(todo: TodoItem, modifier: Modifier = Modifier, onItemClick: (TodoItem) -> Unit) {
Row(
modifier = modifier
.padding(horizontal = 16.dp, vertical = 8.dp)
.clickable { onItemClick(todo) },
// Sub elements are distributed horizontally and evenly
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(todo.task)
val iconAlpha = remember(todo.id) {
randomTint()
}
Icon(
imageVector = todo.icon.imageVector,
tint = LocalContentColor.current.copy(alpha = iconAlpha),
contentDescription = stringResource(id = todo.icon.contentDescription)
)
}
}
private fun randomTint(): Float {
val number = Random.nextFloat().coerceIn(0.3f, 0.9f)
return number
}
data bean
TodoItem.kt
package com.anguomob.jecpack.activity.compose.todo.bean
import android.support.annotation.StringRes
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.ui.graphics.vector.ImageVector
import com.anguomob.jecpack.R
import java.util.*
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) {
Square(Icons.Default.CropSquare, R.string.expand),
Done(Icons.Default.Done, R.string.done),
Event(Icons.Default.Event, R.string.event),
PrivacyTip(Icons.Default.PrivacyTip, R.string.privacy),
Trash(Icons.Default.RestoreFromTrash, R.string.restore),
Default(Square.imageVector, Square.contentDescription)
}
viewMoel
package com.anguomob.jecpack.activity.compose.todo.viewmodel
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import com.anguomob.jecpack.activity.compose.todo.bean.TodoItem
class TodoViewModel : ViewModel() {
//TODO aggregate read-only
var todoItems = mutableStateListOf<TodoItem>()
private set
// Currently editing TodoItem Index position of
private var currentEditPosition by mutableStateOf(-1)
val currentEditItem: TodoItem?
get() = todoItems.getOrNull(currentEditPosition)
fun addItem(item: TodoItem) {
todoItems.add(item)
}
fun removeItem(item: TodoItem) {
todoItems.remove(item)
onEditDone()
}
fun onEditDone() {
currentEditPosition = -1
}
// When it comes to TodoItem When an item in the list is selected , Pass in the object , Get its index position in the list
fun onEditItemSelected(item: TodoItem) {
currentEditPosition = todoItems.indexOf(item)
}
//todoItem Edit finish , Re - assign to tood Item assignment id Property cannot be modified , check
fun onEditItemChange(item: TodoItem) {
todoItems.getOrNull(currentEditPosition)?.let {
todoItems[currentEditPosition] = item
}
}
}
Click on the top of the item to display an item to update it Delete preservation
The previous new logic still exists
边栏推荐
- [in depth understanding of tcapulusdb technology] tcapulusdb model
- Analysis on planting area, output and import of sugarcane in Guangxi in 2021: the output of sugarcane in Guangxi accounts for 68.56% of the total output of sugarcane in China [figure]
- 广州华锐互动VR全景为各行各业带来发展
- El table highly adaptive
- 158_ Model_ Power Bi uses DAX + SVG to open up almost all possibilities for making business charts
- 正则表达式总结
- 06 local method interface
- Kwai 616 war report was launched, and the essence was thrown away for the second time to lead the new wave. Fast brand jumped to the top 3 of the hot list
- mysql事务讲解
- In 2021, China's private equity market is growing, and the scale of private equity fund management reaches 19.78 trillion yuan [figure]
猜你喜欢
两轮市场红海,利尔达芯智行如何乘风破浪?
03 runtime data area overview and threads
Analysis on policy, output and market scale of China's natural gas hydrogen production industry in 2020 [figure]
【ELT.ZIP】OpenHarmony啃论文俱乐部—数据密集型应用内存压缩
04 program counter (PC register)
Pycharm 使用过程中碰到问题
07 local method stack
Overview and trend analysis of China's foreign direct investment industry in 2020 [figure]
云上弹性高性能计算,支持生命科学产业高速发展、降本增效
Use pagoda to set up mqtt server
随机推荐
Huawei cloud SRE deterministic operation and maintenance special issue (the first issue)
RMAN backup database_ Manage backup window
mysql事务讲解
05 virtual machine stack
Tiger DAO VC产品正式上线,Seektiger生态的有力补充
Anaconda download Tsinghua source
[in depth understanding of tcapulusdb technology] form creation and approval of document acceptance
跳一跳小游戏辅助(手动版本)py代码实现
LeetCode 3. Longest substring without repeated characters & sliding window
C ASP, net core framework value transfer method and session use
06 local method interface
Training of long and difficult sentences in postgraduate entrance examination day90
RMAN备份数据库_跳过脱机,只读和不可访问的文件
Analysis on planting area, output and import of sugarcane in Guangxi in 2021: the output of sugarcane in Guangxi accounts for 68.56% of the total output of sugarcane in China [figure]
RMAN backup database_ catalogue
[in depth understanding of tcapulusdb technology] tcapulusdb model
TCP/IP 测试题(三)
2021 development status of China's cloud game industry and analysis of major service providers: Although cloud games are still in their infancy, the market prospect is huge [figure]
Idea annotation color modification method (clear)
Analysis on policy, output and market scale of China's natural gas hydrogen production industry in 2020 [figure]