向下滚动时,RecyclerView Items的值将重置 [英] RecyclerView Items' values reset when scrolling down

查看:72
本文介绍了向下滚动时,RecyclerView Items的值将重置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我要执行的操作:我正在创建一个RecyclerView,它可以添加或删除一个或多个具有EditText但...的子项/片段/视图.

Here is the scenario of what I am trying to do: I am creating a RecyclerView that can add or remove one or more child item/fragment/view that has EditText(s) but....

这是我的问题:每当我在RecyclerView中向下滚动时,其项目的值都会重置.我认为这里的问题是RecyclerView Adapter无法绑定或保存值,但是我不知道代码中的问题到底出在哪里.

Here is my problem: Whenever I scroll down in my RecyclerView, its items' value resets. I think the problem here is that the RecyclerView Adapter cannot bind or hold the values but I don't know where exactly is the problem in my code.

class StocksAdapter() : RecyclerView.Adapter<ViewHolder>() {


class StockFragmentHolder : ViewHolder {
    fun Double.format(digits: Int) = java.lang.String.format("%,.${digits}f", this)


    lateinit var numberOfShares: EditText;
    lateinit var buyPrice: EditText;
    lateinit var btnCompute: Button
    lateinit var btnRemove: Button
    lateinit var stockAveragePrice: TextView
    lateinit var stockTotalAmount: TextView
    private var savedStock : Stock? = null

    constructor(view: View) : super(view) {
        numberOfShares = view.findViewById(R.id.stockNumberOfShares)
        buyPrice = view.findViewById(R.id.stockBuyPrice)
        btnCompute = view.findViewById(R.id.btnCompute)
        btnRemove = view.findViewById(R.id.btnRemove)
        stockAveragePrice = view.findViewById(R.id.stockAveragePrice)
        stockTotalAmount = view.findViewById(R.id.stockTotalAmount)
    }


    fun populateView(stock: Stock, onStocksAdapterListener: OnStocksAdapterListener, position: Int) {

        if(savedStock == null || stock.buyPrice > 0 || stock.numberOfShares > 0) {
            savedStock = stock
        }

        this.buyPrice.setText(if (savedStock!!.buyPrice <= 0.0) "" else savedStock!!.buyPrice.toString())
        this.numberOfShares.setText(if (savedStock!!.numberOfShares <= 0.0) "" else savedStock!!.numberOfShares.toString())
        this.stockAveragePrice.text = "0"
        this.stockTotalAmount.text = "0"

        this.btnCompute.setOnClickListener(View.OnClickListener {

            var stock = Stock();

            stock.numberOfShares = this.numberOfShares.text.toString().toLongOrNull()
            stock.buyPrice = this.buyPrice?.text.toString().toDoubleOrNull()
            stock.sellPrice = 0.0


            if (stock.numberOfShares != null || stock.numberOfShares != 0L) {

                var buyTotalAmount: Double = 0.0;
                buyTotalAmount = StocksCalculator.calculateTotalSharesPrice(stock, StocksCalculator.TRANSACTION_FEE_BASE_VALUES, Constants.TRANSACTION_TYPE.TRANSACTION_TYPE_BUY)

                var averagePricePerShare = (buyTotalAmount / stock.numberOfShares)

                this.stockAveragePrice.text = averagePricePerShare.format(2);
                this.stockTotalAmount.text = "" + buyTotalAmount.format(2)

                onStocksAdapterListener.onStocksComputeButtonClicked(stock.numberOfShares, averagePricePerShare, buyTotalAmount, position)
            }
        })

        this.btnRemove.setOnClickListener(View.OnClickListener {
            onStocksAdapterListener.onStocksRemoveButtonClicked(position)
        })

    }
}


lateinit var onStocksAdapterListener: OnStocksAdapterListener;
lateinit var listStocks: ArrayList<Stock>

public constructor(listStocks: ArrayList<Stock>, onStocksAdapterListener: OnStocksAdapterListener) : this() {
    this.listStocks = listStocks
    this.onStocksAdapterListener = onStocksAdapterListener
    setHasStableIds(true)

}

override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): RecyclerView.ViewHolder {
    var itemView = LayoutInflater.from(parent?.getContext())
            .inflate(R.layout.fragment_stock, parent, false)
}

override fun getItemViewType(position: Int): Int {
    return position
}


override fun getItemCount(): Int {
    return listStocks.size
}

override fun onBindViewHolder(holder: RecyclerView.ViewHolder?, position: Int) {
    var stock: Stock = listStocks.get(position)
    holder.populateView(stock, this.onStocksAdapterListener, position)
}


public interface OnStocksAdapterListener {
    public fun onStocksAddButtonClicked()

    public fun onStocksComputeButtonClicked(numberOfShares: Long?, averagePricePerShare: Double?, averageTotalAmount: Double?, position: Int)

    public fun onStocksRemoveButtonClicked(position: Int)
}

这是我在片段中创建recyclerView的方法:

Here is how I create my recyclerView in my Fragment:

    val mLayoutManager = LinearLayoutManager(this.context)
    var recyclerView: RecyclerView = view.findViewById(R.id.recyclerView)

    val itemDecorator = DividerItemDecoration(context, DividerItemDecoration.VERTICAL)
    itemDecorator.setDrawable(ContextCompat.getDrawable(context, R.drawable.divider))
    recyclerView.addItemDecoration(itemDecorator)
    recyclerView.setLayoutManager(mLayoutManager)
    recyclerView.setItemAnimator(DefaultItemAnimator())
    recyclerView.adapter = stocksAdapter

我尝试禁用ViewHolder的setIsRecyclable,但问题仍然存在.

I have tried disabling the setIsRecyclable of the ViewHolder but the problem still persists.

防止RecyclerView停止重置值的最佳方法是什么?还是应该将RecyclerView替换为ListView?

What is the best approach to prevent the RecyclerView to stop resetting the values? Or should I replace the RecyclerView with ListView?

推荐答案

我找到了一种解决方法,方法是增加recyclerview的缓存大小.只需确保缓存大小足以满足您的应用程序需求即可.

I found a workaround by increasing the cache size of the recyclerview. Just ensure that the cache size is good enough for your application.

代码:

recyclerView.setItemViewCacheSize(int);

这篇关于向下滚动时,RecyclerView Items的值将重置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆