如何在 jetpack compose 中创建具有静态值的可扩展列表视图

问题描述 投票:0回答:2

我已经使用静态值创建了 Kotlin 代码:

我想知道如何使用 jetpack compose 创建相同的内容?我不知道

代码:

       class TestApp : AppCompatActivity() {
    
        var listAdapter: ExpandableListAdapter? = null
        var expListView: ExpandableListView? = null
        var listDataHeader: MutableList<String>? = null
        var listDataChild: HashMap<String, List<String>>? = null
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            expListView = findViewById<View>(R.id.lvExp) as ExpandableListView
            prepareListData()
            listAdapter = ExpandableListAdapter(this, listDataHeader, listDataChild)
            expListView!!.setAdapter(listAdapter)
    
        }
        private fun prepareListData() {
        listDataHeader = ArrayList()
        listDataChild = HashMap()
        listDataHeader?.add(getString(R.string.q_1))
        val on_0: MutableList<String> = ArrayList()
        on_0.add(getString(R.string.faq_d_0))
        listDataChild!![listDataHeader!![0]] = on_0
}
    }
android expandablelistview android-jetpack-compose
2个回答
27
投票

您可以使用

LazyColumn
加上可变状态列表来存储折叠状态:

@Composable
fun CollapsableLazyColumn(
    sections: List<CollapsableSection>,
    modifier: Modifier = Modifier
) {
    val collapsedState = remember(sections) { sections.map { true }.toMutableStateList() }
    LazyColumn(modifier) {
        sections.forEachIndexed { i, dataItem ->
            val collapsed = collapsedState[i]
            item(key = "header_$i") {
                Row(
                    verticalAlignment = Alignment.CenterVertically,
                    modifier = Modifier
                        .clickable {
                            collapsedState[i] = !collapsed
                        }
                ) {
                    Icon(
                        Icons.Default.run {
                            if (collapsed)
                                KeyboardArrowDown
                            else
                                KeyboardArrowUp
                        },
                        contentDescription = "",
                        tint = Color.LightGray,
                    )
                    Text(
                        dataItem.title,
                        fontWeight = FontWeight.Bold,
                        modifier = Modifier
                            .padding(vertical = 10.dp)
                            .weight(1f)
                    )
                }
                Divider()
            }
            if (!collapsed) {
                items(dataItem.rows) { row ->
                    Row {
                        Spacer(modifier = Modifier.size(MaterialIconDimension.dp))
                        Text(
                            row,
                            modifier = Modifier
                                .padding(vertical = 10.dp)
                        )
                    }
                    Divider()
                }
            }
        }
    }
}

data class CollapsableSection(val title: String, val rows: List<String>)

const val MaterialIconDimension = 24f

用途:

CollapsableLazyColumn(
    sections = listOf(
        CollapsableSection(
            title = "Fruits A",
            rows = listOf("Apple", "Apricots", "Avocado")
        ),
        CollapsableSection(
            title = "Fruits B",
            rows = listOf("Banana", "Blackberries", "Blueberries")
        ),
        CollapsableSection(
            title = "Fruits C",
            rows = listOf("Cherimoya", "Cantaloupe", "Cherries", "Clementine")
        ),
    ),
)

结果:


0
投票

扩展@PhilDhukov的答案,我制作了一个更通用的版本,它接受可组合项,从而在自定义行/标题时具有更大的灵活性;

@Composable
fun CollapsableList(
    sections: List<CollapsableListSection>,
    modifier: Modifier = Modifier,
    state: LazyListState = rememberLazyListState(),
    expandByDefault: Boolean = true
) {
    val expandState =
        remember(sections) { sections.map { expandByDefault }.toMutableStateList() }

    LazyColumn(modifier, state = state) {
        sections.forEachIndexed { i, section ->
            val expand = expandState[i]
            item(key = "header_$i") {
                CollapsableListRow(
                    { section.header() },
                    Modifier.clickable { expandState[i] = !expand }
                )
            }
            if (expand) {
                items(section.rows) { row ->
                    CollapsableListRow({ row() })
                }
            }
        }
    }
}

@Composable
internal fun CollapsableListRow(content: @Composable () -> Unit, modifier: Modifier = Modifier) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .then(modifier)
    ) {
        content()
    }
}

data class CollapsableListSection(
    val header: @Composable () -> Unit,
    val rows: List<@Composable () -> Unit>
)
© www.soinside.com 2019 - 2024. All rights reserved.