Multiple choices in a list with compose

Multiple choices in a list with compose

Jetpack Compose is Android’s modern toolkit for building native UI. It simplifies and accelerates UI development on Android. Quickly bring your app to life with less code, powerful tools, and intuitive Kotlin APIs.

Mutliple choices in a list with compose

you have a list with compose it is easier and if you want to do multiple choices in a list with compose you have to use rememberSaveable.

When you use compose you have to set up the gradl like this:

kotlinOptions {
jvmTarget = ‘1.8’
useIR = true
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion “1.0.0-beta08”
}
}

dependencies {

implementation ‘androidx.core:core-ktx:1.5.0’
implementation ‘androidx.appcompat:appcompat:1.3.0’
implementation ‘com.google.android.material:material:1.3.0’
implementation ‘androidx.constraintlayout:constraintlayout:2.0.4’
testImplementation ‘junit:junit:4.13.2’
androidTestImplementation ‘androidx.test.ext:junit:1.1.2’
androidTestImplementation ‘androidx.test.espresso:espresso-core:3.3.0’

// Compose
implementation “org.jetbrains.kotlin:kotlin-stdlib:1.0.0-beta08”
implementation “androidx.activity:activity-compose:1.3.0-beta01”
implementation “androidx.compose.runtime:runtime:1.0.0-beta08”
implementation “androidx.compose.ui:ui:1.0.0-beta08”
implementation “androidx.compose.foundation:foundation:1.0.0-beta08”
implementation “androidx.compose.foundation:foundation-layout:1.0.0-beta08”
implementation “androidx.compose.material:material:1.0.0-beta08”
implementation “androidx.compose.runtime:runtime-livedata:1.0.0-beta08”
implementation “androidx.compose.ui:ui-tooling:1.0.0-beta08”
implementation “com.google.android.material:compose-theme-adapter:1.0.0-beta08”
}
Share

While remember helps you retain state across recompositions, the state is not retained across configuration changes. For this, you must use rememberSaveable. rememberSaveable automatically saves any value that can be saved in a Bundle. For other values, you can pass in a custom saver object.

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.compose.animation.animateColorAsState
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material.Surface
import androidx.compose.material.TabRowDefaults.Divider
import androidx.compose.material.Text
import androidx.compose.material.Checkbox
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyApp {
                MyScreenContent()
            }
        }
    }
}

@Composable
fun MyApp(content: @Composable () -> Unit) {
    Surface(color = Color.White) {
        content()
    }
}

@Composable
fun MyScreenContent(
    names: List<String> = List(15) { "Item #$it" },
    completed: MutableList<Boolean> = MutableList(15) { false }
) {
    Column(modifier = Modifier.fillMaxHeight()) {
        NameList(names, Modifier.weight(1f), completed)
    }
}

@Composable
fun NameList(names: List<String>, modifier: Modifier, completed: MutableList<Boolean>) {
    LazyColumn(modifier = modifier) {
        itemsIndexed(items = names) { index: Int, item: String ->
            Greeting(name = item, completed, index)
            Divider(color = Color.Black)
        }
    }
}

@Composable
fun Greeting(name: String, completedList: MutableList<Boolean>, index: Int) {
    var isSelected by rememberSaveable { mutableStateOf(completedList[index]) }
    val backgroundColor by animateColorAsState(if (isSelected) Color.Blue else Color.Transparent)

    Row {
        Text(
            text = "Hello $name!",
            modifier = Modifier
                .padding(24.dp)
        )
        Checkbox(
                checked = isSelected,
                onCheckedChange = {
                    isSelected = !isSelected
                    completedList[index] = !isSelected
                },
                modifier = Modifier
                    .background(color = backgroundColor)
            )
        }
    }


@Preview("MyScreen preview")
@Composable
fun DefaultPreview() {
    MyApp {
        MyScreenContent()
    }
}

you can download in Github

Kotlin Android Extensions in Adapter

Kotlin Android Extensions in Adapter

Sometimes is difficult to use kotlin android extensions, the best way to use Kotlin synthetic in Adapter or ViewHolder is like this:

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = tasks[position]
holder.bind(item, checkTask, deleteTask)
}

No need to write

val tvTask = view.findViewById(R.id.tvTask)
tvTask.text = task.description

Just

 
itemView.task_item_textView.text = task.description

Or in fun bind you can put

 = with(itemView)

All the fun

fun bind(task: Task, checkTask: (Task) -> Unit, deleteTask: 
(Task) -> Unit) = with(itemView){
            task_item_textView.text = task.description
            task_item_done_checkBox.isChecked = task.completed
            task_item_done_checkBox.setOnClickListener{checkTask(task)}
            setOnClickListener { deleteTask(task) }
        }

Example in Git Hub