添加按钮以查看动态擦除现有视图
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 的内部范围内使用 this
和 return
时,您有时需要指定这些参数的范围。你得到一个错误,因为 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
文本上以查看它所指的范围。
结果布局
我有一个字符串列表,我想创建线性布局的按钮,其文本来自该列表。我在 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 的内部范围内使用 this
和 return
时,您有时需要指定这些参数的范围。你得到一个错误,因为 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
文本上以查看它所指的范围。
结果布局