Anko DSL recyclerview 添加项目时的奇怪行为
Anko DSL recyclerview strange behaviour while adding items
所以我的 RecyclerView 中最初有 6 个项目。当我添加一个项目时,我得到了一个祝酒词,上面说添加了新项目并显示适配器项目增加了。但是新项目是项目“6”的副本。然后我添加更多项目并且都是“6”。然后我上下滚动,我看到项目 "byButton"(这是通过单击按钮添加的按钮的名称),这些项目位于“6”的重复项之间。过了一会儿,整个 RecycleView 重置了,我仍然有 6 个项目,就像开始时一样。我不知道我的代码有什么问题。
class ConnectDeviceUI(val listAdapter: DeviceListAdapter): AnkoComponent<ConnectBleActivity> {
lateinit var addItemButton: FloatingActionButton
override fun createView(ui: AnkoContext<ConnectBleActivity>): View = with(ui) {
return relativeLayout() {
lparams(width= matchParent, height = matchParent)
textView("List of BLE devices"){
setTextAppearance(android.R.style.TextAppearance_Material_Large)
}
addItemButton = floatingActionButton {
imageResource = android.R.drawable.ic_input_add
}.lparams{
margin = dip(10)
alignParentBottom()
alignParentEnd()
alignParentRight()
gravity = Gravity.BOTTOM or Gravity.END
}
recyclerView(){
layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, true)
lparams(width= matchParent, height = matchParent)
adapter = listAdapter
}
}
}
}
class RowLayout(): AnkoComponent<ViewGroup>{
override fun createView(ui: AnkoContext<ViewGroup>): View = with(ui) {
return linearLayout(){
lparams(width= matchParent, height = wrapContent)
setPadding(0,dip(50),0,dip(50))
textView {
id = R.id.ble_item
setTextAppearance(android.R.style.TextAppearance_Material_Large)
setPadding(0,0,dip(100),0)
}.lparams(width = wrapContent, height = wrapContent )
button{
id = R.id.ble_item_button
}.lparams(width = wrapContent, height = wrapContent)
}
}
}
class ConnectBleActivity : AppCompatActivity(), AnkoLogger {
lateinit var BleDevicesList: ArrayList<String>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
BleDevicesList = arrayListOf("1", "2","3", "4", "5", "6")
var adapter = DeviceListAdapter(BleDevicesList)
var ui = ConnectDeviceUI(adapter)
ui.setContentView(this)
ui.addItemButton.onClick {
adapter.put()
toast("New item added. Number of items: ${adapter.itemCount} ")
}
}
}
class DeviceListAdapter(var deviceList: ArrayList<String>): RecyclerView.Adapter<DeviceListHolder>(){
override fun onBindViewHolder(holder: DeviceListHolder?, position: Int) {
holder?.bindItems(deviceList[position])
}
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): DeviceListHolder {
return DeviceListHolder(RowLayout().createView(AnkoContext.create(parent!!.context, parent)))
}
override fun getItemCount(): Int {
return deviceList.size
}
fun put(){
val randomString = UUID.randomUUID().toString()
deviceList.add(deviceList.lastIndex, "byButton")
notifyItemInserted(deviceList.lastIndex)
}
fun drop(){
deviceList.removeAt(deviceList.lastIndex)
notifyItemRemoved(deviceList.lastIndex)
}
}
class DeviceListHolder(var view: View): RecyclerView.ViewHolder(view){
val name: TextView = view.find(R.id.ble_item)
val bt_name: Button = view.find(R.id.ble_item_button)
fun bindItems(listItem: String){
name.text = listItem
bt_name.text = "Test"
}
}
在修改列表本身后使用 List.lastIndex()
,导致模型和视图中的不同值被更新
deviceList.add(deviceList.lastIndex, "byButton")
notifyItemInserted(deviceList.lastIndex)
通知告诉 RecyclerView
只更新最后一项。这包含一个 "6"
而旧位置根本没有更新。要解决此问题,您必须对两者使用相同的索引。
val index = deviceList.lastIndex
deviceList.add(index, "byButton")
notifyItemInserted(index)
所以我的 RecyclerView 中最初有 6 个项目。当我添加一个项目时,我得到了一个祝酒词,上面说添加了新项目并显示适配器项目增加了。但是新项目是项目“6”的副本。然后我添加更多项目并且都是“6”。然后我上下滚动,我看到项目 "byButton"(这是通过单击按钮添加的按钮的名称),这些项目位于“6”的重复项之间。过了一会儿,整个 RecycleView 重置了,我仍然有 6 个项目,就像开始时一样。我不知道我的代码有什么问题。
class ConnectDeviceUI(val listAdapter: DeviceListAdapter): AnkoComponent<ConnectBleActivity> {
lateinit var addItemButton: FloatingActionButton
override fun createView(ui: AnkoContext<ConnectBleActivity>): View = with(ui) {
return relativeLayout() {
lparams(width= matchParent, height = matchParent)
textView("List of BLE devices"){
setTextAppearance(android.R.style.TextAppearance_Material_Large)
}
addItemButton = floatingActionButton {
imageResource = android.R.drawable.ic_input_add
}.lparams{
margin = dip(10)
alignParentBottom()
alignParentEnd()
alignParentRight()
gravity = Gravity.BOTTOM or Gravity.END
}
recyclerView(){
layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, true)
lparams(width= matchParent, height = matchParent)
adapter = listAdapter
}
}
}
}
class RowLayout(): AnkoComponent<ViewGroup>{
override fun createView(ui: AnkoContext<ViewGroup>): View = with(ui) {
return linearLayout(){
lparams(width= matchParent, height = wrapContent)
setPadding(0,dip(50),0,dip(50))
textView {
id = R.id.ble_item
setTextAppearance(android.R.style.TextAppearance_Material_Large)
setPadding(0,0,dip(100),0)
}.lparams(width = wrapContent, height = wrapContent )
button{
id = R.id.ble_item_button
}.lparams(width = wrapContent, height = wrapContent)
}
}
}
class ConnectBleActivity : AppCompatActivity(), AnkoLogger {
lateinit var BleDevicesList: ArrayList<String>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
BleDevicesList = arrayListOf("1", "2","3", "4", "5", "6")
var adapter = DeviceListAdapter(BleDevicesList)
var ui = ConnectDeviceUI(adapter)
ui.setContentView(this)
ui.addItemButton.onClick {
adapter.put()
toast("New item added. Number of items: ${adapter.itemCount} ")
}
}
}
class DeviceListAdapter(var deviceList: ArrayList<String>): RecyclerView.Adapter<DeviceListHolder>(){
override fun onBindViewHolder(holder: DeviceListHolder?, position: Int) {
holder?.bindItems(deviceList[position])
}
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): DeviceListHolder {
return DeviceListHolder(RowLayout().createView(AnkoContext.create(parent!!.context, parent)))
}
override fun getItemCount(): Int {
return deviceList.size
}
fun put(){
val randomString = UUID.randomUUID().toString()
deviceList.add(deviceList.lastIndex, "byButton")
notifyItemInserted(deviceList.lastIndex)
}
fun drop(){
deviceList.removeAt(deviceList.lastIndex)
notifyItemRemoved(deviceList.lastIndex)
}
}
class DeviceListHolder(var view: View): RecyclerView.ViewHolder(view){
val name: TextView = view.find(R.id.ble_item)
val bt_name: Button = view.find(R.id.ble_item_button)
fun bindItems(listItem: String){
name.text = listItem
bt_name.text = "Test"
}
}
在修改列表本身后使用 List.lastIndex()
,导致模型和视图中的不同值被更新
deviceList.add(deviceList.lastIndex, "byButton")
notifyItemInserted(deviceList.lastIndex)
通知告诉 RecyclerView
只更新最后一项。这包含一个 "6"
而旧位置根本没有更新。要解决此问题,您必须对两者使用相同的索引。
val index = deviceList.lastIndex
deviceList.add(index, "byButton")
notifyItemInserted(index)