I'm currently thinking about creating an initiative tracker app for a friend of mine and since I've been out of touch with app development for quite a while I'm trying to evaluate which tools would best suit my needs.
Since the App is going to be developed for Android, I'm pretty sure I'll be using Kotlin and therefore Jetpack Compose caught my eye.
After making a bit of research and going through the docs though, I'm unsure if it is capable of what I want to achieve:
I want to be able to create a dynamic list of entry cards sorted by a certain value asigned to each card. (Which I'm relatively certain LazyColumns will be able to handle).
The catch is this: Each of these cards needs to have buttons and several additional values that can be manipulated with these buttons.
I haven't been able to find descriptions of something like this in the docs or any examples using Jetpack Compose LazyColumns.
I created a (badly made) mockup to hopefully better describe what it is I want to do:
Would anyone be able to share insights on if Jetpack Compose is capable of these features or if not could share advice on what tool to use instead?
Thanks alot and Kind regards.
CodePudding user response:
Yes, with Compose, you can quite easily make such an application.
Here is a basic example of such a UI.
class MainActivity : FragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
AppTheme {
ItemsScreen()
}
}
}
}
class Item(val title: String, value1: Int, value2: Int, value3: Int) {
val value1 = mutableStateOf(value1)
val value2 = mutableStateOf(value2)
val value3 = mutableStateOf(value3)
val valueToSortBy: Int
get() = value1.value value2.value value3.value
}
class ScreenViewModel : ViewModel() {
val items = List(3) {
Item(
"Item $it",
Random.nextInt(10),
Random.nextInt(10),
Random.nextInt(10),
)
}.toMutableStateList()
fun sortItems() {
items.sortByDescending { it.valueToSortBy }
}
fun addNewItem() {
items.add(
Item(
"Item ${items.count()}",
Random.nextInt(10),
Random.nextInt(10),
Random.nextInt(10),
)
)
}
}
@Composable
fun ItemsScreen() {
val viewModel: ScreenViewModel = viewModel()
LaunchedEffect(viewModel.items.map { it.valueToSortBy }) {
viewModel.sortItems()
}
Box(
Modifier
.fillMaxSize()
.padding(10.dp)
) {
LazyColumn(
contentPadding = PaddingValues(vertical = 10.dp),
verticalArrangement = Arrangement.spacedBy(10.dp)
) {
items(viewModel.items) { item ->
ItemView(item)
}
}
FloatingActionButton(
onClick = viewModel::addNewItem,
modifier = Modifier.align(Alignment.BottomEnd)
) {
Text(" ")
}
}
}
@Composable
fun ItemView(item: Item) {
Card(
elevation = 5.dp,
) {
Column(modifier = Modifier.padding(10.dp)) {
Row(
verticalAlignment = Alignment.CenterVertically,
) {
Text(
item.title,
style = MaterialTheme.typography.h5
)
Spacer(modifier = Modifier.weight(1f))
Text(
"Value to sort by: ${item.valueToSortBy}",
style = MaterialTheme.typography.body1,
fontStyle = FontStyle.Italic,
)
}
Spacer(modifier = Modifier.size(25.dp))
Row(
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier.fillMaxWidth()
) {
CounterView(value = item.value1.value, setValue = { item.value1.value = it })
CounterView(value = item.value2.value, setValue = { item.value2.value = it })
CounterView(value = item.value3.value, setValue = { item.value3.value = it })
}
}
}
}
@Composable
fun CounterView(value: Int, setValue: (Int) -> Unit) {
Row(verticalAlignment = Alignment.CenterVertically) {
CounterButton(" ") {
setValue(value 1)
}
Text(
value.toString(),
modifier = Modifier.padding(5.dp)
)
CounterButton("-") {
setValue(value - 1)
}
}
}
@Composable
fun CounterButton(text: String, onClick: () -> Unit) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.size(45.dp)
.background(Color.LightGray)
.clickable(onClick = onClick)
) {
Text(
text,
color = Color.White,
)
}
}
I'm sorting by sum of 3 values here. Note that sorting items like this may not do much performant in a production app, you should use a database to store items and request sorted items from it.