RecyclerView 从不使用 kotlin 中的视图模型刷新



我的onBindViewHolder只在第一次被调用(当我初始化空对象时(。设置列表变量时,列表不会更新。以下是我的课程:

class BankAdapter : RecyclerView.Adapter<BankAdapter.MyHolder>() {
private var bankList: List<Bank> = ArrayList()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyHolder {
println("onCreateViewHolder")
val itemView = LayoutInflater.from(parent.context)
.inflate(R.layout.bank_list_item, parent, false)
return MyHolder(itemView)
}
override fun onBindViewHolder(holder: MyHolder, position: Int) {
println("onBindViewHolder")
val currentBank = bankList[position]
var importo: String
if (currentBank.saldo > 1000000) {
importo = "${currentBank.saldo / 1000000}M €"
} else if (currentBank.saldo > 1000) {
importo = "${currentBank.saldo / 1000}K €"
} else {
importo = "${currentBank.saldo} €"
}
holder.txt_nome_banca.text = currentBank.nome
holder.txt_indirizzo_banca.text = currentBank.indirizzo
holder.txt_iban_banca.text = currentBank.iban
holder.txt_saldo.text = importo
}
fun setBankList(bankList: List<Bank>) {
println("setBankList")
this.bankList = bankList
notifyDataSetChanged()
}
override fun getItemCount(): Int {
println("getItemCount " + bankList.size)
return bankList.size //+1 //Aggiungo un elemento per valorizzare l'item per NUOVO
}
inner class MyHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var cl_new = itemView.findViewById<ConstraintLayout>(R.id.cl_new)
var cl_item = itemView.findViewById<ConstraintLayout>(R.id.cl_item)
var txt_nome_banca = itemView.findViewById<TextView>(R.id.txt_nome_banca)
var txt_iban_banca = itemView.findViewById<TextView>(R.id.txt_iban_banca)
var txt_indirizzo_banca = itemView.findViewById<TextView>(R.id.txt_indirizzo_banca)
var txt_saldo = itemView.findViewById<TextView>(R.id.txt_saldo)
}

这是我的碎片。在我的视图模型观察器中,我在适配器中调用 setBankList 方法:

class HomeFragment : Fragment() {
private lateinit var mView: View
val bankAdapter = BankAdapter()
private lateinit var bankViewModel: BankViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
mView = inflater.inflate(R.layout.fragment_home, container, false)
val rvBank = mView.findViewById<RecyclerView>(R.id.rv_banks)
rvBank.adapter = bankAdapter
rvBank.layoutManager = LinearLayoutManager(mView.context)
bankViewModel = ViewModelProviders.of(this).get(BankViewModel::class.java)
bankViewModel.getAllBank().observe(this, Observer { t ->
bankAdapter.setBankList(t)
})
return mView
}
companion object {
@JvmStatic
fun newInstance() =
HomeFragment().apply {
}
}

}

getItemCount 方法在我设置新列表后调用。大小是正确的,但是在BindViewHolder上不叫

问题是你的数组列表正在失去引用。试试这种方式

class BankAdapter(private val  bankList: ArrayList<Bank>) : RecyclerView.Adapter<BankAdapter.MyHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyHolder {
println("onCreateViewHolder")
val itemView = LayoutInflater.from(parent.context)
.inflate(R.layout.bank_list_item, parent, false)
return MyHolder(itemView)
}
override fun onBindViewHolder(holder: MyHolder, position: Int) {
println("onBindViewHolder")
val currentBank = bankList[position]
var importo: String
if (currentBank.saldo > 1000000) {
importo = "${currentBank.saldo / 1000000}M €"
} else if (currentBank.saldo > 1000) {
importo = "${currentBank.saldo / 1000}K €"
} else {
importo = "${currentBank.saldo} €"
}
holder.txt_nome_banca.text = currentBank.nome
holder.txt_indirizzo_banca.text = currentBank.indirizzo
holder.txt_iban_banca.text = currentBank.iban
holder.txt_saldo.text = importo
}
override fun getItemCount(): Int {
println("getItemCount " + bankList.size)
return bankList.size //+1 //Aggiungo un elemento per valorizzare l'item per NUOVO
}
inner class MyHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var cl_new = itemView.findViewById<ConstraintLayout>(R.id.cl_new)
var cl_item = itemView.findViewById<ConstraintLayout>(R.id.cl_item)
var txt_nome_banca = itemView.findViewById<TextView>(R.id.txt_nome_banca)
var txt_iban_banca = itemView.findViewById<TextView>(R.id.txt_iban_banca)
var txt_indirizzo_banca = itemView.findViewById<TextView>(R.id.txt_indirizzo_banca)
var txt_saldo = itemView.findViewById<TextView>(R.id.txt_saldo)
}
}

现在在片段中用空数组列表初始化适配器,稍后填充数组列表,然后你可以调用notifyDataSetChanged()

class HomeFragment : Fragment() {
private lateinit var mView: View
private lateinit var bankAdapter : BankAdapter
private lateinit var bankViewModel: BankViewModel
private val  bankList = ArrayList<Bank>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
mView = inflater.inflate(R.layout.fragment_home, container, false)
val rvBank = mView.findViewById<RecyclerView>(R.id.rv_banks)
bankAdapter = BankAdapter(bankList)
rvBank.adapter = bankAdapter
rvBank.layoutManager = LinearLayoutManager(mView.context)
bankViewModel = ViewModelProviders.of(this).get(BankViewModel::class.java)
bankViewModel.getAllBank().observe(this, Observer { t ->
bankList.addAll(t)
bankAdapter.notifyDataSetChanged()
})
return mView
}
companion object {
@JvmStatic
fun newInstance() =
HomeFragment().apply {
}
}
}

你有几个错误:

  1. Kotlin 自动生成属性的 getter 和 setter,因此您可以删除getAllBank().
  2. 在传递对新列表的引用setBankList(bankList: List<Bank>),为了使 recyclerview 正常工作,它必须始终指向同一列表。

因此,您需要做的是:

private var bankList: ArrayList = arrayListOf<Bank>()
fun setBankList(bankList: List<Bank>) {
println("setBankList")
this.bankList.clear()
this.bankList.addAll(bankList)
notifyDataSetChanged()
}

里面RecyclerView.Adapter使用PagedListAdapter.

我认为此链接将帮助您Android回收器查看分页

最新更新