Jetpack Compose is like AndroidView
Text
Plain Text
Kotlin
@Composable
fun Label() {
    Text(
        text = "Hello World",
        maxLines = 1,
        overflow = TextOverflow.Ellipsis,
        modifier = Modifier
            .wrapContentHeight()
            .wrapContentWidth(),
        style = TextStyle(background = Color(0xFF4a8fff))
    )
}
Xml
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="#FF4a8fff"
    android:ellipsize="end"
    android:text = "YourText"
    android:maxLines="1" />
Password
Kotlin
@OptIn(ExperimentalComposeUiApi::class)
@Composable
private fun Password() {
    var text by remember { mutableStateOf(TextFieldValue("")) }
    val keyboardController = LocalSoftwareKeyboardController.current
    TextField(
        value = text,
        onValueChange = {
            text = it
        },
        modifier = Modifier
            .requiredWidth(250.dp)
            .wrapContentHeight(),
        maxLines = 1,
        label = {
            Text(text = "Your Label")
        },
        placeholder = {
            Text(text = "Your Placeholder/Hint")
        },
        keyboardOptions = KeyboardOptions(
            keyboardType = KeyboardType.Password,
            imeAction = ImeAction.Done
        ),
        keyboardActions = KeyboardActions(
            onDone = { keyboardController?.hide() }),
        visualTransformation = PasswordVisualTransformation()
    )
}
Xml
<com.google.android.material.textfield.TextInputLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:hint="Your Label"
    app:placeholderText="Your Placeholder">

    <com.google.android.material.textfield.TextInputEditText
        android:layout_width="250dp"
        android:layout_height="wrap_content"
        android:inputType="textPassword"
        android:maxLines="1" />

</com.google.android.material.textfield.TextInputLayout>
Password (Numeric)
Kotlin
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun NumberPassword() {
    var text by remember { mutableStateOf(TextFieldValue("")) }
    val keyboardController = LocalSoftwareKeyboardController.current
    TextField(
        value = text,
        onValueChange = {
            text = it
        },
        maxLines = 1,
        label = {
            Text(text = "Your Label")
        },
        placeholder = {
            Text(text = "Your Placeholder/Hint")
        },
        keyboardOptions = KeyboardOptions(
            keyboardType = KeyboardType.NumberPassword,
            imeAction = ImeAction.Done
        ),
        keyboardActions = KeyboardActions(
            onDone = { keyboardController?.hide() }),
        visualTransformation = PasswordVisualTransformation()
    )
}
Xml
<com.google.android.material.textfield.TextInputLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:hint="Your Label"
    app:placeholderText="Your Placeholder">

    <com.google.android.material.textfield.TextInputEditText
        android:layout_width="250dp"
        android:layout_height="wrap_content"
        android:inputType="numberPassword"
        android:maxLines="1" />

</com.google.android.material.textfield.TextInputLayout>
Password With Visibility Toggle
Kotlin
@OptIn(ExperimentalComposeUiApi::class)
@Composable
private fun PasswordVisibilityToggle() {

    var text by remember { mutableStateOf(TextFieldValue("")) }
    var passwordVisibility by remember { mutableStateOf(false) }
    val keyboardController = LocalSoftwareKeyboardController.current

    TextField(
        value = text,
        onValueChange = {
            text = it
        },
        maxLines = 1,
        modifier = Modifier
            .requiredWidth(250.dp)
            .wrapContentHeight(),
        label = { Text(text = "Your Label") },
        placeholder = { Text(text = "Your Placeholder/Hint") },
        keyboardOptions = KeyboardOptions(
            keyboardType = KeyboardType.Password,
            imeAction = ImeAction.Done
        ),
        keyboardActions = KeyboardActions(
            onDone = { keyboardController?.hide() }),
        visualTransformation = if (passwordVisibility) {
            VisualTransformation.None
        } else {
            PasswordVisualTransformation()
        },
        trailingIcon = {
            val image = if (passwordVisibility) {
                Icons.Filled.Visibility
            } else {
                Icons.Filled.VisibilityOff
            }

            IconButton(onClick = {
                passwordVisibility = !passwordVisibility
            }) {
                Icon(imageVector = image, "")
            }
        }
    )
}
Xml
<com.google.android.material.textfield.TextInputLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:passwordToggleEnabled="true"
    android:hint="Your Hint"
    app:placeholderText="Your Placeholder">

    <com.google.android.material.textfield.TextInputEditText
        android:layout_width="250dp"
        android:layout_height="wrap_content"
        android:inputType="textPassword"
        android:maxLines="1" />

</com.google.android.material.textfield.TextInputLayout>
E-Mail
Kotlin
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun Email() {

    var text by remember { mutableStateOf(TextFieldValue("")) }
    val keyboardController = LocalSoftwareKeyboardController.current

    TextField(
        value = text,
        onValueChange = {
            text = it
        },
        modifier = Modifier
            .requiredWidth(250.dp)
            .wrapContentHeight(),
        maxLines = 1,
        label = {
            Text(text = "Your Label")
        },
        placeholder = {
            Text(text = "Your Placeholder/Hint")
        },
        keyboardOptions = KeyboardOptions(
            keyboardType = KeyboardType.Email,
            imeAction = ImeAction.Done
        ),
        keyboardActions = KeyboardActions(
            onDone = {keyboardController?.hide()} )
    )
}
Xml
<com.google.android.material.textfield.TextInputLayout
    app:placeholderText="Your Placeholder"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:hint="Your Label">

    <com.google.android.material.textfield.TextInputEditText
        android:layout_width="250dp"
        android:layout_height="wrap_content"
        android:inputType="textEmailAddress"
        android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>
Phone
Kotlin
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun PhoneNumber() {
    var text by remember { mutableStateOf(TextFieldValue("012345678900")) }
    val keyboardController = LocalSoftwareKeyboardController.current
    TextField(
        value = text,
        onValueChange = {
            text = it
        },
        maxLines = 1,
        modifier = Modifier
            .wrapContentWidth()
            .wrapContentHeight(),
        label = { Text(text = "Your Label") },
        placeholder = { Text(text = "Your Placeholder/Hint") },
        keyboardOptions = KeyboardOptions(
            keyboardType = KeyboardType.Phone,
            imeAction = ImeAction.Done
        ),
        keyboardActions = KeyboardActions(
            onDone = { keyboardController?.hide() })
    )
}
Xml
<com.google.android.material.textfield.TextInputLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:hint="Your Label"
    app:placeholderText="Your Placeholder">

    <com.google.android.material.textfield.TextInputEditText
        android:layout_width="250dp"
        android:layout_height="wrap_content"
        android:inputType="phone"
        android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>
Postal Address
Kotlin
@Composable
fun PostalAddressExample() {

    var address by remember { mutableStateOf("") }

    TextField(
        value = address,
        onValueChange = { address = it },
    )
}
Xml
<EditText
    android:id="@+id/editTextTextPostalAddress"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:ems="10"
    android:inputType="textPostalAddress" />
Multiline Text
Kotlin
@Composable
fun MultilineText() {
    val text = remember { mutableStateOf("") }
    TextField(
        value = text.value,
        onValueChange = {
            text.value = it
        },
        keyboardOptions = KeyboardOptions(
            keyboardType = KeyboardType.Text
        ),
        label = {
            Text(text = "Label")
        },
        placeholder = {
            Text(text = "Your Placeholder/Hint")
        },
        maxLines = 3,
        modifier = Modifier.width(250.dp)
    )
}
Xml
<com.google.android.material.textfield.TextInputLayout
    android:id="@+id/editTextTextMultiLine"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:ems="10"
    android:gravity="start|top"
    android:hint="@string/your_label"
    android:inputType="textMultiLine"
    app:placeholderText="Your Placeholder">

    <com.google.android.material.textfield.TextInputEditText
        android:layout_width="250dp"
        android:layout_height="wrap_content"
        android:maxLines="3" />

</com.google.android.material.textfield.TextInputLayout>
Number
Kotlin
@Composable
fun NumberExample() {

    var number by remember { mutableStateOf("") }

    TextField(
        value = number,
        onValueChange = { input ->
            number = input
        },
        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
    )
}
Xml
<EditText
    android:id="@+id/editTextNumber"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:ems="10"
    android:inputType="number" />
Number (Signed)
Kotlin
@Composable
fun NumberSignedExample() {

    var number by remember { mutableStateOf("") }

    TextField(
        value = number,
        onValueChange = { input ->
            number = validateInput(input)
        },
        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
    )
}

private fun validateInput(input: String): String {
    val filteredChars = input.filterIndexed { index, char ->
        char in "0123456789" ||
                (char == '-' && 0 == index)
    }
    return filteredChars
}
Xml
<EditText
    android:id="@+id/editTextNumberSigned"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:ems="10"
    android:inputType="numberSigned" />
Number (Decimal)
Kotlin
@Composable
fun NumberDecimalExample() {

    var number by remember { mutableStateOf("") }

    TextField(
        value = number,
        onValueChange = { input ->
            number = validateInput(input)
        },
        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
    )
}

private fun validateInput(input: String): String {
    val filteredChars = input.filterIndexed { index, char ->
        char in "0123456789" ||
                (char == '.' && input.indexOf('.') == index)
    }
    return filteredChars
}
Xml
<EditText
    android:id="@+id/editTextNumberDecimal"
    android:layout_width="250dp"
    android:layout_height="wrap_content"
    android:inputType="numberDecimal" />
Auto Complete
Kotlin
/* This is NOT an official implementation!
* Look if there is an official implementaion already*/

@Composable
private fun AutoCompleteExample() {

    val countriesList = listOf(
        "Germany",
        "Spain",
        "France",
    )

    val dropDownOptions = remember { mutableStateOf(listOf("")) }
    val textFieldValue = remember { mutableStateOf(TextFieldValue()) }
    val dropDownExpanded = remember { mutableStateOf(false) }

    fun onDropdownDismissRequest() {
        dropDownExpanded.value = false
    }

    fun onValueChanged(value: TextFieldValue) {
        dropDownExpanded.value = true
        textFieldValue.value = value
        dropDownOptions.value =
            countriesList.filter { it.startsWith(value.text) && it != value.text }.take(3)
    }

    TextFieldWithDropdown(
        value = textFieldValue.value,
        setValue = ::onValueChanged,
        onDismissRequest = ::onDropdownDismissRequest,
        dropDownExpanded = dropDownExpanded.value,
        list = dropDownOptions.value,
    )
}

@Composable
private fun TextFieldWithDropdown(
    value: TextFieldValue,
    setValue: (TextFieldValue) -> Unit,
    onDismissRequest: () -> Unit,
    dropDownExpanded: Boolean,
    list: List
) {

    TextField(
        modifier = Modifier
            .fillMaxWidth()
            .padding(20.dp)
            .onFocusChanged { focusState ->
                if (!focusState.isFocused)
                    onDismissRequest()
            },
        value = value,
        onValueChange = setValue,
        label = { Text("Enter a country of Europe") },
        colors = TextFieldDefaults.outlinedTextFieldColors()
    )
    DropdownMenu(
        expanded = dropDownExpanded,
        properties = PopupProperties(
            focusable = false,
            dismissOnBackPress = true,
            dismissOnClickOutside = true
        ),
        onDismissRequest = onDismissRequest,
    ) {
        list.forEach { text ->
            DropdownMenuItem(
                modifier = Modifier.clickable(
                    enabled = true,
                    onClickLabel = text,
                    null
                ) {
                    setValue(
                        TextFieldValue(
                            text,
                            TextRange(text.length)
                        )
                    )
                },
                onClick = {
                    setValue(
                        TextFieldValue(
                            text,
                            TextRange(text.length)
                        )
                    )
                }
            ) {
                Text(text = text)
            }
        }
    }
}
Xml
<AutoCompleteTextView
    android:id="@+id/auto_complete_text_view"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:hint="Enter a country in Europe" />

<!-- Code implementation -->

private lateinit var binding: AutoCompleteBinding

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = AutoCompleteBinding.inflate(layoutInflater)
    setContentView(binding.root)
    supportActionBar?.title = "Auto Complete"

    val countriesList = resources.getStringArray(R.array.auto_complete_array)
    val arrayAdapter = ArrayAdapter(this, R.layout.support_simple_spinner_dropdown_item, countriesList)
    binding.autoCompleteTextView.setAdapter(arrayAdapter)
}

<!-- Data -->

<resources>
    <string-array name="auto_complete_array">
        <item>Germany</item>
        <item>Great Britain</item>
        <item>France</item>
        <item>Spain</item>
    </string-array>
</resources>
Text Input
Kotlin
@Composable
fun TextInputExample() {

    var text by remember { mutableStateOf("") }

    TextField(
        value = text,
        onValueChange = {
            text = it
        },
        label = { Text("hint") }
    )
}
Xml
<com.google.android.material.textfield.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <com.google.android.material.textfield.TextInputEditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="hint" />
</com.google.android.material.textfield.TextInputLayout>
Button
Image Button
Kotlin
@Composable
fun ImageButton(image: Any?) {
    Button(
        onClick = {},
        modifier = Modifier.size(100.dp),
        shape = CircleShape,
        colors = ButtonDefaults.buttonColors(
            backgroundColor = Color.White
        ),
        elevation = ButtonDefaults.elevation(0.dp, 0.dp)
    ) {
        GlideImage(
            imageModel = image,
            contentScale = ContentScale.FillWidth,
            contentDescription = "Image of Button",
            modifier = Modifier.fillMaxSize()
        )
    }
}
Xml
<ImageButton
    android:id="@+id/imageButton"
    android:layout_width="80dp"
    android:layout_height="80dp"
    android:background="?selectableItemBackgroundBorderless"
    android:contentDescription="@string/example_image_button"
    android:onClick="onImageButtonClick"/>


// In activity
val imageView = findViewById<android.widget.ImageButton>(R.id.imageButton)

Glide
    .with(this)
    .load(R.drawable.c24logo)
    .fitCenter()
    .into(imageView)

Chip Group
Kotlin
@Composable
fun ChipGroupSingleSelectionExample(list: List = listOf("I'm a list")) {

    var selectedChip by remember { mutableStateOf("") }

    LazyRow(
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.Center,
        modifier = Modifier
            .fillMaxWidth()
            .height(50.dp)
    ) {
        items(list) {
            ActionChip(it)
        }
    }
}
Xml
<HorizontalScrollView
    android:id="@+id/horizontal_scroll_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:scrollbars="none">

    <com.google.android.material.chip.ChipGroup
        android:id="@+id/chip_group"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:singleLine="true"
        app:singleSelection="true">

        <com.google.android.material.chip.Chip
            style="@style/Widget.MaterialComponents.Chip.Choice"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Chip One"
            android:textAlignment="center" />

        [...]

        <com.google.android.material.chip.Chip
            style="@style/Widget.MaterialComponents.Chip.Choice"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Chip Ten"
            android:textAlignment="center" />

    </com.google.android.material.chip.ChipGroup>

</HorizontalScrollView>
Chip
Kotlin
/* At the time of the implementation there were no official implementation!
* Look if there is an official implementaion already*/

@Composable
fun ActionChip(
    name: String = "Action Chip",
    icon: Painter? = null,
    onToggle: ((String) -> Unit)? = null
) {
    var isSelected by remember { mutableStateOf(false) }
    val modifier = if (icon == null) {
        Modifier.padding(horizontal = 12.dp)
    } else Modifier.padding(start = 4.dp, end = 12.dp)

    Surface(
        modifier = Modifier.padding(4.dp),
        shape = CircleShape,
        color = if (isSelected) Purple100 else Gray300,
    ) {
        Row(
            verticalAlignment = Alignment.CenterVertically,
            modifier = Modifier
                .height(32.dp)
                .toggleable(
                    value = isSelected,
                    onValueChange = {
                        isSelected = !isSelected
                        onToggle?.invoke(name)
                    }
                )
        ) {
            if (icon != null) {
                Icon(
                    icon,
                    "Icon",
                    tint = if (isSelected) Green else Red,
                    modifier = Modifier
                        .padding(horizontal = 4.dp)
                        .width(24.dp)
                )
            }

            Text(
                text = name,
                color = if (isSelected) Purple500 else Gray700,
                style = MaterialTheme.typography.body2,
                modifier = modifier
            )
        }
    }
}
Xml
<com.google.android.material.chip.Chip
    android:id="@+id/chip_with_icon"
    style="@style/Widget.MaterialComponents.Chip.Choice"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Chip With Icon"
    app:chipIconEnabled="true"
    app:chipIcon="@drawable/ic_your_icon" />
Check Box
Kotlin
@Composable
fun CheckBox() {
    var checked by remember { mutableStateOf(true) }
    Checkbox(
        checked = checked,
        onCheckedChange = {
            checked = it
        }
    )
}
Xml
<CheckBox
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="onCheckBoxClicked"
    android:checked="true" />
Radio Group
Kotlin
@Composable
fun RadioGroup() {

    val stringList = listOf(
        "First Radio Button",
        "Second Radio Button",
        "Third Radio Button"
    )

    val rememberObserver = remember {
        mutableStateOf("")
    }

    Column(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {

        stringList.forEach { item ->
            Row(
                verticalAlignment = Alignment.CenterVertically,
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(horizontal = 16.dp)
            ) {
                RadioButton(selected = rememberObserver.value == item,
                    onClick = {
                        rememberObserver.value = item
                    }
                )
                Text(
                    text = item,
                    modifier = Modifier.clickable { rememberObserver.value = item }
                )
            }
        }
    }
}
Xml
<RadioGroup
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <RadioButton
        android:id="@+id/first_radio_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="First Radio Button"/>

    <RadioButton
        android:id="@+id/second_radio_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Second Radio Button"/>

    <RadioButton
        android:id="@+id/third_radio_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Third Radio Button"/>

</RadioGroup>
Radio Button
Kotlin
@Composable
fun RadioButtonExample() {
    val observer = remember { mutableStateOf(false) }

    RadioButton(
        selected = observer.value,
        onClick = { observer.value = !observer.value }
    )

    Text(
        text = "I am a Radio Button",
        modifier = Modifier
            .clickable {
                observer.value = !observer.value
            }
    )
}

Xml
<RadioButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="I am a Radio Button"/>
Toggle Button
Kotlin
/* this is a custom build toggle button because*/
/* there is no toggle button in compose right now */

@Composable
fun CustomToggleButton() {

    val buttonClicked: MutableState = remember {
        mutableStateOf(false)
    }

    val buttonText: String
    val buttonTextColor: Color
    val buttonBackgroundColor: Color

    if (buttonClicked.value) {
        buttonText = "On"
        buttonTextColor = Color.Green
        buttonBackgroundColor = Color.LightGray
    } else {
        buttonText = "Off"
        buttonTextColor = Color.Red
        buttonBackgroundColor = Color.Gray
    }

    Button(
        onClick = { buttonClicked.value = !buttonClicked.value },
        colors = ButtonDefaults.buttonColors(backgroundColor = buttonBackgroundColor)
    ) {
        Text(text = buttonText, color = buttonTextColor)
    }
}

Xml
<ToggleButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
Switch
Kotlin
@Composable
fun Switch() {
    val checkedState = remember { mutableStateOf(false) }
    Switch(
        checked = checkedState.value,
        onCheckedChange = { checkedState.value = it }
    )
}
Xml
<Switch
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
Floating Action Button
Kotlin
@Composable
private fun FloatingActionButton() {

    FloatingActionButton()
    onClick = { /*your code*/ }
    ) {
        Icon(
            Icons.Rounded.Add,
            contentDescription = "Floating ActionButton"
        )
    }

/* Or you can use an Extended Floating Action Button */

    FloatingActionButton(
        modifier = Modifier.constrainAs(RectangleFAB) { },
        onClick = { /*your code*/ },
        shape = RectangleShape
    ) {
        Icon(
            Icons.Rounded.Add,
            contentDescription = "Floating ActionButton"
        )
    }
}
Xml
<com.google.android.material.floatingactionbutton.FloatingActionButton
    android:id="@+id/floating_action_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_baseline_date_range"
    android:contentDescription="FloatingActionButton" />

/* Or you can use an Extended Floating Action Button */

<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
    android:id="@+id/extended_floating_action_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Extended FAB" />
List
List with different Views
Kotlin
sealed class ExampleListItems {

    data class TitleItem(
        val title: String
    ) : ExampleListItems()

    data class ContentItem(
        val title: String,
        val body: String
    ) : ExampleListItems()

}

@Composable
fun ExampleItemsListView(listOfExampleItems: List<ExampleListItems>) {
    LazyColumn {
        items(listOfExampleItems) { item ->
            when (item) {
                is ExampleListItems.TitleItem -> TitleItemView(item = item)
                is ExampleListItems.ContentItem -> ContentItemView(item = item)
            }
        }
    }
}

@Composable
fun TitleItemView(item: ExampleListItems.TitleItem) {
    Row(
        modifier = Modifier
            .background(color = Color.LightGray)
            .padding(all = 20.dp)
    ) {
        Text(text = item.title, fontWeight = FontWeight.Bold)
    }
}

@Composable
fun ContentItemView(item: ExampleListItems.ContentItem) {
    Row(
        modifier = Modifier
            .background(color = Color.Cyan)
            .padding(all = 20.dp)
    ) {
        Column {
            Text(text = item.title, fontWeight = FontWeight.SemiBold)
            Spacer(modifier = Modifier.padding(vertical = 8.dp))
            Text(text = item.body, fontWeight = FontWeight.ExtraLight)
        }
    }
}
Xml
<androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/shared_colorBackground"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/>

// Define a layout file for a singular item, one for each viewType

// Define two constants similar to this

    val CONTENT_TYPE = 0
    val TITLE_TYPE = 1

// Write Custom List Adapter

class DifferentViewAdapter :
    ListAdapter<ExampleListItems, RecyclerView.ViewHolder>(DifferentViewDiffCallback) {

    // Handle the Animations of deleted, changed items

    object DifferentViewDiffCallback : DiffUtil.ItemCallback<ExampleListItems>() {

        override fun areItemsTheSame(
            oldItem: ExampleListItems,
            newItem: ExampleListItems
        ): Boolean =
            oldItem.hashCode() == newItem.hashCode()

        override fun areContentsTheSame(
            oldItem: ExampleListItems,
            newItem: ExampleListItems
        ): Boolean =
            oldItem == newItem
    }

    // Create the matching ViewHolder for the current viewType

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return if (viewType == TITLE_TYPE)
            TitleViewHolder(
                TitleItemBinding.inflate(
                    LayoutInflater
                        .from(parent.context), parent, false
                ).root
            )
        else ContentViewHolder(
                ContentItemBinding.inflate(
                    LayoutInflater
                        .from(parent.context), parent, false
                    ).root
                )
            )
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        if (holder is TitleViewHolder) {
            val titleItem = getItem(position) as ExampleListItems.TitleItem
            val binding = TitleItemBinding.bind(holder.itemView)

            binding.title.text = titleItem.title
        } else if (holder is ContentViewHolder) {
            val contentItem = getItem(position) as ExampleListItems.ContentItem
            val binding = ContentItemBinding.bind(holder.itemView)

            with(binding) {
                contentTitle.text = contentItem.title
                contentBody.text = contentItem.body
            }
        }
    }

    // Specify the viewType

    override fun getItemViewType(position: Int): Int {
        return if (getItem(position) is ExampleListItems.ContentItem) CONTENT_TYPE
        else TITLE_TYPE
    }

    class ContentViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)

    class TitleViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
}

// Set Adapter in Activity/Fragment and submit your data

class AndroidUIListWithDifferentViewsActivity : AppCompatActivity() {

    var binding: RecyclerViewListBinding? = null
    var adapter: DifferentViewAdapter? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        supportActionBar?.title = "Different View List"

        binding = RecyclerViewListBinding.inflate(LayoutInflater.from(this), null, false)
        setContentView(binding?.root)
        adapter = DifferentViewAdapter()
        binding?.recyclerViewList?.adapter = adapter

        val exampleList = mutableListOf(
            ExampleListItems.TitleItem("I am a title"),
            ExampleListItems.TitleItem("I am a title"),
            ExampleListItems.ContentItem("I am a title", "I am body"),
            ExampleListItems.TitleItem("I am a title")
        )

        adapter?.submitList(exampleList)
    }
}
Grid
Kotlin
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun GridExample() {

    val colorList = listOf(
        Color.Red,
        Color.Black,
        Color(0xFFBB86FC),
        Color(0xFF3700B3)
    )

    LazyVerticalGrid(
        cells = GridCells.Fixed(2),
        modifier = Modifier.size(200.dp)
    ) {

        (0..3).forEach {

            item {

                Box(
                    modifier = Modifier
                        .size(100.dp)
                        .background(colorList[it])
                )
            }
        }
    }
}
Xml
<GridLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:columnCount="2"
    android:rowCount="2">

    <View
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@color/red" />

    <View
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@color/black" />

    <View
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@color/purple_200" />

    <View
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@color/purple_700" />

</GridLayout>
Custom Fixed Grid
Kotlin
@Composable
fun FixedGridExample() {
    val colorList = listOf(
        Color.Red,
        Color.Black,
        Purple200,
        Purple700
    )

    FixedGrid(2) {

        (0..3).forEach {

            Box(
                modifier = Modifier
                    .size(100.dp)
                    .background(colorList[it % 4])
            )
        }
    }
}

@Composable
fun FixedGrid(
    columnCount: Int,
    content: @Composable () -> Unit
) {

    Layout(content = content) { measurables, constraints ->

        val rowCount: Int =
            ceil(measurables.size.toDouble() / columnCount.toDouble()).toInt()

        val placeables = measurables.map { measurable ->
            measurable.measure(constraints = constraints)
        }

        val placeableWidths = placeables.map { it.width }
        val placeableHeights = placeables.map { it.height }

        // get maximum widths of elements in each column
        val widths = getWidths(columnCount, placeableWidths)
        // get maximum heights of elements in each row
        val heights = getHeights(columnCount, placeableHeights)

        val layoutWidth = widths.sum()
        val layoutHeight = heights.sum()

        val xPositions = List(columnCount) {
            var result = 0
            for (i in 0 until it) {
                result += widths[i]
            }
            result
        }

        val yPositions = List(rowCount) {
            var result = 0
            for (i in 0 until it) {
                result += heights[i]
            }
            result
        }

        layout(
            width = layoutWidth,
            height = layoutHeight
        ) {
            placeables.forEachIndexed { index, placeable ->
                placeable.place(
                    x = xPositions[index % columnCount],
                    y = yPositions[index / columnCount]
                )
            }
        }
    }
}

fun getWidths(
    columnCount: Int,
    widths: List,
): List {

    val result = mutableListOf()

    for (i in 0 until columnCount) {

        // specifies the width of the column by the widest element
        var max = 0
        for (j in i until widths.size step columnCount) {
            if (max < widths[j]) max = widths[j]
        }
        result.add(max)

    }

    return result
}

fun getHeights(
    columnCount: Int,
    heights: List,
): List {

    val result = mutableListOf()

    for (i in heights.indices step columnCount) {

        // specifies the height of the row by the highest element
        var max = 0
        for (j in i until min(i + columnCount, heights.size)) {
            if (max < heights[j]) max = heights[j]
        }
        result.add(max)

    }

    return result
}
Staggered
Kotlin
@Composable
private fun StaggeredGrid() {
    LazyColumn {
        item {
            StaggeredVerticalGrid(
                maxColumnWidth = 155.dp,
                modifier = Modifier.padding(4.dp)
            ) {
                (1..100).forEach {
                    GridItem()
                }
            }
        }
    }
}

@Composable
private fun GridItem() {
    Card(
        modifier = Modifier
            .height((100..250).random().dp)
            .padding(5.dp),
        shape = RoundedCornerShape(15.dp),
        elevation = 5.dp
    ) {
        Box(
            modifier = Modifier
                .fillMaxSize()
                .background(Color(Random.nextInt(256), Random.nextInt(256), Random.nextInt(256)))
        )
    }
}

@Composable
private fun StaggeredVerticalGrid(
    modifier: Modifier = Modifier,
    maxColumnWidth: Dp,
    content: @Composable () -> Unit
) {
    Layout(
        content = content,
        modifier = modifier
    ) { measurables, constraints ->
        check(constraints.hasBoundedWidth) {
            "Unbounded width not supported"
        }
        // get how many columns fit on screen
        val columns = ceil(constraints.maxWidth / maxColumnWidth.toPx()).toInt()

        // get how wide every column can be
        val columnWidth = constraints.maxWidth / columns
        val itemConstraints = constraints.copy(maxWidth = columnWidth)

        // track each column's height
        val colHeights = MutableList(columns) { 0 }
        val placeables = measurables.map { measurable ->
            val column = shortestColumn(colHeights)
            val placeable = measurable.measure(itemConstraints)
            colHeights[column] += placeable.height
            placeable
        }

        val height = colHeights.maxOrNull()
            ?.coerceIn(constraints.minHeight, constraints.maxHeight)
            ?: constraints.minHeight
        layout(
            width = constraints.maxWidth,
            height = height
        ) {
            // save the y coordinate for each column
            val colY = MutableList(columns) { 0 }
            placeables.forEach { placeable ->
                val column = shortestColumn(colY)
                placeable.place(
                    // calculate the x coordinate of each element
                    x = columnWidth * column,
                    y = colY[column]
                )
                colY[column] += placeable.height
            }
        }
    }
}

private fun shortestColumn(colHeights: MutableList): Int {
    var minHeight = Int.MAX_VALUE
    var column = 0
    colHeights.forEachIndexed { index, height ->
        if (height < minHeight) {
            minHeight = height
            column = index
        }
    }
    return column
}
Xml
<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/staggered_recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/shared_colorBackground"
    app:layoutManager="androidx.recyclerview.widget.StaggeredGridLayoutManager"
    app:spanCount="3"/>

// Define Layout for single item

<androidx.cardview.widget.CardView
    android:id="@+id/color_card"
    android:layout_width="120dp"
    android:layout_height="wrap_content"
    app:cardCornerRadius="15dp"
    app:cardElevation="5dp"
    app:cardUseCompatPadding="true"/>

// Write Custom Adapter

class StaggeredAdapter :
    ListAdapter<Int, StaggeredAdapter.ColorViewHolder>(StaggeredDiffUtilCallback) {

    object StaggeredDiffUtilCallback : DiffUtil.ItemCallback<Int>() {

        override fun areItemsTheSame(oldItem: Int, newItem: Int): Boolean =
            oldItem.hashCode() == newItem.hashCode()

        override fun areContentsTheSame(oldItem: Int, newItem: Int): Boolean =
            oldItem == newItem
    }

    class ColorViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ColorViewHolder =
        ColorViewHolder(
            ColorItemBinding.inflate(
                LayoutInflater.from(parent.context),
                parent,
                false
            ).root
        )

    override fun onBindViewHolder(holder: ColorViewHolder, position: Int) {
        val color = getItem(position)
        val binding = ColorItemBinding.bind(holder.itemView)

        with(binding) {
            colorCard.setCardBackgroundColor(color)
            colorCard.updateLayoutParams {
                width = 120.dp
                height = Random.nextInt(100, 250).dp
            }
        }
    }

    // Extension function to get dp from Int

    val Int.dp get() = (this * Resources.getSystem().displayMetrics.density).toInt()
}

// Set adapter in Activity or Fragment

class AndroidUIStaggeredListActivity : AppCompatActivity() {

    private var binding: StaggeredRecyclerViewBinding? = null
    private var adapter : StaggeredAdapter? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = StaggeredRecyclerViewBinding.inflate(layoutInflater)
        setContentView(binding?.root)

        adapter = StaggeredAdapter()
        binding?.staggeredRecyclerView?.adapter = adapter
        adapter?.submitList(createColorList())
        supportActionBar?.title = "Staggered List"
    }

    private fun createColorList(): MutableList<Int> {
        val colorList = mutableListOf<Int>()
        (1..100).forEach {
            colorList.add(Color.argb(255, Random.nextInt(256), Random.nextInt(256), Random.nextInt(256)))
        }
        return colorList 
    } 
}
Layouts
Constraints
Kotlin
@Composable
fun ConstraintLayoutContent() {
    ConstraintLayout {
        // Create references for the composables to constrain
        val (button, text) = createRefs()
        Button(
            onClick = { },
            modifier = Modifier.constrainAs(button) {
                top.linkTo(parent.top, margin = 16.dp)
                start.linkTo(parent.start)
            }
        ) {
            Text("Button")
        }
        Text("Text", Modifier.constrainAs(text) {
            top.linkTo(button.bottom, margin = 16.dp)
            start.linkTo(parent.start)
        })
    }
}
Xml
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_marginTop="16dp"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Text"
        app:layout_constraintTop_toBottomOf="@id/button"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_marginTop="16dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Helper (Guideline Vertical)
Kotlin
@Composable
fun ConstraintLayoutGuidelineVertical() {
    ConstraintLayout {

        val (button) = createRefs()
        val guideline = createGuidelineFromStart(100.dp)

        Button(
            onClick = { },
            modifier = Modifier.constrainAs(button) {
                top.linkTo(parent.top, margin = 16.dp)
                start.linkTo(guideline)
            }
        ) {
            Text("Button")
        }
    }
}
Xml
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_begin="100dp" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintStart_toStartOf="@id/guideline"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="16dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Helper (Guideline Horizontal)
Kotlin
 @Composable
 fun ConstraintLayoutGuidelineHorizontal() {
     ConstraintLayout {

         val (button) = createRefs()
         val guideline = createGuidelineFromTop(100.dp)

         Button(
             onClick = { },
             modifier = Modifier.constrainAs(button) {
                 top.linkTo(guideline)
                 start.linkTo(parent.start)
             }
         ) {
             Text("Button")
         }
     }
 }
Xml
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_begin="100dp" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Button"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@id/guideline" />
</androidx.constraintlayout.widget.ConstraintLayout>
Helper (Barrier)
Kotlin
@Composable
fun ConstraintLayoutBarrier() {
    ConstraintLayout {
        // Create references for the composables to constrain
        val (text1, text2, button) = createRefs()

        Text(
            text = "text1",
            modifier = Modifier
                .constrainAs(text1) {
                    top.linkTo(parent.top)
                    start.linkTo(parent.start)
                }
                .height(200.dp)
                .wrapContentWidth()
        )

        Text(
            text = "text2",
            modifier = Modifier
                .constrainAs(text2) {
                    top.linkTo(parent.top)
                    end.linkTo(parent.end)
                }
                .wrapContentHeight()
                .wrapContentWidth()
        )

        val barrier = createBottomBarrier(text1, text2)

        Button(
            onClick = { },
            modifier = Modifier.constrainAs(button) {
                top.linkTo(barrier)
                start.linkTo(parent.start)
            }
        ) {
            Text("Button")
        }
    }
}
Xml
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/text1"
        android:layout_width="wrap_content"
        android:layout_height="200dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:text="text1"/>

    <TextView
        android:id="@+id/text2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:text="text2"/>

    <androidx.constraintlayout.widget.Barrier
        android:id="@+id/barrier"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:barrierDirection="bottom"
        app:constraint_referenced_ids="text1, text2" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintTop_toBottomOf="@+id/barrier" />
</androidx.constraintlayout.widget.ConstraintLayout>
Helper (Flow)
Kotlin
// Vertical FlowLayout
// the crossAxisAlignment doesn't work properly

FlowColumn(
    modifier = Modifier
        .height(300.dp)
        .wrapContentWidth(),
    mainAxisAlignment = FlowMainAxisAlignment.Center,
    mainAxisSpacing = 16.dp,
    crossAxisSpacing = 50.dp,
    crossAxisAlignment = FlowCrossAxisAlignment.Center,
) {
    // add here your view elements
}

// Horizontal FlowLayout
// the crossAxisAlignment doesn't work properly

FlowRow(
    modifier = Modifier
        .fillMaxWidth()
        .wrapContentHeight()
        .padding(20.dp),
    mainAxisAlignment = FlowMainAxisAlignment.Center,
    crossAxisSpacing = 16.dp,
    mainAxisSpacing = 16.dp
) {
    // add here your code
}
Xml
<!-- Vertical FlowLayout -->

<androidx.constraintlayout.helper.widget.Flow
    android:id="@+id/flow_vertical_example"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginHorizontal="20dp"
    android:orientation="vertical"
    app:constraint_referenced_ids="id's of your elements"
    app:flow_maxElementsWrap="5"
    app:flow_verticalGap="16dp"
    app:flow_wrapMode="aligned" />

<!-- Horizontal FlowLayout -->

<androidx.constraintlayout.helper.widget.Flow
    android:id="@+id/flow_horizontal_example"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginHorizontal="20dp"
    android:orientation="horizontal"  <--
    app:constraint_referenced_ids="id's of your elements"
    app:flow_horizontalGap="16dp"
    app:flow_maxElementsWrap="5"
    app:flow_verticalGap="16dp"
    app:flow_wrapMode="chain"
    app:layout_constraintHorizontal_chainStyle="spread" />
Helper (Layer)
Kotlin
// At the time of the implementation there was no official compose equivalent
// This is an attempt to create a helperlayer

@Composable
private fun HelperLayerExample() {

    var rotationRGB: Float by remember { mutableStateOf(0f) }
    val angleRGB: Float by animateFloatAsState(
        targetValue = rotationRGB,
        animationSpec = tween(durationMillis = 2000, easing = LinearEasing)
    )

    var rotationRG: Float by remember { mutableStateOf(0f) }
    val angleRG: Float by animateFloatAsState(
        targetValue = rotationRG,
        animationSpec = tween(durationMillis = 2000, easing = LinearEasing)
    )

    ConstraintLayout(
        modifier = Modifier.fillMaxSize()
    ) {
        // first layer
        Column(
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Center,
            modifier = Modifier
                .graphicsLayer {
                    rotationZ = angleRGB
                }
        ) {
            // second layer within the first layer
            Column(
                modifier = Modifier.graphicsLayer {
                    rotationZ = angleRG
                }
            ) {
                ColorBox(color = Red200)
                ColorBox(color = Green200)
            }
            ColorBox(color = Blue200)
        }

        Button(
            onClick = { rotationRGB += 360f }
        ) {
            Text(text = "Rotate 360°")
        }

        Button(
            onClick = { rotationRG += 360f }
        ) {
            Text(text = "Rotate Red and Green°")
        }
    }
}
Xml
<!-- XML Code -->
<View
    android:id="@+id/view_red"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:background="@color/red_200" />

    [...]

<Button
    android:id="@+id/rotate_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Rotate 360ª" />

<androidx.constraintlayout.helper.widget.Layer
    android:id="@+id/all_views"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:constraint_referenced_ids="view_red,view_green,view_blue"
    tools:ignore="MissingConstraints"/>

<!-- Code -->

binding?.rotateButton?.setOnClickListener {
    ValueAnimator.ofFloat(0F, 360F)
        .apply {
            addUpdateListener { animator ->
                binding?.allViews?.rotation = animator.animatedValue as Float
            }
            duration = 2000
            start()
        }
}

binding?.rotateRedAndGreenButton?.setOnClickListener {
    ValueAnimator.ofFloat(0F, 360F)
        .apply {
            addUpdateListener { animator ->
                binding?.viewRedAndGreen?.rotation = animator.animatedValue as Float
            }
            duration = 2000
            start()
        }
}
FrameLayout
Kotlin
@Composable
fun FrameLayoutExample() {
    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        Image(
            painter = painterResource(R.drawable.c24logo),
            contentDescription = "Check24 Logo",
            modifier = Modifier.size(250.dp)
        )
    }
}
Xml
<:FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">:

    <:ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:contentDescription="@string/check24logo"
        android:src="@drawable/c24logo" />:

<:/FrameLayout>:
Container
Spinner
Kotlin
@Composable
fun SpinnerExample() {

    val itemList = listOf(
        "Berlin",
        "Hamburg",
        "Stuttgart",
        "München",
        "Düsseldorf",
        "Osnabrück"
    )

    var text by remember { mutableStateOf("Select a city!") }
    var expanded by remember { mutableStateOf(false) }

    Spinner(
        text = text,
        expanded = expanded,
        list = itemList,
        onItemClick = {
            text = it
            expanded = false
        },
        onClick = {
            expanded = !expanded
        }
    )
}

@Composable
fun Spinner(
    text: String = "Select something!",
    expanded: Boolean = false,
    list: List,
    onItemClick: ((String) -> Unit)? = null,
    onClick: () -> Unit
) {
    Row(
        verticalAlignment = Alignment.CenterVertically,
        modifier = Modifier.clickable(onClick = onClick)
    ) {
        Text(text = text, )
        Icon(
            imageVector = Icons.Filled.ArrowDropDown,
            contentDescription = "ArrowDropDown",
        )
        DropdownMenu(
            expanded = expanded,
            onDismissRequest = onClick
        ) {
            list.forEach { item ->

                DropdownMenuItem(
                    onClick = {
                        onItemClick?.invoke(item)
                    }
                ) {
                    Text(text = item)
                }
            }
        }
    }
}
Xml
<Spinner
    android:id="@+id/spinner"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

<!-- Spinner Data -->

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="spinner_array">
        <item>Berlin</item>
        <item>Hamburg</item>
        <item>Stuttgart</item>
        <item>München</item>
        <item>Düsseldorf</item>
        <item>Osnabrück</item>
    </string-array>
</resources>

<!-- implementation in the activity-->

val spinner = binding.spinner
ArrayAdapter.createFromResource(
    this,
    R.array.spinner_array,
    R.layout.support_simple_spinner_dropdown_item
).also { adapter ->
    adapter.setDropDownViewResource(R.layout.support_simple_spinner_dropdown_item)
    spinner.adapter = adapter
}
Horizontal Scrolling
Kotlin
@Composable
fun HorizontalScrollBox() {
    val scrollState = rememberScrollState()

    LazyRow(
        Modifier
            .fillMaxSize()
            .horizontalScroll(scrollState)
    ) {
        [...]
    }
}
Xml
<HorizontalScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    [...]
</HorizontalScrollView>
Vertical Scrolling
Kotlin
@Composable
fun VerticalScrollBox() {
    val scrollState = rememberScrollState()

    LazyColumn(
        Modifier
            .fillMaxSize()
            .verticalScroll(scrollState)
    ) {
        [...]
    }
}
Xml
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    [...]
</ScrollView>
ViewPager
Kotlin
@OptIn(ExperimentalPagerApi::class)
@Composable
fun ViewPagerExample() {
    HorizontalPager(count = 5) { page ->
        Card(
            modifier = Modifier
                .fillMaxSize()
                .padding(20.dp),
            elevation = 10.dp,
            backgroundColor = Color.LightGray
        ) {
            Box(
                contentAlignment = Alignment.Center
            ) {
                Text(text = "This is page ${page + 1}")
            }
        }
    }
}
Xml
    <-- View Pager -->

<androidx.viewpager2.widget.ViewPager2
    android:id="@+id/view_pager_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

    <-- Fragment(s) in View Pager -->

<androidx.cardview.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="25dp"
    android:elevation="10dp"
    app:cardBackgroundColor="#FFCCCCCC">

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/view_pager_fragment_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/example_text"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:textColor="@color/black" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.cardview.widget.CardView>

    <-- View Pager Adapter -->

class ViewPagerAdapter(fragmentActivity: FragmentActivity) : FragmentStateAdapter(fragmentActivity) {
    override fun getItemCount(): Int = 5

    override fun createFragment(position: Int): Fragment = ViewPagerFragment(position)
}

    <-- View Pager Fragment Implementation -->

class ViewPagerFragment(val position: Int) : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = ViewPagerFragmentBinding.inflate(inflater, container, false)
        binding.viewPagerFragmentText.text = "This is page ${position + 1}"
        return binding.root
    }
}
Card
Kotlin
@Composable
fun CardExample() {

    Card(
        elevation = 10.dp,
        shape = CircleShape
    ) {
        Text(
            text = "Card with elevation and circleShape",
            modifier = Modifier.padding(15.dp)
        )
    }

    Card(
        shape = RoundedCornerShape(5.dp)
    ) {
        Text(
            text = "Card with rounded corners and no elevation",
            modifier = Modifier.padding(15.dp)
        )
    }

    Card(
        elevation = 10.dp,
        backgroundColor = Color.LightGray
    ) {
        Text(
            text = "Card with color and elevation",
            modifier = Modifier.padding(15.dp)
        )
    }

    Card(
        elevation = 10.dp,
        border = BorderStroke(1.dp, Color.Green)
    ) {
        Text(
            text = "Card with a border",
            modifier = Modifier.padding(15.dp)
        )
    }

    Card(
        shape = RoundedCornerShape(
            topEnd = 15.dp,
            topStart = 0.dp,
            bottomEnd = 0.dp,
            bottomStart = 15.dp
        )
    ) {
        Text(
            text = "Card with two rounded corners",
            modifier = Modifier.padding(15.dp)
        )
    }

    val shapes = Shapes(
        large = CutCornerShape(
            topStart = 16.dp,
            topEnd = 0.dp,
            bottomEnd = 16.dp,
            bottomStart = 0.dp
        )
    )
    MaterialTheme(shapes = shapes){
        Card(
            elevation = 10.dp,
            shape = MaterialTheme.shapes.large
        ) {
            Text(
                text = "Card with cut corners",
                modifier = Modifier.padding(15.dp)
            )
        }
    }
}
Xml
<androidx.cardview.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="20dp"
    app:cardCornerRadius="50dp"
    app:cardElevation="10dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Card with elevation and rounded corners" />
</androidx.cardview.widget.CardView>

<androidx.cardview.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="20dp"
    app:cardCornerRadius="10dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Card with no elevation and rounded corners" />
</androidx.cardview.widget.CardView>

<androidx.cardview.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="20dp"
    app:cardBackgroundColor="@color/gray"
    app:cardCornerRadius="10dp"
    app:cardElevation="10dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Card with color and elevation" />
</androidx.cardview.widget.CardView>

<com.google.android.material.card.MaterialCardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="20dp"
    app:strokeColor="@color/green"
    app:strokeWidth="2dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Card with a border" />
</com.google.android.material.card.MaterialCardView>

<com.google.android.material.card.MaterialCardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="20dp"
    app:shapeAppearance="@style/ShapeAppearance.MyApp.MediumComponent.Rounded">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Card with two rounded corners" />
</com.google.android.material.card.MaterialCardView>

<com.google.android.material.card.MaterialCardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="20dp"
    app:shapeAppearance="@style/ShapeAppearance.MyApp.MediumComponent.Cut">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Card with two cut corners" />
</com.google.android.material.card.MaterialCardView>

<!-- the styles-->

<style name="ShapeAppearance.MyApp.MediumComponent.Cut" parent="ShapeAppearance.MaterialComponents.MediumComponent">
    <item name="cornerFamilyTopLeft">cut</item>
    <item name="cornerFamilyBottomRight">cut</item>
    <item name="cornerSizeTopLeft">20dp</item>
    <item name="cornerSizeBottomRight">20dp</item>
</style>

<style name="ShapeAppearance.MyApp.MediumComponent.Rounded" parent="ShapeAppearance.MaterialComponents.MediumComponent">
    <item name="cornerFamilyTopRight">rounded</item>
    <item name="cornerFamilyBottomLeft">rounded</item>
    <item name="cornerSizeTopLeft">15dp</item>
    <item name="cornerSizeBottomRight">15dp</item>
</style>
AppBarLayout
Kotlin
@Composable
fun AppBarExample() {
    Scaffold(
        topBar = {

            TopAppBar(
                title = {
                    Text(
                        text = "App Bar Layout",
                        color = Color.White
                    )
                },
                navigationIcon = {
                    IconButton(onClick = { /* your code */ }) {

                        Icon(
                            imageVector = Icons.Rounded.Menu,
                            contentDescription = "Menu"
                        )
                    }
                }

            )
        },
        content = { [...] }
    )
}
Xml
<com.google.android.material.appbar.AppBarLayout
    android:id="@+id/appbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:title="@string/app_bar_layout"
        app:navigationIcon="@drawable/ic_baseline_menu_24"
        app:titleTextColor="@color/white" />

</com.google.android.material.appbar.AppBarLayout>
BottomAppBar
Kotlin
@Composable
fun BottomAppBarExample() {

    val screens = listOf(
        BottomBarScreen.Favorite,
        BottomBarScreen.Download
    )

    var currentScreen by remember { mutableStateOf(BottomBarScreen.Favorite) }

    Scaffold(
        topBar = {
            TopAppBar(
                title = {
                    Text(text = "BottomAppBar")
                }
            )
        },
        bottomBar = {
            BottomAppBarDetails(screens, currentScreen) {
                    screen ->
                currentScreen = screen
            }
        },
        floatingActionButtonPosition = FabPosition.Center,
        isFloatingActionButtonDocked = true,
        floatingActionButton = {
            FloatingActionButtonDetails()
        },
    ) {
        when (currentScreen) {
            BottomBarScreen.Favorite -> FavoriteScreen()
            BottomBarScreen.Download -> DownloadScreen()
        }
    }
}

@Composable
private fun BottomAppBarDetails(
    screens: List,
    currentScreen: BottomBarScreen,
    onClick : (BottomBarScreen) -> Unit
) {
    BottomAppBar(cutoutShape = CircleShape) {
        screens.forEach { screen ->
            BottomNavigationItem(
                label = { Text(text = screen.title) },
                icon = {
                    Icon(
                        imageVector = screen.icon,
                        contentDescription = "Navigation Icon"
                    )
                },
                selected = screen == currentScreen,
                onClick = {
                    onClick(screen)
                },
                alwaysShowLabel = false
            )
        }
    }
}

@Composable
private fun FloatingActionButtonDetails() {
    FloatingActionButton(
        shape = CircleShape,
        onClick = { /* your code */ }
    ) {
        Icon(
            Icons.Filled.Add,
            "Floating Action Button"
        )
    }
}
Xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".features.bar.AndroidUIBottomAppBarActivity">

    <FrameLayout
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </FrameLayout>

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/floating_action_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:contentDescription="BottomAppBarWithFloatingActionButton"
        android:src="@drawable/ic_baseline_add_24"
        app:fabSize="auto"
        app:layout_anchor="@id/bottom_app_bar" />

    <com.google.android.material.bottomappbar.BottomAppBar
        android:id="@+id/bottom_app_bar"
        style="@style/DemoMaterial"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:backgroundTint="@color/purple_500"
        app:fabAlignmentMode="center">

        <com.google.android.material.bottomnavigation.BottomNavigationView
            android:id="@+id/bottom_navigation_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginEnd="16dp"
            android:background="@drawable/transparent_background"
            app:itemIconTint="@color/white"
            app:itemTextColor="@color/white"
            app:labelVisibilityMode="selected"
            app:menu="@menu/bottom_app_bar_menu" />

    </com.google.android.material.bottomappbar.BottomAppBar>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

    <!-- and the menu items -->

    <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/favorite"
        android:icon="@drawable/ic_baseline_favorite_24"
        android:title="Favorite" />

    <item
        android:enabled="false" />

    <item
        android:id="@+id/download"
        android:icon="@drawable/ic_baseline_cloud_download_24"
        android:title="Download" />

</menu>
Toolbar
Kotlin
@Composable
fun ToolbarExample() {
    Scaffold(
        topBar = {
            TopAppBarDetails()
        }
    ) { }
}

@Composable
private fun TopAppBarDetails() {

    val context = LocalContext.current
    var expanded by remember { mutableStateOf(false) }
    var clickedItemText by remember { mutableStateOf("") }

    TopAppBar(
        title = { Text(text = "Toolbar") },
        navigationIcon = {
            IconButton(onClick = { context.findActivity()?.onBackPressed() }) {
                Icon(Icons.Default.ArrowBack, "Back Button")
            }
        },
        actions = {
            IconButton(onClick = { }) {
                Icon(Icons.Default.Search, "Search")
            }
            IconButton(onClick = { expanded = !expanded }) {
                Icon(Icons.Default.MoreVert, "Options")
            }
            OptionDropdownMenu(expanded, onDismissMenu = { onDismissMenu: Boolean ->
                expanded = onDismissMenu
            }) {

            }
        }
    )
}

@Composable
private fun OptionDropdownMenu(
    expanded: Boolean,
    list: List = listOf("First Option", "Second Option", "Third Option"),
    onDismissMenu: ((Boolean) -> Unit)? = null,
    onClickItem: ((String) -> Unit)? = null
) {

    DropdownMenu(
        expanded = expanded,
        onDismissRequest = { onDismissMenu?.invoke(false) },
    ) {
        list.forEach { item ->

            DropdownMenuItem(
                onClick = {
                    onClickItem?.invoke(item)
                    onDismissMenu?.invoke(false)
                }
            ) {
                Text(text = item)
            }
        }
    }
}
Xml
<com.google.android.material.appbar.AppBarLayout
    android:id="@+id/top_app_bar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent">

    <com.google.android.material.appbar.MaterialToolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:theme="@style/ToolbarThemeExample"
        app:menu="@menu/tool_bar_menu"
        app:navigationIcon="@drawable/ic_baseline_arrow_back_24"
        app:title="Toolbar"
        app:titleTextColor="@color/white">

    </com.google.android.material.appbar.MaterialToolbar>

</com.google.android.material.appbar.AppBarLayout>

<!-- menu data -->

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    
    <item android:id="@+id/toolbar_search" android:icon="@drawable/ic_baseline_search_24"
        android:iconTint="@color/white" android:title="Search" app:showAsAction="ifRoom" />
    
    <item 
        android:id="@+id/first_option"
        android:title="First Option" />
    
    <item android:id="@+id/second_options"
        android:title="Second Option" />
    
    <item android:id="@+id/third_options"
        android:title="Third Option" />

</menu>

<!-- code -->

binding?.toolbar?.setNavigationOnClickListener {
    onBackPressed()
}
TabLayout
Kotlin
@Composable
fun TabLayoutExample() {
    var selectedTabIndex by remember { mutableStateOf(0) }

    val tabTexts = listOf("A", "B", "C")

    TabRow(
        selectedTabIndex = selectedTabIndex,
        backgroundColor = Color.White
    ) {
        tabTexts.forEachIndexed { index, text ->
            Tab(
                selected = index == selectedTabIndex,
                modifier = Modifier.size(50.dp),
                onClick = {
                    selectedTabIndex = index
                }
            ) {
                Text(text = text)
            }
        }
    }
}
Xml
<com.google.android.material.tabs.TabLayout
    android:id="@+id/tab_layout"
    android:layout_width="0dp"
    android:layout_height="wrap_content" />

// in activity

var binding: TabLayoutBinding? = TabLayoutBinding.inflate(layoutInflater)

binding?.tabLayout?.apply {
    addTab(newTab().setText("A"))
    addTab(newTab().setText("B"))
    addTab(newTab().setText("C"))
}
TabItem
Kotlin
@Composable
fun IconTabs(tabData: List) {
    var tabIndex by remember { mutableStateOf(0) }

    TabRow(
        selectedTabIndex = tabIndex,
        backgroundColor = Color.White
    ) {
        tabData.forEachIndexed { index, icon ->
            Tab(selected = tabIndex == index, onClick = {
                tabIndex = index
            }, icon = {
                Icon(imageVector = icon, contentDescription = null)
            })
        }
    }
}

@Composable
fun TextTabs(tabData: List) {
    var tabIndex by remember { mutableStateOf(0) }

    TabRow(
        selectedTabIndex = tabIndex,
        backgroundColor = Color.White
    ) {
        tabData.forEachIndexed { index, text ->
            Tab(selected = tabIndex == index, onClick = {
                tabIndex = index
            }, text = {
                Text(text = text)
            })
        }
    }
}

@Composable
fun IconAndTextTabs(tabData: List>) {
    var tabIndex by remember { mutableStateOf(0) }

    TabRow(
        selectedTabIndex = tabIndex,
        backgroundColor = Color.White,
    ) {
        tabData.forEachIndexed { index, pair ->
            Tab(selected = tabIndex == index, onClick = {
                tabIndex = index
            }, text = {
                Text(text = pair.first)
            }, icon = {
                Icon(imageVector = pair.second, contentDescription = null)
            })
        }
    }
}
Xml
    <!-- XML Code -->
    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tab_item_icons"
        android:layout_width="0dp"
        android:layout_height="wrap_content" />

    <!-- Code -->

    binding.tabItemText.apply {
        addTab(newTab().setText("MUSIC"))
        addTab(newTab().setText("MARKET"))
        addTab(newTab().setText("FILMS"))
        addTab(newTab().setText("BOOKS"))
    }

    binding.tabItemIcons.apply {
        addTab(newTab().setIcon(R.drawable.ic_baseline_save_24))
        addTab(newTab().setIcon(R.drawable.ic_baseline_date_range))
        addTab(newTab().setIcon(R.drawable.ic_baseline_favorite_24))
        addTab(newTab().setIcon(R.drawable.ic_baseline_cloud_download_24))
    }

    binding.tabItemTextAndIcons.apply {
        addTab(newTab().setText("MUSIC").setIcon(R.drawable.ic_baseline_save_24))
        addTab(newTab().setText("MARKET").setIcon(R.drawable.ic_baseline_date_range))
        addTab(newTab().setText("FILMS").setIcon(R.drawable.ic_baseline_favorite_24))
        addTab(newTab().setText("BOOKS").setIcon(R.drawable.ic_baseline_cloud_download_24))
    }
NavHost
Kotlin
@Composable
fun NavHostDemo() {

    val navController = rememberNavController()

    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {

        val abc = listOf("A", "B", "C")

        NavHost(navController = navController, startDestination = "A") {

            abc.forEach { letter ->

                composable(letter) {
                    Text(text = letter)
                }
            }
        }

        Row {

            abc.forEach { letter ->
                Button(onClick = { navController.navigate(letter) }) {
                    Text(text = letter)
                }
            }
        }
    }
}
Xml
<androidx.fragment.app.FragmentContainerView
    android:id="@+id/nav_host_fragment"
    android:name="androidx.navigation.fragment.NavHostFragment"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:defaultNavHost="true"
    app:layout_constraintBottom_toTopOf="@id/navigation_button_row"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:navGraph="@navigation/nav_host_navigation" />

<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/navigation_button_row"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent">

    <Button
        android:id="@+id/button_a"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/a"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@id/button_b"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button_b"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/b"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@id/button_c"
        app:layout_constraintStart_toEndOf="@+id/button_a"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button_c"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/c"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/button_b"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

// navigation Graph

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nav_host_navigation"
    app:startDestination="@id/fragment_a">

    <fragment
        android:id="@+id/fragment_a"
        android:name="de.check24.compose.demo.features.navigation.fragments.FragmentA"
        tools:layout="@layout/navigation_plain_text" />

    <fragment
        android:id="@+id/fragment_b"
        android:name="de.check24.compose.demo.features.navigation.fragments.FragmentB"
        tools:layout="@layout/navigation_plain_text" />

    <fragment
        android:id="@+id/fragment_c"
        android:name="de.check24.compose.demo.features.navigation.fragments.FragmentC"
        tools:layout="@layout/navigation_plain_text" />

</navigation>

// in activity

val navHostFragment =
    supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment

val navController = navHostFragment.navController

val buttonA = findViewById<Button>(R.id.button_a)
val buttonB = findViewById<Button>(R.id.button_b)
val buttonC = findViewById<Button>(R.id.button_c)

buttonA.setOnClickListener {
    navController.navigate(R.id.fragment_a)
}

buttonB.setOnClickListener {
    navController.navigate(R.id.fragment_b)
}

buttonC.setOnClickListener {
    navController.navigate(R.id.fragment_c)
}
Custom
Map
Kotlin
@Composable
private fun GoogleMapExample() {
    val c24Berlin = LatLng(52.51119997328961, 13.404559796099809)
    val zoom = 17F

    val cameraPositionState = rememberCameraPositionState {
        position = CameraPosition(c24Berlin, zoom, 0F, 0F)
    }

    GoogleMap(
        modifier = Modifier.fillMaxSize(),
        cameraPositionState = cameraPositionState
    )
}
Xml
<fragment xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".features.custom.AndroidUIGoogleMapActivity" />

// In activity
val mapFragment: SupportMapFragment? = supportFragmentManager
    .findFragmentById(R.id.map) as SupportMapFragment?

 mapFragment?.getMapAsync {
    val c24Berlin = LatLng(52.51119997328961, 13.404559796099809)
    val zoom = 17F

    it.moveCamera(CameraUpdateFactory.newLatLngZoom(c24Berlin, zoom))
}
Modifier
Margin
Kotlin
@Composable
fun MarginDemo() {

    Card(backgroundColor = Color.Blue) {

        Text(
            text = "padding (red) and margin (blue)",
            modifier = Modifier
                .padding(
                    horizontal = 50.dp,
                    vertical = 20.dp
                ) // Margin
                .background(Color.Red)
                .padding(20.dp) // Padding
        )
    }
}
Xml
<androidx.cardview.widget.CardView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:cardBackgroundColor="@color/blue"
    app:cardCornerRadius="5dp">

    <TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginHorizontal="50dp"
    android:layout_marginVertical="20dp"
    android:background="@color/red"
    android:padding="20dp"
    android:text="@string/modifier1text"
    android:textAlignment="center"
    app:layout_constraintTop_toTopOf="parent" />

    </androidx.cardview.widget.CardView>
Size
Kotlin
@Composable
fun SizeDemo() {

    Row(
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.Center,
        modifier = Modifier.fillMaxWidth()
    ) {

        Card(
            backgroundColor = Color.LightGray,
            modifier = Modifier.size(70.dp),

            ) {

            Text(
                text = "size: big"
            )
        }

        Spacer(modifier = Modifier.size(20.dp))

        Card(
            backgroundColor = Color.LightGray,
            modifier = Modifier.size(50.dp)
        ) {

            Text(
                text = "size: small"
            )
        }
    }
}
Xml
<androidx.cardview.widget.CardView
    android:layout_width="70dp"
    android:layout_height="70dp"
    app:cardBackgroundColor="@color/light_gray"
    app:cardCornerRadius="5dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/modifier2text1" />

</androidx.cardview.widget.CardView>

<androidx.cardview.widget.CardView
    android:layout_width="50dp"
    android:layout_height="50dp"
    app:cardBackgroundColor="@color/light_gray"
    app:cardCornerRadius="5dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/modifier2text2" />

</androidx.cardview.widget.CardView>
Clickable
Kotlin
@Composable
fun ClickableDemo() {

    var count by remember { mutableStateOf(0) }

    Text(
        text = "Clicked ${count}x",
        modifier = Modifier
            .clickable {
                count++
            }
    )
}
Xml
<TextView
    android:id="@+id/modifier_clickable"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:clickable="true"
    android:focusable="true"
    android:onClick="onTextClick"
    android:text="@string/sample_text_clickable" />

// in activity

fun onTextClick(view: View) {
    if (view.id != R.id.modifier_clickable) return

    count++
    (view as TextView).text = "Clicked ${count}x"
}
Shadow
Kotlin
@Composable
fun ShadowDemo() {

    Card(
        modifier = Modifier
            .shadow(elevation = 20.dp)
    ) {
        Text(
            text = "shadow",
            modifier = Modifier.padding(10.dp)
        )
    }
}
Xml
<androidx.cardview.widget.CardView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:cardElevation="20dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="@string/shadow" />

</androidx.cardview.widget.CardView>
Background
Kotlin
@Composable
fun BackgroundDemo() {
    Text(
        text = "red background",
        modifier = Modifier.background(Color.Red)
    )
}
Xml
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@color/red"
    android:text="@string/modifier_background" />
Positioning
ConstraintLayout
Kotlin
ConstraintLayout(
modifier = Modifier.fillMaxSize()
) {
    val (purple, orange, blue, green, leftView, middleView, rightView) = createRefs()
    val chainRefOne = createHorizontalChain(green, blue, chainStyle = ChainStyle.Spread)
    val chainRefTwo =
        createHorizontalChain(leftView, middleView, rightView, chainStyle = ChainStyle.Spread)

    Text(
        textAlign = TextAlign.Center,
        text = "constraint to start, top and end of parent with a horizontal bias of 30/70",
        modifier = Modifier
            .padding(top = 80.dp)
            .width(150.dp)
            .background(Purple200)
            .padding(10.dp)
            .constrainAs(purple) {
                linkTo(
                    parent.start,
                    parent.end,
                    bias = 0.3F
                )
            }
    )

    Text(
        textAlign = TextAlign.Center,
        text = "constraint via circle radius(170dp) and angle(135) to purple",
        modifier = Modifier
            .width(180.dp)
            .background(Orange200)
            .padding(10.dp)
            .constrainAs(orange) {
                circular(purple, angle = 135F, distance = 170.dp)
            }
    )

    Text(
        textAlign = TextAlign.Center,
        text = "Chain A, both are bi-directional connected",
        modifier = Modifier
            .width(120.dp)
            .background(Green200)
            .padding(10.dp)
            .constrainAs(green) {
                top.linkTo(parent.top)
                bottom.linkTo(parent.bottom)
            }
    )

    Text(
        text = "Chain B, and chained with chainStyle \"Spread\"",
        modifier = Modifier
            .width(120.dp)
            .background(Blue200)
            .padding(10.dp)
            .constrainAs(blue) {
                top.linkTo(parent.top)
                bottom.linkTo(parent.bottom)
            },
        textAlign = TextAlign.Center
    )

    Text(
        text = "chained with 30 percent",
        modifier = Modifier
            .background(Red200)
            .height(60.dp)
            .padding(10.dp)
            .constrainAs(leftView) {
                bottom.linkTo(parent.bottom)
                width = Dimension.percent(0.3F)
            },
        textAlign = TextAlign.Center
    )

    Text(
        text = "chained with 40 percent",
        modifier = Modifier
            .background(Color.Gray)
            .height(60.dp)
            .padding(10.dp)
            .constrainAs(middleView) {
                bottom.linkTo(parent.bottom)
                width = Dimension.percent(0.4F)
            },
        textAlign = TextAlign.Center
    )

    Text(
        textAlign = TextAlign.Center,
        text = "chained with 30 percent",
        modifier = Modifier
            .background(Color.Cyan)
            .height(60.dp)
            .padding(10.dp)
            .constrainAs(rightView) {
                bottom.linkTo(parent.bottom)
                width = Dimension.percent(0.3F)
            }
    )
}
Xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/purple"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:background="@color/purple_200"
        android:gravity="center"
        android:padding="10dp"
        android:text="constraint to start, top and end of parent with a horizontal bias of 30/70"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.3"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.1"/>

    <TextView
        android:id="@+id/orange"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:background="@color/orange_200"
        android:gravity="center"
        android:padding="10dp"
        android:text="constraint via circle radius(110dp) and angle(135) to purple"
        app:layout_constraintCircle="@id/purple"
        app:layout_constraintCircleAngle="135"
        app:layout_constraintCircleRadius="110dp" />

    <TextView
        android:id="@+id/blue"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:background="@color/blue_200"
        android:gravity="center"
        android:padding="10dp"
        android:text="Chain B, and chained with chainStyle "spread" together "
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_chainStyle="spread"
        app:layout_constraintStart_toEndOf="@+id/green"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/green"
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:background="@color/green_200"
        android:gravity="center"
        android:padding="10dp"
        android:text="Chain A, both are bi-directional connected"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/blue"
        app:layout_constraintHorizontal_chainStyle="spread"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/left_textview"
        android:layout_width="0dp"
        android:layout_height="60dp"
        android:background="@color/red_200"
        android:gravity="center"
        android:padding="10dp"
        android:text="chained with 30 percent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/middle_textview"
        app:layout_constraintHorizontal_chainStyle="spread"
        app:layout_constraintHorizontal_weight="0.3"
        app:layout_constraintStart_toStartOf="parent" />

    <TextView
        android:id="@+id/middle_textview"
        android:layout_width="0dp"
        android:layout_height="60dp"
        android:background="@color/gray"
        android:gravity="center"
        android:padding="10dp"
        android:text="chained with 40 percent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/right_textview"
        app:layout_constraintHorizontal_weight="0.4"
        app:layout_constraintStart_toEndOf="@+id/left_textview" />

    <TextView
        android:id="@+id/right_textview"
        android:layout_width="0dp"
        android:layout_height="60dp"
        android:background="@color/teal_200"
        android:gravity="center"
        android:padding="10dp"
        android:text="chained with 30 percent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_weight="0.3"
        app:layout_constraintStart_toEndOf="@+id/middle_textview" />
</androidx.constraintlayout.widget.ConstraintLayout>
Flow
Kotlin
// Vertical FlowLayout

FlowColumn(
    modifier = Modifier
        .height(300.dp)
        .wrapContentWidth(),
    mainAxisAlignment = FlowMainAxisAlignment.Center,
    mainAxisSpacing = 16.dp,
    crossAxisSpacing = 50.dp,
    crossAxisAlignment = FlowCrossAxisAlignment.Center,
    ) {
    // add here your view elements
}

// Horizontal FlowLayout

FlowRow(
    modifier = Modifier
        .fillMaxWidth()
        .wrapContentHeight()
        .padding(20.dp),
    mainAxisAlignment = FlowMainAxisAlignment.Center,
    crossAxisSpacing = 16.dp,
    mainAxisSpacing = 16.dp
    ) {
    // add here your code
}
Xml
<!-- Vertical FlowLayout -->

<androidx.constraintlayout.helper.widget.Flow
    android:id="@+id/flow_vertical_example"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginHorizontal="20dp"
    android:orientation="vertical"
    app:constraint_referenced_ids="id's of your elements"
    app:flow_maxElementsWrap="5"
    app:flow_verticalGap="16dp"
    app:flow_wrapMode="aligned" />

<!-- Horizontal FlowLayout -->

<androidx.constraintlayout.helper.widget.Flow
    android:id="@+id/flow_horizontal_example"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginHorizontal="20dp"
    android:orientation="horizontal"
    app:constraint_referenced_ids="id's of your elements"
    app:flow_horizontalGap="16dp"
    app:flow_maxElementsWrap="5"
    app:flow_verticalGap="16dp"
    app:flow_wrapMode="chain"
    app:layout_constraintHorizontal_chainStyle="spread" />
LinearLayout (Vertical)
Kotlin
Column(
    modifier = Modifier
    .fillMaxSize()
    .padding(50.dp)
) {
    Text(
        text = "TextView One",
        textAlign = TextAlign.Center,
        modifier = Modifier
            .wrapContentHeight()
            .fillMaxWidth()
            .padding(vertical = 20.dp)
            .background(Orange200)
            .padding(10.dp)
    )

    [...]

}
Xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingHorizontal="50dp"
    android:paddingVertical="50dp">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginVertical="20dp"
        android:background="@color/orange_200"
        android:padding="10dp"
        android:text="TextView One"
        android:textAlignment="center" />

        [...]

</LinearLayout>
LinearLayout (Horizontal)
Kotlin
Row(
    modifier = Modifier
        .fillMaxSize()
        .padding(vertical = 50.dp, horizontal = 20.dp)
) {
    Box(
        modifier = Modifier
            .padding(horizontal = 20.dp)
            .width(50.dp)
            .fillMaxHeight()
            .background(Orange200)
            .padding(10.dp)
    )

    [...]

}
Xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:paddingHorizontal="20dp"
    android:paddingVertical="50dp">

    <View
        android:layout_width="50dp"
        android:layout_height="match_parent"
        android:layout_marginHorizontal="20dp"
        android:background="@color/orange_200"
        android:padding="10dp"
        android:textAlignment="center" />

    [...]

</LinearLayout>
GridLayout
Kotlin
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun GridExample() {

    val colorList = listOf(
        Color.Red,
        Color.Black,
        Color(0xFFBB86FC),
        Color(0xFF3700B3)
    )

    LazyVerticalGrid(
        cells = GridCells.Fixed(2),
        modifier = Modifier.size(200.dp)
    ) {

        (0..3).forEach {

            item {

                Box(
                    modifier = Modifier
                        .size(100.dp)
                        .background(colorList[it])
                )
            }
        }
    }
}
Xml
<GridLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:columnCount="2"
    android:rowCount="2">

    <View
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@color/red" />

    <View
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@color/black" />

    <View
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@color/purple_200" />

    <View
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@color/purple_700" />

</GridLayout>
FrameLayout
Kotlin
@Composable
fun FrameLayoutExample() {
    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        Image(
            painter = painterResource(R.drawable.c24logo),
            contentDescription = "Check24 Logo",
            modifier = Modifier.size(250.dp)
        )
    }
}
Xml
<:FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">:

    <:ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:contentDescription="@string/check24logo"
        android:src="@drawable/c24logo" />:

<:/FrameLayout>:
States
Observable types
Kotlin
class MyViewModel : ViewModel() {
    var isClicked = MutableStateFlow(false)
    var text = MutableLiveData()

    fun onToggle() {
        isClicked.value = !isClicked.value
    }

    fun onValueChanged(input: String) {
        text.value = input
    }
}

@Composable
private fun ObservableTypeExample(model: MyViewModel) {
    val text: String by model.text.observeAsState("")
    val isClicked: Boolean by model.isClicked.collectAsState()

    MyScreen(
        text = text,
        isClicked = isClicked,
        onValueChanged = { model.onValueChanged(it) },
        onToggle = { model.onToggle() }
    )
}

@Composable
fun MyScreen(
    text: String,
    isClicked: Boolean,
    onValueChanged: (String) -> Unit,
    onToggle: () -> Unit
) {

    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        TextField(
            value = text,
            onValueChange = { onValueChanged(it) },
        )

        Switch(
            checked = isClicked,
            onCheckedChange = { onToggle() }
        )

        Box(
            modifier = Modifier
                .size(100.dp)
                .background(
                    if (isClicked) Green200 else Blue200
                )
        )
    }
}
Xml
    <!-- XML Code -->

    <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/text_layout"
        android:layout_width="250dp"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp">

        <com.google.android.material.textfield.TextInputEditText
            android:id="@+id/input_edit_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </com.google.android.material.textfield.TextInputLayout>

    <Switch
        android:id="@+id/observable_switch"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <View
        android:id="@+id/view_box"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@color/blue_200" />

    <!-- Code -->

private var binding: ObservableTypesBinding? = null
private var viewModel = ObservableViewModel()

viewModel.isClicked.observe(this) {
    setBackgroundColor(binding?.viewBox, viewModel.isClicked)
}

binding?.observableSwitch?.setOnClickListener {
    viewModel.onClick()
}

private fun setBackgroundColor(viewBox: View?, clicked: MutableLiveData<Boolean>) {
    if (clicked.value == true) {
        viewBox?.setBackgroundResource(R.color.green_200)
    } else {
        viewBox?.setBackgroundResource(R.color.blue_200)
    }
}   

class ObservableViewModel: ViewModel() {

    val isClicked: MutableLiveData<Boolean> = MutableLiveData(false)

    fun onClick() {
        isClicked.value = !(isClicked.value ?: false)
    }
}
Stateful
Kotlin
// stateful composables tend to be less reusable and harder to test

@Composable
private fun StatefulExample() {
    // stateful means that the composable manages its own state
    // no states are handled in the parent object.
    MySwitch()
}

@Composable
private fun MySwitch() {
    // the state
    var isClicked by remember { mutableStateOf(false) }

    Switch(
        checked = isClicked,
        // the child manages its own state
        onCheckedChange = { isClicked = !isClicked }
    )
    Box(
        modifier = Modifier
            .size(150.dp)
            .background(
                if (isClicked) Green200 else Blue200
            )
    )
}
Xml
<!-- XML Code -->

<Switch
    android:id="@+id/switch_example"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

<View
    android:id="@+id/box"
    android:layout_width="150dp"
    android:layout_height="150dp"
    android:background="@color/blue_200"/>

    <!-- Code-->

private var isClicked = false
binding?.switchExample?.setOnClickListener {
    if (isClicked) {
        binding?.box?.setBackgroundColor(resources.getColor(R.color.blue_200))
    } else {
        binding?.box?.setBackgroundColor(resources.getColor(R.color.green_200))
    }
    isClicked = !isClicked
}
Stateless with hoisting
Kotlin
@Composable
fun StatelessExample() {

    // the parent manages the state of the child
    var isClicked by remember { mutableStateOf(false) }

    MySwitch(isClicked = isClicked) {
        // the parent, in this case th StatelessExample manages the state of MySwitch through an event of the child
        isClicked = !isClicked
    }
}

@Composable
fun MySwitch(isClicked: Boolean, onToggle: () -> Unit) {
    // the child gives back an event to parent via lambda expression,
    // so it can handle the state properly
    Switch(
        checked = isClicked,
        onCheckedChange = { onToggle() }
    )
    Box(
        modifier = Modifier
            .size(150.dp)
            .background(
                if (isClicked) Green200 else Blue200
            )
    )
}
Xml
<!-- XML Code -->

    <Switch
        android:id="@+id/switch_example"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <View
        android:id="@+id/box"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:background="@color/blue_200"/>

<!-- Code-->

    private var isClicked = false
    binding?.switchExample?.setOnClickListener {
        if (isClicked) {
            binding?.box?.setBackgroundColor(resources.getColor(R.color.blue_200))
        } else {
            binding?.box?.setBackgroundColor(resources.getColor(R.color.green_200))
        }
        isClicked = !isClicked
    }
State holder
Kotlin
class MyStateHolder() {
    // states
    var text by mutableStateOf("")
    var isClicked by mutableStateOf(false)

    // events
    fun onTextChanged(input: String) {
        text = input
    }

    fun onToggle(clicked: Boolean) {
        isClicked = clicked
    }
}

// Through this implementation, the lifecycle corresponds to the composable that implemented it
@Composable
fun rememberStateHolder(): MyStateHolder =
    remember { MyStateHolder() }

@Composable
fun MyScreen(state: MyStateHolder = rememberStateHolder()) {

    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        TextField(
            value = state.text,
            onValueChange = { state.onTextChanged(it) },
        )

        Switch(
            checked = state.isClicked,
            onCheckedChange = { state.onToggle(it) }
        )

        Box(
            modifier = Modifier
                .size(100.dp)
                .background(
                    if (state.isClicked) Green200 else Blue200
                )
        )
    }
}
Xml
    <!-- XML Code -->
<com.google.android.material.textfield.TextInputLayout
    android:id="@+id/text_layout"
    android:layout_width="250dp"
    android:layout_height="wrap_content"
    android:layout_marginBottom="10dp">

    <com.google.android.material.textfield.TextInputEditText
        android:id="@+id/input_edit_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>

<Switch
    android:id="@+id/state_holder_switch"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

<View
    android:id="@+id/view_box"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_marginTop="10dp"
    android:background="@color/blue_200" />

    <!-- Code -->

binding?.stateHolderSwitch?.setOnClickListener {
    setBackgroundColor(
        binding?.viewBox,
        requireNotNull(binding?.stateHolderSwitch?.isChecked)
    )
}

private fun setBackgroundColor(viewBox: View?, clicked: Boolean) {
    if (clicked) {
        viewBox?.setBackgroundResource(R.color.green_200)
    } else {
        viewBox?.setBackgroundResource(R.color.blue_200)
    }
}
ViewModel
Kotlin
// the ViewModel manages the states and the events
// it also has access to the business logic and has a longer lifecycle than the composable
class MyViewModel : MyViewModelInterface {
    // states
    override var number = mutableStateOf(0)
    override var isClicked = mutableStateOf(false)

    // events
    fun addNumber() {
        number.value = number.value + 1
    }
    fun toggle(clicked: Boolean) {
        isClicked.value = clicked
    }
}

interface MyViewModelInterface {
    val number: MutableState
    val isClicked : MutableState

    fun addNumber()
    fun toggle(clicked: Boolean)
}

@Composable
fun MyScreen(myViewModel: MyViewModelInterface) {
    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Text(
            text = myViewModel.number.value.toString(),
            modifier = Modifier.clickable { myViewModel.addNumber() }
        )

        Switch(
            checked = myViewModel.isClicked.value,
            onCheckedChange = { myViewModel.toggle(it) }
        )

        Box(
            modifier = Modifier
                .size(100.dp)
                .background(
                    if (myViewModel.isClicked.value) Green200 else Blue200
                )
        )
    }
}
Xml
    <!-- XML Code -->

<TextView
    android:id="@+id/textView"
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:background="@color/blue_200"
    android:foreground="?attr/selectableItemBackground"
    android:gravity="center"
    android:clickable="true"
    android:focusable="true" />

<Switch
    android:id="@+id/viewModel_switch"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginVertical="10dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<View
    android:id="@+id/box_view"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:background="@color/blue_200" />

    <!-- onCreate -->

binding?.apply {
    setBackgroundColor(viewModelUI.isClicked, boxView)
    textView.text = viewModelUI.number.toString()

    viewModelSwitch.setOnClickListener {
        viewModelUI.onToggle()
        setBackgroundColor(viewModelUI.isClicked, boxView)
    }

    textView.setOnClickListener {
        viewModelUI.onClick()
        textView.text = viewModelUI.number.toString()
    }
}

    <!-- Code -->

private fun setBackgroundColor(clicked: Boolean, boxView: View) {
    if (clicked) {
        boxView.setBackgroundResource(R.color.green_200)
    } else {
        boxView.setBackgroundResource(R.color.blue_200)
    }
}

class MyAndroidUIViewModel : ViewModel() {
    var isClicked: Boolean = false
    var number: Int = 0

    fun onToggle() {
        isClicked = !isClicked
    }

    fun onClick() {
        number++
    }
}
Events
Event Flow
Kotlin
// brief explanation, states are given by the parents to the children.
// The children, on the other hand, only give events to the parents.
// Thus we have a unidirectional flow.

@Composable
fun EventsExample() {
    // this is the parent class
    // it contains the child and gives down the states
    // ideally only the parent changes the states
    var number by remember { mutableStateOf(0) }

    Column(
        Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        // here it gives the states to the child
        NumberText(number = number.toString())

        // between the curly brackets, the parent can decide what should happen when an event occurs.
        AddButton {
            number++
        }

        SubtractButton {
            number--
        }
    }

}

@Composable
fun NumberText(number: String) {
    // the child can't change the state, in this case number.
    Text(
        // the number displayed depends on the state
        text = number,
        fontSize = 24.sp,
        color = White
    )
}

@Composable
fun AddButton(onClick: () -> Unit) {
    // if the child is clicked, an event is sent to the parents.
    Button(
        onClick = onClick,
        modifier = Modifier.padding(10.dp)
    ) {
        Text(text = "ADD +1")
    }
}

@Composable
fun SubtractButton(onClick: () -> Unit) {
    Button(
        onClick = onClick
    ) {
        Text(text = "ADD -1")
    }
}
Xml
<!--
 brief explanation, the viewModel holds the data and modifies it.
 It gives the states/data to the fragment.
 The fragment modifies the UI.
 The UI sends events to the ViewModel for example, that it got clicked.
 The event flow starts all over again
-->

<!-- Fragment -->
class Activity: AppCompatActivity() {

    lateinit var binding: EventLayoutBinding
    private val viewModel: EventViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = EventLayoutBinding.inflate(layoutInflater)
        setContentView(binding.root)
        supportActionBar?.title = "Events"

        binding.apply {

            addButton.setOnClickListener {
                viewModel.plusOne()
                textView.text = viewModel.number.toString()
            }

            subtractButton.setOnClickListener {
                viewModel.minusOne()
                textView.text = viewModel.number.toString()
            }
        }
    }
}

<!-- ViewModel -->
class EventViewModel : ViewModel() {
    var number = 0

    fun plusOne() {
        number++
    }
    
    fun minusOne(){
        number--
    }
}

<!-- XML Code -->

<TextView
    android:id="@+id/textView"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:background="@color/green_200"
    android:textColor="@color/white"
    android:textSize="24sp"
    android:gravity="center"/>

<Button
    android:id="@+id/add_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"
    android:text="Add +1" />

<Button
    android:id="@+id/subtract_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"
    android:text="Add -1" />
Material Theme
Theme
Kotlin
// colour

val exampleColors: Colors
    get() = lightColors(
        primary = Color(0xFF862A8A),
        primaryVariant = Color(0xFFC280D5),
        onPrimary = Color(0xFFFFFFFF),

        secondary = Color(0xFFFF30FC),
        secondaryVariant = Color(0xFAEAF7FB),
        onSecondary = Color(0xFFFFFFFF),

        error = Color(0xFFC82D70),
        onError = Color(0xFFFFFFFF),

        surface = Color(0xFFFFFFFF),
        onSurface = Color(0xFF333333),

        background = Color(0xFCEFEFF3),
        onBackground = Color(0xFFFFFFFF)
    )

// font style

val exampleTypography: Typography
    get() = Typography(
        h1 = TextStyle(
            fontSize = 24.sp,
            lineHeight = 28.sp,
            color = Grey3,
            letterSpacing = 0.sp
        ),
        h2 = TextStyle(
            fontSize = 20.sp,
            lineHeight = 24.sp,
            color = Grey6,
            letterSpacing = 0.sp
        ),
        h3 = TextStyle(
            fontSize = 18.sp,
            lineHeight = 22.sp,
            color = Grey3,
            letterSpacing = 0.sp
        ),
        h4 = TextStyle(
            fontSize = 16.sp,
            lineHeight = 20.sp,
            color = Grey6,
            letterSpacing = 0.sp
        ),
        h5 = TextStyle(
            fontSize = 14.sp,
            lineHeight = 18.sp,
            color = Grey9,
            letterSpacing = 0.sp
        ),
        h6 = TextStyle(
            fontSize = 12.sp,
            lineHeight = 16.sp,
            color = Grey3,
            letterSpacing = 0.sp
        ),
        subtitle1 = TextStyle(
            fontSize = 18.sp,
            lineHeight = 22.sp,
            color = Grey3,
            letterSpacing = 0.sp
        ),
        subtitle2 = TextStyle(
            fontSize = 16.sp,
            lineHeight = 20.sp,
            color = Grey6,
            letterSpacing = 0.sp
        ),
        body1 = TextStyle(
            fontSize = 16.sp,
            lineHeight = 20.sp,
            color = Grey6,
            letterSpacing = 0.sp
        ),
        body2 = TextStyle(
            fontSize = 14.sp,
            lineHeight = 18.sp,
            color = Grey9,
            letterSpacing = 0.sp
        ),
        button = TextStyle(
            fontSize = 16.sp,
            lineHeight = 18.sp,
            color = Color.White,
            letterSpacing = 0.sp
        ),
        caption = TextStyle(
            fontSize = 12.sp,
            lineHeight = 16.sp,
            color = Grey3,
            letterSpacing = 0.sp
        ),
        overline = TextStyle(
            fontSize = 12.sp,
            lineHeight = 16.sp,
            color = Grey6,
            letterSpacing = 0.sp
        )
    )

// shapes

val exampleShapes: Shapes
    get() = Shapes(
        small = RoundedCornerShape(0.dp),
        medium = RoundedCornerShape(8.dp),
        large = RoundedCornerShape(16.dp)
    )

@Composable
fun ExampleTheme(content: @Composable () -> Unit) {
    MaterialTheme(
        colors = exampleColors,
        typography = exampleTypography,
        shapes = exampleShapes,
        content = content
    )
}

// usable like this

@Composable
fun ExampleThemeDemo() {
    ExampleTheme {
        [...]
    }
}

// also addable to manifest

<activity
    android:name=".features.theme.ComposableThemeActivity"
    android:exported="false"
    android:theme="@style/ExampleTheme" />
Xml
    <!-- allocation of colour, style and shape -->

<style name="ExampleTheme" parent="Theme.AppCompat">
    <item name="colorPrimary">#862A8A</item>
    <item name="colorPrimaryVariant">#C280D5</item>
    <item name="colorOnPrimary">@color/white</item>

    <item name="colorSecondary">#FF30FC</item>
    <item name="colorSecondaryVariant">#EAF7FB</item>
    <item name="colorOnSecondary">@color/white</item>

    <item name="colorError">#C82D70</item>
    <item name="colorOnError">@color/white</item>

    <item name="colorSurface">@color/white</item>
    <item name="colorOnSurface">#333333</item>

    <item name="android:colorBackground">#EFEFF3</item>
    <item name="android:windowBackground">@color/white</item>

    <item name="textAppearanceHeadline1">@style/h1</item>
    <item name="textAppearanceHeadline2">@style/h2</item>
    <item name="textAppearanceHeadline3">@style/h3</item>
    <item name="textAppearanceHeadline4">@style/h4</item>
    <item name="textAppearanceHeadline5">@style/h5</item>
    <item name="textAppearanceHeadline6">@style/h6</item>
    <item name="textAppearanceSubtitle1">@style/s1</item>
    <item name="textAppearanceSubtitle2">@style/s2</item>
    <item name="textAppearanceBody1">@style/b1</item>
    <item name="textAppearanceBody2">@style/b2</item>
    <item name="textAppearanceButton">@style/button</item>
    <item name="textAppearanceCaption">@style/caption</item>
    <item name="textAppearanceOverline">@style/overline</item>

    <item name="shapeAppearanceSmallComponent">@style/small</item>
    <item name="shapeAppearanceMediumComponent">@style/medium</item>
    <item name="shapeAppearanceLargeComponent">@style/large</item>

</style>

    <!-- font style -->

<resources>
    <style name="h1" parent="TextAppearance.MaterialComponents.Headline1">
        <item name="android:textSize">24sp</item>
        <item name="lineHeight">28sp</item>
        <item name="android:textColor">@color/shared_cool_grey_3</item>
        <item name="android:letterSpacing">0</item>
    </style>

    <style name="h2" parent="TextAppearance.MaterialComponents.Headline2">
        <item name="android:textSize">20sp</item>
        <item name="lineHeight">24sp</item>
        <item name="android:textColor">@color/shared_cool_grey_6</item>
        <item name="android:letterSpacing">0</item>
    </style>

    <style name="h3" parent="TextAppearance.MaterialComponents.Headline3">
        <item name="android:textSize">18sp</item>
        <item name="lineHeight">22sp</item>
        <item name="android:textColor">@color/shared_cool_grey_3</item>
        <item name="android:letterSpacing">0</item>
    </style>

    <style name="h4" parent="TextAppearance.MaterialComponents.Headline4">
        <item name="android:textSize">16sp</item>
        <item name="lineHeight">20sp</item>
        <item name="android:textColor">@color/shared_cool_grey_6</item>
        <item name="android:letterSpacing">0</item>
    </style>

    <style name="h5" parent="TextAppearance.MaterialComponents.Headline5">
        <item name="android:textSize">14sp</item>
        <item name="lineHeight">18sp</item>
        <item name="android:textColor">@color/shared_cool_grey_9</item>
        <item name="android:letterSpacing">0</item>
    </style>

    <style name="h6" parent="TextAppearance.MaterialComponents.Headline6">
        <item name="android:textSize">12sp</item>
        <item name="lineHeight">16sp</item>
        <item name="android:textColor">@color/shared_cool_grey_3</item>
        <item name="android:letterSpacing">0</item>
    </style>

    <style name="s1" parent="TextAppearance.MaterialComponents.Subtitle1">
        <item name="android:textSize">18sp</item>
        <item name="lineHeight">22sp</item>
        <item name="android:textColor">@color/shared_cool_grey_3</item>
        <item name="android:letterSpacing">0</item>
    </style>

    <style name="s2" parent="TextAppearance.MaterialComponents.Subtitle2">
        <item name="android:textSize">16sp</item>
        <item name="lineHeight">20sp</item>
        <item name="android:textColor">@color/shared_cool_grey_6</item>
        <item name="android:letterSpacing">0</item>
    </style>

    <style name="b1" parent="TextAppearance.MaterialComponents.Body1">
        <item name="android:textSize">16sp</item>
        <item name="lineHeight">20sp</item>
        <item name="android:textColor">@color/shared_cool_grey_6</item>
        <item name="android:letterSpacing">0</item>
    </style>

    <style name="b2" parent="TextAppearance.MaterialComponents.Body2">
        <item name="android:textSize">14sp</item>
        <item name="lineHeight">18sp</item>
        <item name="android:textColor">@color/shared_cool_grey_9</item>
        <item name="android:letterSpacing">0</item>
    </style>

    <style name="button" parent="TextAppearance.MaterialComponents.Button">
        <item name="android:textSize">16sp</item>
        <item name="lineHeight">18sp</item>
        <item name="android:textColor">@color/shared_white</item>
        <item name="android:letterSpacing">0</item>
    </style>

    <style name="caption" parent="TextAppearance.MaterialComponents.Caption">
        <item name="android:textSize">12sp</item>
        <item name="lineHeight">16sp</item>
        <item name="android:textColor">@color/shared_cool_grey_3</item>
        <item name="android:letterSpacing">0</item>
    </style>

    <style name="overline" parent="TextAppearance.MaterialComponents.Overline">
        <item name="android:textSize">12sp</item>
        <item name="lineHeight">16sp</item>
        <item name="android:textColor">@color/shared_cool_grey_6</item>
        <item name="android:letterSpacing">0</item>
    </style>


    <color name="shared_cool_grey_6">#666666</color>
    <color name="shared_cool_grey_9">#999999</color>
    <color name="shared_white">#FFFFFF</color>
    <color name="shared_cool_grey_3">#333333</color>
</resources>

    <!-- shape styles -->

<resources>
<style name="small" parent="ShapeAppearance.MaterialComponents.SmallComponent">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSize">0%</item>
</style>

<style name="medium" parent="ShapeAppearance.MaterialComponents.MediumComponent">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSize">5%</item>
</style>

<style name="large" parent="ShapeAppearance.MaterialComponents.LargeComponent">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSize">10%</item>
</style>
</resources>

    <!-- in manifest -->

<activity
    android:name=".features.theme.AndroidUIThemeActivity"
    android:exported="false"
    android:theme="@style/ExampleTheme" />
Side Effects
LaunchedEffect
Kotlin
@Composable
fun LaunchedEffectDemo() {
    var isSnackbarVisible by remember { mutableStateOf(false) }
    val scaffoldState = rememberScaffoldState()

    if (isSnackbarVisible) {

        //LaunchedEffect Safely executes suspends funs
        LaunchedEffect(scaffoldState.snackbarHostState) {

            //showSnackbar is a suspend fun
            scaffoldState.snackbarHostState.showSnackbar(
                message = "this is a snackbar",
                actionLabel = "hide"
            )

            isSnackbarVisible = scaffoldState.snackbarHostState.currentSnackbarData != null
        }
    }

    Scaffold(
        scaffoldState = scaffoldState,
        topBar = {

            TopAppBar(
                title = { Text(text = "Launched Effect") }
            )
        }
    ) {

        Box(
            modifier = Modifier.fillMaxSize(),
            contentAlignment = Alignment.Center
        ) {

            Button(onClick = { isSnackbarVisible = !isSnackbarVisible }) {
                Text(text =
                if (isSnackbarVisible) "Hide Snackbar"
                else "Show Snackbar"
                )
            }
        }
    }
}
DisposableEffect
Kotlin
@Composable
fun DisposableEffectDemo() {

    var isEffectActive by remember { mutableStateOf(true) }
    var count by remember { mutableStateOf(0) }
    var disposableEffectKey by remember { mutableStateOf(true) }

    if (isEffectActive) {

        DisposableEffect(disposableEffectKey) {

            //is called when DisposableEffect leaves composition or key changed
            onDispose { count++ }
        }
    }

    Column(horizontalAlignment = Alignment.CenterHorizontally) {

        Text(text = "Disposed $count times")

        Button(onClick = { isEffectActive = !isEffectActive }) {

            Text(
                text = if (isEffectActive) "Deactivate"
                else "Activate"
            )
        }

        Button(onClick = { disposableEffectKey = !disposableEffectKey }) {

            Text(text = "Change key")
        }
    }
}
SideEffect
Kotlin
/*
    the SideEffect is used when you only want to run code if the composable is successfully recomposed.
    After the recomposition the codeblock within the SideEffect gets executed.
*/

@Composable
fun WithoutSideEffect() {
    var timer by remember {
        mutableStateOf(0)
    }

    Box(
        modifier = Modifier
            .size(100.dp)
            .padding(20.dp)
            .background(Green200),
        contentAlignment = Alignment.Center
    ) {
        Text(
            text = "$timer",
        )
    }

    /*
        through the Sleep, the timer gets changed when the composables recomposes itself.
        Therefore it does not call the recomposition.
    */
    Thread.sleep(1000)
    timer++
}

@Composable
fun WithSideEffect() {
    var timer by remember {
        mutableStateOf(0)
    }

    Box(
        contentAlignment = Alignment.Center,
        modifier = Modifier
            .size(100.dp)
            .padding(20.dp)
            .background(Green200),
    ) {
        Text(
            text = "$timer",
        )
    }

    /*
        Through SideEffect timer gets called after the composable got recomposed.
        So the composable gets recomposed and afterwards it increases timer.
        In this case we created a loop
    */
    SideEffect {
        Thread.sleep(1000)
        timer++
    }
}
Dialog
Time
Kotlin
@Composable
fun TimeExample() {

    var timePicked: String by remember {
        mutableStateOf("Pick a Time")
    }

    val activity = LocalContext.current as AppCompatActivity

    Text(
        text = timePicked,
        modifier = Modifier
            .clickable {
                showTimePicker(
                    { time: String ->
                        timePicked = time
                    },
                    activity
                )
            }
    )
}

private fun showTimePicker(
    time: (String) -> Unit,
    activity: AppCompatActivity
) {
    val picker = MaterialTimePicker.Builder()
        .setTimeFormat(TimeFormat.CLOCK_24H)
        .build()

    // be careful with the timepicker, because you need to manage the dispose!
    picker.show(activity.supportFragmentManager, picker.toString())

    picker.addOnPositiveButtonClickListener {
        time(
            formatTime(
                picker.hour,
                picker.minute
            )
        )
    }
}

private fun formatTime(hour: Int, minute: Int): String {
    var stringHour = hour.toString()
    var stringMinute = minute.toString()

    if (hour < 10) stringHour = "0$stringHour"
    if (minute < 10) stringMinute = "0$stringMinute"
    return "Time: $stringHour:$stringMinute"
}
Xml
<TextView
    android:id="@+id/time_picker_text_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:hint="Pick a time" />

    <!-- code implementation -->

private fun showTimePicker() {

    val materialTimePicker = MaterialTimePicker
        .Builder()
        .setTimeFormat(TimeFormat.CLOCK_24H)
        .build()

    materialTimePicker.addOnPositiveButtonClickListener {
        binding.timePickerTextView.text =
        formatTime(materialTimePicker.hour, materialTimePicker.minute)
    }
        materialTimePicker.show(supportFragmentManager, "TAG")
}

private fun formatTime(hour : Int, minute: Int) : String {
        var stringHour = hour.toString()
        var stringMinute = minute.toString()

        if (hour < 10) stringHour = "0$stringHour"
        if (minute < 10) stringMinute = "0$stringMinute"
        return "Time: $stringHour:$stringMinute"
}
Date
Kotlin
@Composable
fun Date() {

    var datePicked: String by remember {
        mutableStateOf("Date")}

    val updatedDate = { date: String ->
        datePicked = date
    }

    val activity = LocalContext.current as AppCompatActivity

    Text(
        text = datePicked,
        color = MaterialTheme.colors.onSurface,
        modifier = Modifier
            .wrapContentSize()
            .clickable { showDatePicker(activity, updatedDate) }
    )
}

private fun showDatePicker(
    activity: AppCompatActivity,
    updatedDate: (String) -> Unit
) {
    val picker = MaterialDatePicker.Builder.datePicker().build()

    // be careful with the datepicker, because you need to manage the dispose!
    picker.show(activity.supportFragmentManager, picker.toString())
    picker.addOnPositiveButtonClickListener {
        updatedDate(picker.headerText)
    }
}
Xml
<TextView
    android:id="@+id/TextViewDate"
    android:text="Date"
    app:drawableEndCompat="@drawable/ic_baseline_date_range" />

//In Activity or Fragment

    textViewDate = findViewById(R.id.TextViewDate)
    textViewDate.setOnClickListener {
      showDatePicker()
    }

    private fun showDatePicker() {
         val materialDatePicker = MaterialDatePicker
                                  .Builder
                                  .datePicker()
                                  .build()

         materialDatePicker.addOnPositiveButtonClickListener {
            textViewDate.text = materialDatePicker.headerText
         }
         materialDatePicker.show(supportFragmentManager, "TAG")
    }
}
AlertDialog
Kotlin
@Composable
fun AlertDialogExample() {
    var isVisible by remember { mutableStateOf(false) }

    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        Button(onClick = { isVisible = true }
        ) {
            Text(text = "SHOW DIALOG")
        }
    }

    ShowDialog(isVisible) {
        isVisible = !isVisible
    }
}

@Composable
fun ShowDialog(isVisible: Boolean, onClick: () -> Unit) {

    if (isVisible) {
        AlertDialog(
            onDismissRequest = { onClick() },
            title = {
                Text(
                    text = "Title",
                    style = MaterialTheme.typography.h6
                )
            },
            confirmButton = {
                Text(
                    text = "ACCEPT",
                    style = MaterialTheme.typography.button,
                    color = MaterialTheme.colors.primary,
                    modifier = Modifier
                        .padding(8.dp)
                        .clickable(
                            indication = null,
                            interactionSource = remember { MutableInteractionSource() }
                        ) {
                            onClick()
                        }
                )
            },
            dismissButton = {
                Text(
                    text = "DECLINE",
                    style = MaterialTheme.typography.button,
                    color = MaterialTheme.colors.primary,
                    modifier = Modifier
                        .padding(8.dp)
                        .clickable(
                            indication = null,
                            interactionSource = remember { MutableInteractionSource() }
                        ) {
                            onClick()
                        }
                )
            },
            text = {
                Text(
                    text = "Scias me hoc mane canem meum mulsisse. Numquam satus dies sine me calidum pug lac",
                    style = MaterialTheme.typography.body1
                )
            }
        )
    }
}
Xml
<!-- XML Code -->

<Button
    android:id="@+id/showDialogButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="show Dialog"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<!-- Code -->

lateinit var binding: AlertDialogLayoutBinding

private var dialog: AlertDialog? = null

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = AlertDialogLayoutBinding.inflate(layoutInflater)
    setContentView(binding.root)
    supportActionBar?.title = "AlertDialog"

    dialog = AlertDialog.Builder(this)
        .setTitle("Title")
        .setMessage("Scias me hoc mane canem meum mulsisse. Numquam satus dies sine me calidum pug lac")
        .setCancelable(true)
        .setPositiveButton("ACCEPT") { _, _ ->
            finishActivity()
        }
        .setNegativeButton("DECLINE") { _, _ ->
            finishActivity()
        }
        .create()

    binding.showDialogButton.setOnClickListener {
        dialog?.show()
    }
}

private fun finishActivity() {
    lifecycleScope.launch {
        finish()
    }
}

override fun onDestroy() {
    dialog?.dismiss()
    dialog = null
    super.onDestroy()
}