Skip to content

Commit

Permalink
Merge pull request #28 from aclassen/feature/v0.7
Browse files Browse the repository at this point in the history
Feature/v0.7
  • Loading branch information
aclassen authored Oct 13, 2021
2 parents afb03ab + 36ce022 commit 29496a2
Show file tree
Hide file tree
Showing 17 changed files with 250 additions and 43 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,11 +55,11 @@ fun ReorderList(vm: ReorderListViewModel = viewModel()) {
}

@Composable
fun HorizontalReorderList(
private fun HorizontalReorderList(
modifier: Modifier = Modifier,
items: List<ItemData>,
state: ReorderableState = rememberReorderState(),
onMove: (fromPos: Int, toPos: Int) -> (Unit),
onMove: (fromPos: ItemPosition, toPos: ItemPosition) -> (Unit),
) {
LazyRow(
state = state.listState,
Expand Down Expand Up @@ -91,12 +88,12 @@ fun HorizontalReorderList(
}

@Composable
fun VerticalReorderList(
private fun VerticalReorderList(
modifier: Modifier = Modifier,
items: List<ItemData>,
state: ReorderableState = rememberReorderState(),
onMove: (fromPos: Int, toPos: Int) -> (Unit),
canDragOver: ((index: Int) -> Boolean),
onMove: (fromPos: ItemPosition, toPos: ItemPosition) -> (Unit),
canDragOver: ((pos: ItemPosition) -> Boolean),
) {
LazyColumn(
state = state.listState,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ 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


Expand All @@ -26,13 +27,13 @@ class ReorderListViewModel : ViewModel() {
if (it.mod(10) == 0) ItemData("Locked", "id$it", true) else ItemData("Dog $it", "id$it")
}.toMutableStateList()

fun moveCat(from: Int, to: Int) {
cats.move(from, to)
fun moveCat(from: ItemPosition, to: ItemPosition) {
cats.move(from.index, to.index)
}

fun moveDog(from: Int, to: Int) {
dogs.move(from, to)
fun moveDog(from: ItemPosition, to: ItemPosition) {
dogs.move(from.index, to.index)
}

fun isDogDragEnabled(idx: Int) = dogs.getOrNull(idx)?.isLocked != true
fun isDogDragEnabled(pos: ItemPosition) = dogs.getOrNull(pos.index)?.isLocked != true
}
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>
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ buildscript {

dependencies {
classpath("org.jetbrains.compose:compose-gradle-plugin:1.0.0-alpha3")
classpath("com.android.tools.build:gradle:4.2.2")
classpath("com.android.tools.build:gradle:7.0.3")
classpath(kotlin("gradle-plugin", version = "1.5.21"))
}
}
Expand Down
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 gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading

0 comments on commit 29496a2

Please sign in to comment.