You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

点击右侧字母索引列时如何在屏幕中央显示放大首字母提示

实现方案

完全可以实现点击/滑动右侧字母索引时在屏幕中央显示放大选中字母的效果,核心是在布局上层加一个居中的提示浮层,仅在用户操作索引栏时展示,操作结束自动隐藏,仅需在原有代码基础上做少量修改:

  • 新增两个状态变量:分别控制中央提示的显隐、存储当前选中的字母内容
  • 补全右侧索引栏的手势逻辑:手指按下、滑动过程中显示提示,手指抬起/拖动取消时隐藏提示
  • 将原有列表+索引栏的Row布局嵌套进Box容器,在Box的层级上方添加居中的放大字母提示组件

改动后完整代码

enum class Items(@StringRes val nameId: Int, val typeId: Int) {
    Item1(R.string.apple, R.string.fruit),
    Item2(R.string.banana, R.string.fruit),
    Item3(R.string.cherry, R.string.fruit),
    Item4(R.string.date, R.string.fruit),
    Item5(R.string.eggplant, R.string.vegetable),
    Item6(R.string.fig, R.string.fruit),
    Item7(R.string.guava, R.string.fruit),
    Item8(R.string.jackfruit, R.string.fruit),
    Item9(R.string.kiwi, R.string.fruit),
    Item10(R.string.leek, R.string.vegetable),
    Item11(R.string.okra, R.string.vegetable),
    Item12(R.string.pumpkin, R.string.fruit),
    Item13(R.string.rhubarb, R.string.fruit),
    Item14(R.string.spinach, R.string.vegetable),
    Item15(R.string.turnip, R.string.vegetable),
    Item16(R.string.watermelon, R.string.fruit);
}

@Composable
fun LetterIndexList() {
    val items = remember {
        arrayOf(
            Items.Item1,
            Items.Item2,
            Items.Item3,
            Items.Item4,
            Items.Item5,
            Items.Item6,
            Items.Item7,
            Items.Item8,
            Items.Item9,
            Items.Item10,
            Items.Item11,
            Items.Item12,
            Items.Item13,
            Items.Item14,
            Items.Item15,
            Items.Item16
        ).sortedBy { getString(it.nameId) }
    }
    val headers = remember { items.map { getString(it.nameId).first().uppercase() }.toSet().toList() }

    // 新增:中央提示显隐状态、当前提示字母
    var showIndexTip by remember { mutableStateOf(false) }
    var currentTipLetter by remember { mutableStateOf("") }

    Box(modifier = Modifier.fillMaxSize()) {
        Row {
            val listState = rememberLazyListState()
            LazyColumn(
                state = listState,
                modifier = Modifier.weight(1f)
            ) {
                items(items) {
                    Column() {
                        Text(
                            text = stringResource(id = it.nameId)
                        )
                        Text(
                            text = stringResource(id = it.typeId)
                        )
                    }
                }
            }
            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
                // 新增:更新当前提示的字母
                currentTipLetter = headers[selectedHeaderIndex]
                val selectedItemIndex = items.indexOfFirst { getString(it.nameId).first().uppercase() == headers[selectedHeaderIndex] }
                scope.launch {
                    listState.scrollToItem(selectedItemIndex)
                }
            }

            Column(
                verticalArrangement = Arrangement.SpaceEvenly,
                modifier = Modifier
                    .fillMaxHeight()
                    .background(Color.Green)
                    // 改动:补全点击手势的显隐逻辑
                    .pointerInput(Unit) {
                        detectTapGestures(
                            onPress = {
                                showIndexTip = true
                                awaitRelease()
                                showIndexTip = false
                            }
                        ) {
                            updateSelectedIndexIfNeeded(it.y)
                        }
                    }
                    // 改动:补全拖动手势的显隐逻辑
                    .pointerInput(Unit) {
                        detectVerticalDragGestures(
                            onDragStart = { showIndexTip = true },
                            onDragEnd = { showIndexTip = false },
                            onDragCancel = { showIndexTip = false }
                        ) { change, _ ->
                            updateSelectedIndexIfNeeded(change.position.y)
                        }
                    }
            ) {
                headers.forEachIndexed { i, header ->
                    Text(
                        header,
                        modifier = Modifier.onGloballyPositioned {
                            offsets[i] = it.boundsInParent().center.y
                        }
                    )
                }
            }
        }

        // 新增:屏幕中央放大字母提示
        if (showIndexTip) {
            Box(
                modifier = Modifier
                    .align(Alignment.Center)
                    .size(80.dp)
                    .background(Color.DarkGray, RoundedCornerShape(12.dp)),
                contentAlignment = Alignment.Center
            ) {
                Text(
                    text = currentTipLetter,
                    fontSize = 36.sp,
                    color = Color.White,
                    fontWeight = FontWeight.Bold
                )
            }
        }
    }
}

可自定义调整项

  • 中央提示的尺寸、背景色、圆角、字体大小、字重都可以根据设计需求直接修改对应参数
  • 如果需要更顺滑的展示效果,可以用AnimatedVisibility包裹中央提示组件,添加淡入淡出、缩放的过渡动画
  • 可以给提示增加额外的样式,比如加阴影、边框,匹配整体APP风格

内容的提问来源于stack exchange,提问作者wbk727

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 10:42:22