RecyclerView永远不会在Kotlin中使用ViewModel刷新

时间:2019-09-16 13:59:21

标签: android kotlin android-recyclerview adapter viewmodel

我的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)
}

这是我的片段。在我的viewModel观察器中,我在适配器内调用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方法。大小是正确的,但是onBindViewHolder不被称为

3 个答案:

答案 0 :(得分:0)

RecyclerView.Adapter内部使用PagedListAdapter

我认为此链接将帮助您Android RecyclerView Pagination

答案 1 :(得分:0)

您有几个错误:

  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()
}

答案 2 :(得分:0)

问题是您的数组列表丢失了参考。尝试这种方式

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)
        }
    }

现在在Fragment中使用空的arraylist初始化适配器,然后填充arraylist,然后可以调用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 {
            }
    }
}