Browse Source

Add scrollbar to Todo example (#41)

pull/49/head
Arkadii Ivanov 4 years ago committed by GitHub
parent
commit
05303f947d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 75
      examples/todoapp/common/main/src/commonMain/kotlin/example/todo/common/main/ui/TodoMainUi.kt
  2. 26
      examples/todoapp/common/utils/src/androidMain/kotlin/example/todo/common/utils/compose/Scrollbars.kt
  3. 23
      examples/todoapp/common/utils/src/commonMain/kotlin/example/todo/common/utils/compose/Scrollbars.kt
  4. 36
      examples/todoapp/common/utils/src/desktopMain/kotlin/example/todo/common/utils/compose/Scrollbars.kt
  5. 18
      examples/todoapp/desktop/src/jvmMain/kotlin/example/todo/desktop/Main.kt

75
examples/todoapp/common/main/src/commonMain/kotlin/example/todo/common/main/ui/TodoMainUi.kt

@ -1,18 +1,20 @@
package example.todo.common.main.ui package example.todo.common.main.ui
import androidx.compose.foundation.Icon
import androidx.compose.foundation.Text import androidx.compose.foundation.Text
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumnFor import androidx.compose.foundation.lazy.LazyColumnFor
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.Button import androidx.compose.material.Button
import androidx.compose.material.Checkbox import androidx.compose.material.Checkbox
import androidx.compose.material.Divider import androidx.compose.material.Divider
import androidx.compose.material.Icon
import androidx.compose.material.IconButton import androidx.compose.material.IconButton
import androidx.compose.material.OutlinedTextField import androidx.compose.material.OutlinedTextField
import androidx.compose.material.TopAppBar import androidx.compose.material.TopAppBar
@ -32,6 +34,9 @@ import example.todo.common.main.TodoMain.Output
import example.todo.common.main.store.TodoItem import example.todo.common.main.store.TodoItem
import example.todo.common.main.store.TodoMainStore.Intent import example.todo.common.main.store.TodoMainStore.Intent
import example.todo.common.main.store.TodoMainStore.State import example.todo.common.main.store.TodoMainStore.State
import example.todo.common.utils.compose.MARGIN_SCROLLBAR
import example.todo.common.utils.compose.VerticalScrollbar
import example.todo.common.utils.compose.rememberScrollbarAdapter
import example.todo.common.utils.onKeyUp import example.todo.common.utils.onKeyUp
@Composable @Composable
@ -67,33 +72,63 @@ private fun TodoList(
onDoneChanged: (id: Long, isDone: Boolean) -> Unit, onDoneChanged: (id: Long, isDone: Boolean) -> Unit,
onDeleteItemClicked: (id: Long) -> Unit onDeleteItemClicked: (id: Long) -> Unit
) { ) {
LazyColumnFor(items = items) { item -> Box {
Row(modifier = Modifier.clickable(onClick = { onItemClicked(item.id) })) { val listState = rememberLazyListState()
Spacer(modifier = Modifier.width(8.dp))
LazyColumnFor(items = items, state = listState) {
Checkbox( Item(
checked = item.isDone, item = it,
modifier = Modifier.align(Alignment.CenterVertically), onItemClicked = onItemClicked,
onCheckedChange = { onDoneChanged(item.id, it) } onDoneChanged = onDoneChanged,
onDeleteItemClicked = onDeleteItemClicked
) )
Spacer(modifier = Modifier.width(8.dp)) Divider()
}
Text( VerticalScrollbar(
text = AnnotatedString(item.text), modifier = Modifier.align(Alignment.CenterEnd).fillMaxHeight(),
modifier = Modifier.weight(1F).align(Alignment.CenterVertically), adapter = rememberScrollbarAdapter(
maxLines = 1, scrollState = listState,
overflow = TextOverflow.Ellipsis itemCount = items.size,
averageItemSize = 37.dp
) )
)
}
}
@Composable
private fun Item(
item: TodoItem,
onItemClicked: (id: Long) -> Unit,
onDoneChanged: (id: Long, isDone: Boolean) -> Unit,
onDeleteItemClicked: (id: Long) -> Unit
) {
Row(modifier = Modifier.clickable(onClick = { onItemClicked(item.id) })) {
Spacer(modifier = Modifier.width(8.dp))
Checkbox(
checked = item.isDone,
modifier = Modifier.align(Alignment.CenterVertically),
onCheckedChange = { onDoneChanged(item.id, it) }
)
Spacer(modifier = Modifier.width(8.dp))
Text(
text = AnnotatedString(item.text),
modifier = Modifier.weight(1F).align(Alignment.CenterVertically),
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
Spacer(modifier = Modifier.width(8.dp)) Spacer(modifier = Modifier.width(8.dp))
IconButton(onClick = { onDeleteItemClicked(item.id) }) { IconButton(onClick = { onDeleteItemClicked(item.id) }) {
Icon(Icons.Default.Delete) Icon(Icons.Default.Delete)
}
} }
Divider() Spacer(modifier = Modifier.width(MARGIN_SCROLLBAR))
} }
} }

26
examples/todoapp/common/utils/src/androidMain/kotlin/example/todo/common/utils/compose/Scrollbars.kt

@ -0,0 +1,26 @@
package example.todo.common.utils.compose
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
actual val MARGIN_SCROLLBAR: Dp = 0.dp
actual interface ScrollbarAdapter
@Composable
actual fun rememberScrollbarAdapter(
scrollState: LazyListState,
itemCount: Int,
averageItemSize: Dp
): ScrollbarAdapter =
object : ScrollbarAdapter {}
@Composable
actual fun VerticalScrollbar(
modifier: Modifier,
adapter: ScrollbarAdapter
) {
}

23
examples/todoapp/common/utils/src/commonMain/kotlin/example/todo/common/utils/compose/Scrollbars.kt

@ -0,0 +1,23 @@
package example.todo.common.utils.compose
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.Dp
expect val MARGIN_SCROLLBAR: Dp
expect interface ScrollbarAdapter
@Composable
expect fun rememberScrollbarAdapter(
scrollState: LazyListState,
itemCount: Int,
averageItemSize: Dp
): ScrollbarAdapter
@Composable
expect fun VerticalScrollbar(
modifier: Modifier,
adapter: ScrollbarAdapter
)

36
examples/todoapp/common/utils/src/desktopMain/kotlin/example/todo/common/utils/compose/Scrollbars.kt

@ -0,0 +1,36 @@
package example.todo.common.utils.compose
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
actual val MARGIN_SCROLLBAR: Dp = 8.dp
actual typealias ScrollbarAdapter = androidx.compose.foundation.ScrollbarAdapter
@OptIn(ExperimentalFoundationApi::class)
@Composable
actual fun rememberScrollbarAdapter(
scrollState: LazyListState,
itemCount: Int,
averageItemSize: Dp
): ScrollbarAdapter =
androidx.compose.foundation.rememberScrollbarAdapter(
scrollState = scrollState,
itemCount = itemCount,
averageItemSize = averageItemSize
)
@Composable
actual fun VerticalScrollbar(
modifier: Modifier,
adapter: ScrollbarAdapter
) {
androidx.compose.foundation.VerticalScrollbar(
modifier = modifier,
adapter = adapter
)
}

18
examples/todoapp/desktop/src/jvmMain/kotlin/example/todo/desktop/Main.kt

@ -1,7 +1,9 @@
package example.todo.desktop package example.todo.desktop
import androidx.compose.desktop.AppWindow import androidx.compose.desktop.AppWindow
import androidx.compose.desktop.DesktopTheme
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface import androidx.compose.material.Surface
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import com.arkivanov.decompose.DefaultComponentContext import com.arkivanov.decompose.DefaultComponentContext
@ -23,13 +25,17 @@ fun main() {
AppWindow("Todo").show { AppWindow("Todo").show {
Surface(modifier = Modifier.fillMaxSize()) { Surface(modifier = Modifier.fillMaxSize()) {
TodoRoot( MaterialTheme {
componentContext = DefaultComponentContext(lifecycle), DesktopTheme {
dependencies = object : TodoRoot.Dependencies { TodoRoot(
override val storeFactory = DefaultStoreFactory componentContext = DefaultComponentContext(lifecycle),
override val database = TodoDatabase(TodoDatabaseDriver()) dependencies = object : TodoRoot.Dependencies {
override val storeFactory = DefaultStoreFactory
override val database = TodoDatabase(TodoDatabaseDriver())
}
).invoke()
} }
).invoke() }
} }
} }
} }

Loading…
Cancel
Save