Skip to content

Commit

Permalink
Added new "fixed items" sample
Browse files Browse the repository at this point in the history
  • Loading branch information
aclassen committed Oct 13, 2021
1 parent 10d3547 commit 36ce022
Show file tree
Hide file tree
Showing 11 changed files with 221 additions and 17 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ val state = rememberReorderState()
LazyColumn(
state = state.listState,
modifier = Modifier.reorderable(state, { from, to -> data.move(from, to) })) {
modifier = Modifier.reorderable(state, { from, to -> data.move(from.index, to.index) })) {
...
}
```
Expand Down Expand Up @@ -69,7 +69,7 @@ fun ReorderableList(){
val data = List(100) { "item $it" }.toMutableStateList()
LazyColumn(
state = state.listState,
modifier = Modifier.reorderable(state, { a, b -> data.move(a, b) })
modifier = Modifier.reorderable(state, { from, to -> data.move(from.index, to.index) })
) {
items(data, { it }) { item ->
Box(
Expand Down
2 changes: 2 additions & 0 deletions android/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ dependencies {
implementation("com.google.android.material:material:1.4.0")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.4.0-rc01")
implementation("androidx.navigation:navigation-compose:2.4.0-alpha10")
implementation("io.coil-kt:coil-compose:1.4.0")
}

android {
Expand Down
1 change: 1 addition & 0 deletions android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.burnoutcrew.android">
<uses-permission android:name="android.permission.INTERNET" />

<application
android:icon="@mipmap/ic_launcher"
Expand Down
76 changes: 72 additions & 4 deletions android/src/main/kotlin/org/burnoutcrew/android/ui/Root.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,92 @@
*/
package org.burnoutcrew.android.ui

import androidx.compose.material.Scaffold
import androidx.compose.material.Text
import androidx.compose.material.TopAppBar
import androidx.compose.foundation.layout.padding
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.List
import androidx.compose.material.icons.filled.Star
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.navigation.NavController
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import org.burnoutcrew.android.R
import org.burnoutcrew.android.ui.reorderlist.ReorderImageList
import org.burnoutcrew.android.ui.reorderlist.ReorderList
import org.burnoutcrew.android.ui.theme.ReorderListTheme


@Composable
fun Root() {
ReorderListTheme {
val navController = rememberNavController()
val navigationItems = listOf(
NavigationItem.Lists,
NavigationItem.Music,
)
Scaffold(
topBar = {
TopAppBar(title = { Text(stringResource(R.string.app_name)) })
},
bottomBar = {
BottomNavigationBar(navigationItems, navController)
}
) {
Navigation(
navController,
Modifier.padding(top = it.calculateTopPadding(), bottom = it.calculateBottomPadding())
)
}
}
}

@Composable
private fun Navigation(navController: NavHostController, modifier: Modifier) {
NavHost(navController, startDestination = NavigationItem.Lists.route, modifier = modifier) {
composable(NavigationItem.Lists.route) {
ReorderList()
}
composable(NavigationItem.Music.route) {
ReorderImageList()
}
}
}
}


@Composable
private fun BottomNavigationBar(items: List<NavigationItem>, navController: NavController) {
BottomNavigation(contentColor = Color.White) {
val navBackStackEntry = navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry.value?.destination?.route
items.forEach { item ->
BottomNavigationItem(
icon = { Icon(item.icon, item.title) },
label = { Text(text = item.title) },
selected = currentRoute == item.route,
onClick = {
navController.navigate(item.route) {
navController.graph.startDestinationRoute?.let { route ->
popUpTo(route) {
saveState = true
}
}
launchSingleTop = true
restoreState = true
}
}
)
}
}
}

private sealed class NavigationItem(var route: String, var icon: ImageVector, var title: String) {
object Lists : NavigationItem("lists", Icons.Default.List, "Lists")
object Music : NavigationItem("fixed", Icons.Default.Star, "Fixed")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2021 André Claßen
*
* 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 org.burnoutcrew.android.ui.reorderlist

import androidx.compose.runtime.toMutableStateList
import androidx.lifecycle.ViewModel
import org.burnoutcrew.reorderable.ItemPosition
import org.burnoutcrew.reorderable.move
import kotlin.random.Random


class ImageListViewModel : ViewModel() {
val images = List(20) { "https://picsum.photos/seed/compose$it/200/300" }.toMutableStateList()
val headerImage = "https://picsum.photos/seed/compose${Random.nextInt(Int.MAX_VALUE)}/400/200"
val footerImage = "https://picsum.photos/seed/compose${Random.nextInt(Int.MAX_VALUE)}/400/200"

fun onMove(from: ItemPosition, to: ItemPosition) {
images.move(images.indexOfFirst { it == from.key }, images.indexOfFirst { it == to.key })
}

fun canDragOver(pos: ItemPosition) = images.any { it == pos.key }
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,4 @@
*/
package org.burnoutcrew.android.ui.reorderlist

import androidx.compose.runtime.Stable

@Stable
data class ItemData(val title: String, val key: String, val isLocked: Boolean = false)
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* Copyright 2021 André Claßen
*
* 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 org.burnoutcrew.android.ui.reorderlist


import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.Divider
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import coil.compose.rememberImagePainter
import org.burnoutcrew.android.R
import org.burnoutcrew.reorderable.*

@Composable
fun ReorderImageList(
vm: ImageListViewModel = viewModel(),
state: ReorderableState = rememberReorderState(),
modifier: Modifier = Modifier,
) {
LazyColumn(
state = state.listState,
modifier = modifier
.then(
Modifier.reorderable(
state,
onMove = { from, to -> vm.onMove(from, to) },
canDragOver = { vm.canDragOver(it) })
)
) {
item {
HeaderFooter(stringResource(R.string.header_title), vm.headerImage)
}
items(vm.images, { it }) { item ->
Column(
modifier = Modifier
.fillMaxWidth()
.draggedItem(state.offsetByKey(item))
.background(MaterialTheme.colors.surface)
.detectReorderAfterLongPress(state)
) {
Row {
Image(
painter = rememberImagePainter(item),
contentDescription = null,
modifier = Modifier.size(128.dp)
)
Text(
text = item,
modifier = Modifier.padding(16.dp)
)
}
Divider()
}
}
item {
HeaderFooter(stringResource(R.string.footer_title), vm.footerImage)
}
}
}

@Composable
private fun HeaderFooter(title: String, url: String) {
Box(modifier = Modifier.height(128.dp).fillMaxWidth()) {
Image(
painter = rememberImagePainter(url),
contentDescription = null,
modifier = Modifier.fillMaxSize(),
contentScale = ContentScale.Crop
)
Text(
title,
style = MaterialTheme.typography.h2,
color = Color.White,
modifier = Modifier.align(Alignment.Center)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
package org.burnoutcrew.android.ui.reorderlist


import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.layout.*
Expand All @@ -28,8 +27,6 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Divider
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Menu
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
Expand Down Expand Up @@ -58,7 +55,7 @@ fun ReorderList(vm: ReorderListViewModel = viewModel()) {
}

@Composable
fun HorizontalReorderList(
private fun HorizontalReorderList(
modifier: Modifier = Modifier,
items: List<ItemData>,
state: ReorderableState = rememberReorderState(),
Expand Down Expand Up @@ -91,7 +88,7 @@ fun HorizontalReorderList(
}

@Composable
fun VerticalReorderList(
private fun VerticalReorderList(
modifier: Modifier = Modifier,
items: List<ItemData>,
state: ReorderableState = rememberReorderState(),
Expand Down
2 changes: 2 additions & 0 deletions android/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<resources>
<string name="app_name">Lazy reorder list</string>
<string name="header_title">Header</string>
<string name="footer_title">Footer</string>
</resources>
4 changes: 2 additions & 2 deletions desktop/src/jvmMain/kotlin/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ fun main() = application {
onCloseRequest = ::exitApplication,
title = "Lazy reorder list"
) {
VerticalReorderList(items = data) { a, b -> data.move(a, b) }
VerticalReorderList(items = data) { a, b -> data.move(a.index, b.index) }
}
}

@Composable
fun VerticalReorderList(
items: List<String>,
state: ReorderableState = rememberReorderState(),
onMove: (fromPos: Int, toPos: Int) -> (Unit),
onMove: (fromPos: ItemPosition, toPos: ItemPosition) -> (Unit),
) {
Box {
LazyColumn(
Expand Down
2 changes: 1 addition & 1 deletion reorderable/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ plugins {
}

group = "org.burnoutcrew.composereorderable"
version = "0.6.2"
version = "0.7.0"

kotlin {
android {
Expand Down

0 comments on commit 36ce022

Please sign in to comment.