Jetpack Compose 中的字母滚动条

Alphabetical Scrollbar in jetpack compose

有谁知道如何创建一个按字母顺序排列的快速滚动条,显示 Jetpack Compose 中的所有字母?

与此类似:

我制作了一个可滚动的列表,但我不知道如何制作侧面的字母并使其“跳转”到正确的字母。

这是我目前的编码:

package com.example.ValpeHagen.ui.theme

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowDropDown
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
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.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.ValpeHagen.model.DataProvider
import com.example.ValpeHagen.model.DataProvider2
import com.example.androiddevchallenge.data.model.Rase




class Valpen {

    val rase = DataProvider2.rase




@Composable
fun VerticalHorizontalScroll(rase: Rase) {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .background(Color.White)
    ) {
        Column(
            modifier = Modifier
                .fillMaxWidth()
                .height(60.dp)
                .background(Grass),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Center
        ) {
            Text(text = "Velg Rase",
                color = Color.White,
                fontSize = 30.sp,
                fontWeight = FontWeight.Bold,)
        }

        LazyColumn {
            item {
                Text(
                    text = "Hurtigvalg",
                    color = Color.Black,
                    fontSize = 18.sp,
                    fontWeight = FontWeight.Bold,
                    modifier = Modifier.padding(10.dp)
                )
            }

            //Horizontal Scroll view
            item {
                LazyRow {
                    itemsIndexed(items = DataProvider.puppyList) { index, itemPuppy ->
                        Card(
                            modifier = Modifier
                                .width(110.dp)
                                .height(140.dp)
                                .padding(10.dp, 5.dp, 5.dp, 0.dp)
                                .clip(RoundedCornerShape(10.dp))
                                .background(Color.White),
                            elevation = 5.dp
                        )  {
                            Column(
                                modifier = Modifier.padding(5.dp),
                                horizontalAlignment = Alignment.CenterHorizontally,
                                verticalArrangement = Arrangement.Center
                            ) {

                                Image(
                                    painter = painterResource(id = DataProvider.puppy.puppyImageId),
                                    contentDescription = "profile Image",
                                    contentScale = ContentScale.Crop,
                                    modifier = Modifier
                                        .size(60.dp)
                                        .clip(CircleShape)
                                )

                                Spacer(modifier = Modifier.padding(5.dp))

                                Text(
                                    text = DataProvider.puppy.breeds,
                                    color = Color.Black,
                                    fontWeight = FontWeight.Bold,
                                    fontSize = 16.sp)

                            }
                        }
                    }
                }
            }
            val mylist = listOf("Affenpinscher", "Wheaten terrier" , "dachshund",
                "Fransk bulldog","Affenpinscher", "Wheaten terrier" , "dachshund",
                "Fransk bulldog","Affenpinscher", "Wheaten terrier" , "dachshund",
                "Fransk bulldog","Affenpinscher", "Wheaten terrier" , "dachshund",
                "Fransk bulldog","Affenpinscher", "Wheaten terrier" , "dachshund",
                "Fransk bulldog","Affenpinscher", "Wheaten terrier" , "dachshund",
                "Fransk bulldog","Affenpinscher", "Wheaten terrier" , "dachshund",
                "Fransk bulldog")


            item {

                Text(
                    text = "Alle hunderaser",
                    color = Color.Black,
                    fontSize = 18.sp,
                    fontWeight = FontWeight.Bold,
                    modifier = Modifier
                        .padding(vertical = 10.dp, horizontal = 10.dp)
                        .clip(RoundedCornerShape(10.dp))
                        .background(Color.White))
            }


            item {


                val list = listOf("A", "B", "C", "D",
                    "E","F","G","H","I","J","K","L","M","N",
                    "O","P","Q","R","S","T","U","V","W","X", "Y","Z","Æ","Ø","Å")
                val expanded = remember { mutableStateOf(false) }
                val currentValue = remember { mutableStateOf(list[0]) }



                Surface(modifier = Modifier.fillMaxSize()) {

                    Box(modifier = Modifier.fillMaxWidth()) {

                        Row(modifier = Modifier
                            .clickable {
                                expanded.value = !expanded.value
                            }
                            .align(Alignment.CenterStart)) {
                            Text(text = currentValue.value,
                                color = Grass,
                                fontSize = 18.sp,
                                fontWeight = FontWeight.Bold,
                                modifier = Modifier.padding(horizontal = 14.dp)
                            )
                            Icon(imageVector = Icons.Filled.ArrowDropDown, contentDescription = null)


                            DropdownMenu(expanded = expanded.value, onDismissRequest = {
                                expanded.value = false
                            }) {

                                list.forEach {

                                    DropdownMenuItem(onClick = {
                                        currentValue.value = it
                                        expanded.value = false
                                    }) {

                                        Text(text = it,
                                            color = Grass,
                                            fontSize = 18.sp,
                                            fontWeight = FontWeight.Bold,
                                            modifier = Modifier
                                                .padding(vertical = 10.dp,
                                                    horizontal = 10.dp))


                                    }

                                }






                            }


                        }





                    }

                }
            }


        }





    }

}
     }

要显示字母,您只需要 Column 和所需的项目。要将惰性列滚动到所需的项目,您可以使用惰性列状态。

这是一个基本示例:

val items = remember { LoremIpsum().values.first().split(" ").sortedBy { it.lowercase() } }
val headers = remember { items.map { it.first().uppercase() }.toSet().toList() }
Row {
    val listState = rememberLazyListState()
    LazyColumn(
        state = listState,
        modifier = Modifier.weight(1f)
    ) {
        items(items) {
            Text(it)
        }
    }
    val offsets = remember { mutableStateMapOf<Int, Float>() }
    var selectedHeaderIndex by remember { mutableStateOf(0) }
    val scope = rememberCoroutineScope()

    fun updateSelectedIndexIfNeeded(offset: Float) {
        val index = offsets
            .mapValues { abs(it.value - offset) }
            .entries
            .minByOrNull { it.value }
            ?.key ?: return
        if (selectedHeaderIndex == index) return
        selectedHeaderIndex = index
        val selectedItemIndex = items.indexOfFirst { it.first().uppercase() == headers[selectedHeaderIndex] }
        scope.launch {
            listState.scrollToItem(selectedItemIndex)
        }
    }

    Column(
        verticalArrangement = Arrangement.SpaceEvenly,
        modifier = Modifier
            .fillMaxHeight()
            .background(Color.Gray)
            .pointerInput(Unit) {
                detectTapGestures {
                    updateSelectedIndexIfNeeded(it.y)
                }
            }
            .pointerInput(Unit) {
                detectVerticalDragGestures { change, _ ->
                    updateSelectedIndexIfNeeded(change.position.y)
                }
            }
    ) {
        headers.forEachIndexed { i, header ->
            Text(
                header,
                modifier = Modifier.onGloballyPositioned {
                    offsets[i] = it.boundsInParent().center.y
                }
            )
        }
    }
}