Android 向下滚动时,RecyclerView项的值重置
下面是我正在尝试做的场景:我正在创建一个RecyclerView,它可以添加或删除一个或多个子项/片段/视图,该子项/片段/视图包含EditText,但 我的问题是:每当我在我的RecyclerView中向下滚动时,它的项目值就会重置。我认为这里的问题是,RecyclerView适配器无法绑定或保存这些值,但我不知道代码中的具体问题在哪里Android 向下滚动时,RecyclerView项的值重置,android,kotlin,android-recyclerview,Android,Kotlin,Android Recyclerview,下面是我正在尝试做的场景:我正在创建一个RecyclerView,它可以添加或删除一个或多个子项/片段/视图,该子项/片段/视图包含EditText,但 我的问题是:每当我在我的RecyclerView中向下滚动时,它的项目值就会重置。我认为这里的问题是,RecyclerView适配器无法绑定或保存这些值,但我不知道代码中的具体问题在哪里 class StocksAdapter() : RecyclerView.Adapter<ViewHolder>() { class Stoc
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)
}
我已尝试禁用ViewHolder的setIsRecyclable,但问题仍然存在
防止RecyclerView停止重置值的最佳方法是什么?或者我应该用ListView替换RecyclerView吗?正如我在代码中看到的那样,您正试图在活动加载之后添加一个项目。因此,当您滚动活动时,它会再次调用onCreate活动,并且数据会再次从存储或网络中加载,因此请使用特定方法或OnActiviyt结果方法加载数据。正如我在代码中看到的,您正试图在活动加载之后添加一项。因此,当您滚动“活动”时,它会再次调用onCreate活动,并且数据会再次从存储或网络中加载,因此请使用特定方法或OnActiviyt结果方法加载数据。我通过增加recyclerview的缓存大小找到了一种解决方法。只需确保缓存大小适合您的应用程序即可 代码:
我通过增加recyclerview的缓存大小找到了一个解决方法。只需确保缓存大小适合您的应用程序即可 代码:
我不知道你的代码中什么是savedStock,或者你用它做什么。但是您的populateView方法没有按预期工作 如果仅将此savedStock用于渲染,请将其完全删除,否则,不要在populateView中使用它 在populateView中,根据获得的位置来绘制值,取决于传递的股票 您的代码应该类似于
this.buyPrice.setText(if (stock!!.buyPrice <= 0.0) "" else stock!!.buyPrice.toString())
this.numberOfShares.setText(if (stock!!.numberOfShares <= 0.0) "" else stock!!.numberOfShares.toString())
我不知道你的代码中什么是savedStock,或者你用它做什么。但是您的populateView方法没有按预期工作 如果仅将此savedStock用于渲染,请将其完全删除,否则,不要在populateView中使用它 在populateView中,根据获得的位置来绘制值,取决于传递的股票 您的代码应该类似于
this.buyPrice.setText(if (stock!!.buyPrice <= 0.0) "" else stock!!.buyPrice.toString())
this.numberOfShares.setText(if (stock!!.numberOfShares <= 0.0) "" else stock!!.numberOfShares.toString())
尝试删除ifsavedStock==null | | | stock.buyPrice>0 | | | stock.numberOfShares>0{savedStock=stock},并且只删除savedStock=stock@SahilManchanda嗨,我已经做完了。问题仍然存在:当你说它重置值时,你是什么意思?@Eminem EditText值重置为默认值0,而它们本不应该重置为默认值,因为我已经将这些值设置为“无0”。我认为这是因为RecyclerView已经销毁了最上面的项目,这就是为什么会有值被重置removig the ifsavedStock==null | | | | stock.buyPrice>0 | | | stock.numberOfShares>0{savedStock=stock}并且只有savedStock=stock@SahilManchanda嗨,我已经做完了。问题仍然存在:当你说它重置值时,你是什么意思?@Eminem EditText值重置为默认值0,而它们本不应该重置为默认值,因为我已经将这些值设置为“无0”。我认为这是因为RecyclerView已经销毁了最上面的项,这就是为什么会有重置值。嗨,我已经在片段的onCreateView中初始化了数据和recycler。我已经弄明白了为什么子项会重置,因为recycler视图在添加新项后已经回收了以前的项。我已经找到了解决方法,增加recyclerView.setItemViewCacheSizeint的大小;为确保recyclerview不会销毁以前的项目,必须在创建项目后或使用任何方法在recyclerview中添加项目,以便应用程序无法再次自动加载数据。您好,我已在片段的onCreateView中初始化了数据和回收器。我已经弄明白了为什么子项会重置,因为recycler视图在添加新项后已经回收了以前的项。我已经找到了解决方法,增加recyclerView.setItemViewCacheSizeint的大小;要确保recyclerview不会销毁以前的项目,必须在创建项目后或使用任何方法在recyclerview中添加项目,以便应用程序无法再次自动加载数据。
this.buyPrice.setText(if (stock!!.buyPrice <= 0.0) "" else stock!!.buyPrice.toString())
this.numberOfShares.setText(if (stock!!.numberOfShares <= 0.0) "" else stock!!.numberOfShares.toString())