Row Expandable LazyVerticalGrid

 avatar
unknown
kotlin
3 years ago
4.6 kB
18
Indexable
package com.example.testcompose
// compose_ui_version > 1.2.1

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.grid.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Slider
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.testcompose.ui.theme.TestComposeTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            TestComposeTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    Greeting()
                }
            }
        }
    }
}

data class SliderItem(
    val index: Int, val isShown:
    MutableState<Boolean> = mutableStateOf(false)
)

@Composable
fun Greeting() {
    var selectedIndex by remember {
        mutableStateOf(0)
    }

    val defaultItem = listOf("0", "1", "2", "3", "4", "5", "6", "7", "8")
    val volumeSlider = listOf(SliderItem(0), SliderItem(1), SliderItem(2))

    LazyVerticalGrid(
        modifier = Modifier.padding(16.dp),
        columns = GridCells.Fixed(3),
        verticalArrangement = Arrangement.spacedBy(16.dp),
        horizontalArrangement = Arrangement.spacedBy(16.dp),
        content = {
            defaultItem.forEachIndexed { itemIndex, item ->
                item {
                    Item(content = item, isSelected = selectedIndex == itemIndex, onClick = {
                        selectedIndex = itemIndex

                        //item đầu tiên rỗng sẽ không chọn
                        if (itemIndex != 0) {
                            val sliderIndex = selectedIndex / 3
                            volumeSlider.forEach { slider ->
                                slider.isShown.value = slider.index == sliderIndex
                            }
                        } else {
                            volumeSlider.forEach { slider ->
                                slider.isShown.value = false
                            }
                        }
                    })
                }

                if ((itemIndex + 1) % 3 == 0) {
                    header { VolumeSlider(volumeSlider[(itemIndex + 1) / 3 - 1].isShown.value) }
                }
            }
        })
}

fun LazyGridScope.header(
    content: @Composable LazyGridItemScope.() -> Unit
) {
    item(span = { GridItemSpan(this.maxLineSpan) }, content = content)
}

@Composable
fun VolumeSlider(enable: Boolean) {
    AnimatedVisibility(visible = enable) {
        Box(
            modifier = Modifier
                .clip(shape = RoundedCornerShape(8.dp))
                .fillMaxWidth()
                .padding(16.dp)
        ) {
            Slider(
                value = 50f,
                valueRange = 0f..100f,
                onValueChange = {},
                modifier = Modifier
                    .fillMaxWidth()
                    .align(Alignment.Center)
            )
        }
    }
}

@Composable
fun Item(content: String, isSelected: Boolean, onClick: () -> Unit) {
    Box(
        modifier = Modifier
            .clip(shape = CircleShape)
            .background(color = Color.Green)
            .border(if (isSelected) 4.dp else 0.dp, Color.Red, shape = CircleShape)
            .aspectRatio(1f)
            .clickable { onClick() }
    ) {
        Text(text = content, modifier = Modifier.align(Alignment.Center), color = Color.White)
    }
}

@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    TestComposeTheme {
        Greeting()
    }
}

Editor is loading...