添加按钮以查看动态擦除现有视图

Adding buttons to view dynamically wipes existing views

我有一个字符串列表,我想创建线性布局的按钮,其文本来自该列表。我在 XML 文件中的线性布局是:

...other stuff...
<LinearLayout
    android:id="@+id/my_linear_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"/>

然后在onCreate我有以下代码:

buttons = viewModel.myLiveDataList.value!!.map {
    val button = Button(binding.myLinearLayout.context)
    button.layoutParams = LinearLayout.LayoutParams(
        LinearLayout.LayoutParams.WRAP_CONTENT,
        LinearLayout.LayoutParams.WRAP_CONTENT)
    button.text = it.displayName
    return button
}

我觉得我做的不对,因为我从来没有在线性布局上调用 addView,我见过的所有示例都是这样,但是当我尝试调用 addView我收到关于按钮已经有父项的错误。

此代码的结果是片段仅显示一个按钮,其文本是列表的第一个条目。它不显示线性布局之前存在的“其他内容”,也不显示列表中任何其他条目的按钮。

我已经通过日志记录验证了列表本身确实有多个条目,但是映射函数只在第一个条目上执行,我不知道为什么视图中的其他所有内容都被删除了,我只得到一个按钮。

任何人都可以向我解释我做错了什么吗?

编辑:根据要求,我最初尝试按照示例 here 并编写了以下内容:

buttons = viewModel.myLiveDataList.value!!.map {
    val button = Button(this)
    button.layoutParams = LinearLayout.LayoutParams(
        LinearLayout.LayoutParams.WRAP_CONTENT,
        LinearLayout.LayoutParams.WRAP_CONTENT)
    button.text = it.displayName
    binding.myLinearLayout.addView(button)
    return button
}

这不会编译,因为 Button 需要一个上下文,所以我将其更改为 Button(this.context) 然后它在 addView 上崩溃并显示消息

java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

您的代码很接近,但是当您在 Kotlin 的内部范围内使用 thisreturn 时,您有时需要指定这些参数的范围。你得到一个错误,因为 this 指的是映射 lambda,而不是 activity,这就是为什么它说它需要一个上下文。

这对我有用 - 成功地向线性布局添加了三个按钮。请注意使用 this@MainActivity 来获取封闭的 activity 和 return@map。您也可以只在最后一行键入 button 而无需 return 语句,有时它可以在没有 @ 的情况下正确推断出 this 的正确范围,但它通常是指定它是个好主意。

val linearLayout = findViewById<LinearLayout>(R.id.my_linear_layout)

val buttonText = listOf("Button A","Button B","Button C")
val buttons = buttonText.map { txt ->
    val button = Button(this@MainActivity)
    button.layoutParams = LinearLayout.LayoutParams(
        LinearLayout.LayoutParams.WRAP_CONTENT,
        LinearLayout.LayoutParams.WRAP_CONTENT)
    button.text = txt
    linearLayout.addView(button)
    return@map button // or just "button" by itself without a "return"
}

注意:当我第一次复制你的代码时,我看到了关于 Button 需要上下文的相同错误,但在随后的复制尝试中,this 似乎工作正常。我不知道为什么它以前不起作用但现在起作用了,但是使用 @ 表示法不会有什么坏处。在 Android Studio 中,您可以将鼠标悬停在 this 文本上以查看它所指的范围。

结果布局