
[英]Can we give registerforcontextmenu and onclicklistener for a same Textview
[英]can we change textview being on same fragment?
我正在开发一个演示应用程序,每当我在回收器视图的同一项目中更改 edittext 的值时,我都必须更新 recyclerview 中项目的 texview。 以下是我的 rcv 适配器。
class RecyclerViewAdapterU (val dataList:ArrayList<ModelClass>): RecyclerView.Adapter<RecyclerViewAdapterU.ViewHolder>() {
var _binding: UploadItemViewBinding? = null
val binding get() = _binding!!
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): RecyclerViewAdapterU.ViewHolder {
val v =
LayoutInflater.from(parent.context).inflate(R.layout.upload_item_view, parent, false)
_binding = UploadItemViewBinding.bind(v)
return ViewHolder(binding.root)
}
override fun onBindViewHolder(holder: ViewHolder, @SuppressLint("RecyclerView") position: Int) {
bindItems(dataList[position])
holder.getStock()
holder.updateStockDetail()
}
fun bindItems(data: ModelClass) {
binding.itemquant.text = data.item_quant
binding.uploadItemName.text = data.item_name
binding.uploadMfg.text = data.mfg
binding.skuStock.setText(data.item_stock.toString())
binding.skuCode.setText(data.sku_code)
}
override fun getItemCount(): Int {
return dataList.size
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var stockdetail = ArrayList<ModelClass>()
fun getStock() {
binding.skuStock.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
override fun afterTextChanged(editable: Editable) {
for (i in 0 until RecyclerViewAdapter.ob.dataSelected.size){
if (editable.toString().trim()!=""){
var x= editable.toString().trim().toInt()
RecyclerViewAdapter.ob.dataSelected[adapterPosition].item_stock=x
}
}
}
})
}
fun updateStockDetail(){
binding.skuCode.addTextChangedListener(object : TextWatcher{
override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {
}
override fun afterTextChanged(editable: Editable) {
if (editable.length==3){
var x:String
for (i in 0 until RecyclerViewAdapter.ob.dataSelected.size){
if (editable.toString().trim()!=""){
x=editable.toString().trim()
RecyclerViewAdapter.ob.dataSelected[adapterPosition].sku_code=x
println("$x in if")
}
}
println(RecyclerViewAdapter.ob.dataSelected[adapterPosition].sku_code)
getUpdatedDetails(RecyclerViewAdapter.ob.dataSelected[adapterPosition].sku_code)
for (i in stockdetail){
bindItems(i)
//binding.uploadItemName.text=i.item_name
println(i.item_name)
}
}
}
})
}
fun getUpdatedDetails(skucode:String){
val call: Call<List<ModelClass>>? =
ApiClient.instance?.myApi?.getfromsku(skucode)!!
call!!.enqueue(object : Callback<List<ModelClass>?> {
override fun onResponse(
call: Call<List<ModelClass>?>,
response: Response<List<ModelClass>?>
) {
val skuDetails=response.body()
stockdetail.clear()
if (skuDetails != null) {
for (i in skuDetails){
println(i.item_name)
stockdetail.addAll(skuDetails)
}
}
}
override fun onFailure(call: Call<List<ModelClass>?>, t: Throwable) {
}
})
}
}
}
查看 updatestockdetail function。 不确定我是否以正确的方式做事..如果不正确,有人可以帮助我以正确的方式做事吗?
问题的详细解释。 此图像 B20 中的屏幕截图是 Bingo20gm 的 sku 代码。 同样,L20 用于 Lays20gm,所以如果我将 B20 更改为 L20,则显示 Bingo 20gm 的 textview 应更改为 Lays 20gm。 数据由 API 提供,我在 getupdateddetails() 中调用它,并将它们放在一个列表中。
这更像是一个代码审查问题,但我认为你过于复杂了。
当您使用RecyclerView
(或任何列表小部件)时,您有三个部分:
RecyclerView
)Adapter
) 在RecyclerView
中,数据显示在称为ViewHolder
的迷你布局中。 不是为每个项目创建一个,而是创建一个池,当ViewHolder
滚动出视图时,它会被回收(重用)以显示新项目 - 这就是为什么它被称为RecyclerView
(而不是ListView
)
因此,每个ViewHolder
都是可以显示项目详细信息的东西,当onBindViewHolder
时,适配器会确定如何使用视图持有者来表示您的数据- 例如设置文本、图像、颜色、检查状态等。你还可以在ViewHolder
中粘贴一些变量并在绑定期间设置这些变量,因此您可以获得有关当前显示内容的更多信息 - 设置position
变量很常见。 这样,您可以将一些代码放入ViewHolder
中,以处理它当前表示的数据。
关键是,您可以使ViewHolder
这个独立的组件:
EditText
和一个TextView
EditText
上设置TextWatcher
EditText
内容更改时更新TextView
这都是ViewHolder
内部的,它只是在自己的布局中连接组件
如果您需要ViewHolder
推送一些信息(例如您输入的文本或“单击按钮”事件),您可能希望在您的适配器中放置一个 function 以便它可以调用:
fun updateThing(data: String, position: Int) {
// update your data sources, do any validation, etc
// call notifyDataSetChanged() or similar, if required
}
如果您的 ViewHolder 中有一个position
变量(您在ViewHolder
期间onBindViewHolder
),那么 VH 只需在调用 function 时传递它。 嘿,这是更新,我正在显示 position X,这是新数据。 那样的话,VH 只关心 UI 的东西,所有的数据逻辑都在适配器中保持独立——这可以做一些事情,比如决定列表是否需要更新。
这样做的另一个原因是适配器也处理来自其他来源的更新,例如您的 API 调用。 所以如果你所有的数据更新逻辑都在一个地方,由一件事处理,那就容易多了。 这样,无论更新的来源是什么,无论出于何种原因需要更新,都以相同的方式完成。 如果适配器决定数据已更改,并且显示需要更新,则通过正常方法发生 - 即onBindViewHolder
被调用,您在RecyclerView
上设置当前数据。 所以你可以得到这个事件链:
ViewHolder
更新上的EditText
TextWatcher
代码使用新数据调用适配器的updateThing
functiononBindViewHolder
被调用并显示(现在更改的)数据ViewHolder
的TextView
设置为显示新数据所以在这种情况下,您根本不需要直接修改TextView
,您只需更新数据,作为该过程的一部分,新数据就会显示出来。 因为这就是数据更改时应该发生的事情,无论是什么导致它发生变化。 而且您无需担心是什么原因造成的,您只需显示它!
这是一个很长的答案,我显然没有重写你的代码,但希望它能让你更好地了解它是如何工作的,以及如何分离和简化它们。 您的ViewHolder
中有很多代码可以操作数据、在适配器上四处寻找、迭代其中的所有项目等 - 它实际上应该只显示内容并对 UI 事件做出反应。 处理数据是适配器的工作
我尝试重新使用您的代码,但有些事情没有意义,例如RecyclerViewAdapter.ob.dataSelected
。 你从哪里得到RecyclerViewAdapter
实例?
因此,我在下面粘贴了一段我之前编写的适配器代码,它可以解决与您需要的完全相同的目的。
class RecyclerViewAdapter(
val interactionListener: InteractionListener,
val onTextChangedListener: OnTextChangedListener
) : RecyclerView.Adapter<RecyclerViewAdapter.OptionViewHolder>() {
private val variantsList = ArrayList<VariantsItem>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OptionViewHolder {
val binding = SellVariantRowItemBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
return OptionViewHolder(binding)
}
override fun onBindViewHolder(holder: OptionViewHolder, position: Int) {
holder.bind(variantsList[position])
}
override fun getItemCount() = variantsList.size
fun updateVariantsList(newList: ArrayList<VariantsItem>) {
variantsList.clear()
variantsList.addAll(newList)
notifyDataSetChanged()
}
inner class OptionViewHolder(
private val binding: SellVariantRowItemBinding
) : RecyclerView.ViewHolder(binding.root) {
private var subVariant: String = ""
@SuppressLint("SetTextI18n")
fun bind(variantsItem: VariantsItem) {
subVariant = variantsItem.subVariant
binding.apply {
binding.root.tag = "pos_$bindingAdapterPosition"
sizeTv.text = "Size (${bindingAdapterPosition+1})"
variantValue.text = variantsItem.variant
subVariantValue.text = variantsItem.subVariant
quantityET.setText(variantsItem.quantity.toString().takeIf { it != "0" }?:"1")
sellingPriceET.setText(variantsItem.listingPrice.toString())
marketPriceET.setText(variantsItem.labelPrice.toString())
setOnClickListeners(variantsItem)
setTextChangeListeners(variantsItem)
}
}
private fun setTextChangeListeners(item: VariantsItem) {
binding.apply {
quantityET.addTextChangedListener {
if (it.toString().toIntOrNull() != null) {
onTextChangedListener.onQuantityChanged(
bindingAdapterPosition,
item.subVariant, item.variant,
it.toString()
)
}
}
marketPriceET.addTextChangedListener {
if (it.toString().toIntOrNull() != null) {
onTextChangedListener.onMarketPriceChanged(
bindingAdapterPosition,
item.subVariant,item.variant,
it.toString()
)
}
}
sellingPriceET.addTextChangedListener {
if (it.toString().toIntOrNull() != null){
onTextChangedListener.onSellingPriceChanged(
bindingAdapterPosition,
item.subVariant,item.variant,
it.toString()
)
}
}
}
}
private fun setOnClickListeners(variantsItem: VariantsItem) {
binding.apply {
deleteVariantBtn.setSafeOnClickListener {
interactionListener.onDeleteCard(variantsItem)
}
subVariantLayout.setSafeOnClickListener {
interactionListener.onChangeSubVariant(variantsItem)
}
variantLayout.setSafeOnClickListener {
interactionListener.onChangeVariant(variantsItem)
}
addNewVariant.setSafeOnClickListener {
it.pan()
interactionListener.onAddVariant(variantsItem.subVariant)
}
}
}
}
interface InteractionListener{
fun onChangeSubVariant(subToBeDeleted: VariantsItem)
fun onChangeVariant(variant: VariantsItem)
fun onDeleteCard(variant: VariantsItem)
fun onAddVariant(subVariantValue: String)
}
interface OnTextChangedListener{
fun onQuantityChanged(position: Int, subVariant: String, variant: String, quantity: String)
fun onMarketPriceChanged(position: Int, subVariant: String, variant: String, price: String)
fun onSellingPriceChanged(position: Int, subVariant: String, variant: String, price: String)
}
}
有几点需要注意:
binding
实例来处理回收站视图的所有项目。 为此,我们有ViewHolder
。val variantsAdapter = RecyclerViewAdapter(this, this)
。 这将允许您在 Recycler View 适配器之外编写业务逻辑(包括上下文所需的语句,例如调用不同的活动或启动服务,或者在您的情况下,进行 API 调用)如果您有任何问题,请随时与我们联系。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.