为什么RecyclerView适配器会更新传递给它的对象列表的实例?

问题描述 投票:0回答:1

我有一个问题 recyclerview.adapter 我正在做的是将一个对象列表传给一个对话框,该对话框有一个回收视图和两个按钮,1.Cancel和2.Done如果用户从回收视图中选择了项目,将传给片段。Done如果用户从回收视图中选择了一些项目,这些项目将被传递给片段。现在假设用户已经选择了2个项目,并打开对话框选择了更多的项目,但现在用户想取消选择,并返回(在不取消选择的情况下)使用旧的数据到片段,但目前它正在更新片段的对象列表。

下面是对话框的代码。

fun showChooserDialog(
    baseActivity: AppCompatActivity,
    typeCode: Int,
    dataList: ArrayList<PrefsStateModel>
) {
    var alertDialog: AlertDialog? = null
    val dialogBuilder =
        AlertDialog.Builder(baseActivity, R.style.CustomDialog)
    dialogBuilder.setCancelable(true)
    val inflater = LayoutInflater.from(baseActivity)
    val dialogView: View = inflater.inflate(R.layout.view_select_prefs, null)
    dialogBuilder.setView(dialogView)
    val btnCancel = dialogView.findViewById<MaterialButton>(R.id.btnCancel)
    val btnDone = dialogView.findViewById<MaterialButton>(R.id.btnDone)
    val recyclerView = dialogView.findViewById<RecyclerView>(R.id.listViewPrefs)
    recyclerView.setHasFixedSize(true)
    val layoutManager = LinearLayoutManager(baseActivity)
    recyclerView.layoutManager = layoutManager
    val adapter =
        SelectPrefAdapter(
            baseActivity,
            dataList
        )
    recyclerView.adapter = adapter
    btnCancel.setOnClickListener {
        preferenceView.onUserNotSelected()
        alertDialog?.dismiss()
    }
    btnDone.setOnClickListener {
        val data = adapter.getList()
        preferenceView.onUserSelectedPrefDone(data, typeCode)
        alertDialog?.dismiss()
    }

    alertDialog = dialogBuilder.create()
    alertDialog.window?.setLayout(600, 400)
    alertDialog.show()
}

我想做的是,当用户点击取消按钮时,即使他从回收视图中选择了更多的项目,那么片段的回收视图不应该更新项目,它必须显示旧的项目,但目前它正在更新项目,即使我点击取消按钮时没有通过。

这里是适配器的代码。

class SelectPrefAdapter(var context: Context, var dataList: ArrayList<PrefsStateModel>) :
RecyclerView.Adapter<SelectPrefAdapter.UserViewHolder>() {

override fun onCreateViewHolder(parent: ViewGroup, p1: Int) =
    UserViewHolder(
        LayoutInflater.from(parent.context).inflate(R.layout.view_pref_adapter, parent, false)
    )

override fun getItemCount() = dataList.size

override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
    var prefsState = dataList[position]
    holder.lable.text = prefsState.name

    if (prefsState.isSelected) {
        holder.lable.setTextColor(context.resources.getColor(R.color.colorPrimary))
        holder.icon.visibility = View.VISIBLE
    } else {
        holder.lable.setTextColor(context.resources.getColor(R.color.colorGreyShade2))
        holder.icon.visibility = View.INVISIBLE
    }

    holder.lable.setOnClickListener {
        if (prefsState.isSelected) {
            prefsState.isSelected = false
            holder.lable.setTextColor(context.resources.getColor(R.color.colorPrimary))
            holder.icon.visibility = View.VISIBLE

        } else {
            prefsState.isSelected = true
            holder.lable.setTextColor(context.resources.getColor(R.color.colorGreyShade2))
            holder.icon.visibility = View.INVISIBLE
        }
        notifyDataSetChanged()
    }
}

class UserViewHolder(view: View) : RecyclerView.ViewHolder(view) {
    val icon = view.imageViewIcon
    val lable = view.textviewPrefName
}


fun getList(): ArrayList<PrefsStateModel> {
    return dataList
}
}

这是主适配器代码,我从这里把数据传给对话框的回收视图适配器。

class ProfilePrefAdapter(
var context: Context,
var dataListPref: ArrayList<PrefsStateModel>,
var onPrefSelection: OnPrefSelection
) :
RecyclerView.Adapter<ProfilePrefAdapter.PrefViewHolder>() {

override fun onCreateViewHolder(parent: ViewGroup, p1: Int) = PrefViewHolder(
    LayoutInflater.from(parent.context).inflate(R.layout.view_pref, parent, false)
)

override fun getItemCount() = dataListPref.size

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

override fun onBindViewHolder(holder: PrefViewHolder, position: Int) {
    val prefs = dataListPref[position]
    holder.chipView.text = prefs.name
    if (prefs.isSelected) {
        holder.chipView.setBackgroundResource(R.drawable.rounded_border_selected)
        holder.chipView.setTextColor(context.resources.getColor(R.color.colorWhite))
    } else {
        holder.chipView.setBackgroundResource(R.drawable.rounded_border_unselected)
        holder.chipView.setTextColor(context.resources.getColor(R.color.colorGreyShade1))
    }
    if (position == dataListPref.size - 1) {
        onPrefSelection.onPrefSelection(getSelected())
    }

    holder.chipView.setOnClickListener {
        if (prefs.isSelected) {
            prefs.isSelected = false
            holder.chipView.setBackgroundResource(R.drawable.rounded_border_unselected)
            holder.chipView.setTextColor(context.resources.getColor(R.color.colorGreyShade1))
        } else {
            prefs.isSelected = true
            holder.chipView.setBackgroundResource(R.drawable.rounded_border_selected)
            holder.chipView.setTextColor(context.resources.getColor(R.color.colorWhite))
        }
        notifyDataSetChanged()
        onPrefSelection.onPrefSelection(getSelected())
    }
}

class PrefViewHolder(view: View) : RecyclerView.ViewHolder(view) {
    val chipView = view.textViewPref
}

fun setList(data: ArrayList<PrefsStateModel>) {
    clearData()
    dataListPref.addAll(data)
    notifyDataSetChanged()
}

private fun clearData() {
    dataListPref.clear()
}

fun getData(): List<PrefsStateModel> {
    return dataListPref.toMutableList()
}

private fun getSelected(): Int {
    var count = 0
    for (data in dataListPref) {
        if (data.isSelected) {
            count++
        }
    }
    return count
}

}

这是我获取数据并传递给对话框的地方。

private fun showDialog(type: Int) {
    var dataToPasses: ArrayList<PrefsStateModel>? = ArrayList()
    when (type) {
        1 -> {
            dataToPasses?.clear()
            dataToPasses?.addAll(adapterGener!!.getData())
        }
        2 -> {
            dataToPasses?.clear()
            dataToPasses?.addAll(adapterContent!!.getData())
        }
        3 -> {
            dataToPasses?.clear()
            dataToPasses?.addAll(adapterLanuage!!.getData())
        }

    }
    utils.showLog(TAG, "data to be sent to dialog $dataToPasses and $generPrefList")
    preferencePresenter.showChooserDialog(baseActivity, type, dataToPasses!!)

}
android android-recyclerview android-alertdialog recycler-adapter
1个回答
0
投票

出现这种情况是因为你的 fragmentrecyclreview 在同一个对象列表上工作,它被称为 shallow copy为了解决这个问题,你需要创建深层拷贝并将其传递给适配器。

例子

ArrayList<PrefsStateModel> newList = new ArrayList<PrefsStateModel>();

    for(PrefsStateModel p : oldList) {
        newList.add(p.clone());
    }


public class PrefsStateModel{

    String s;
    Date d;
    ...

    public PrefsStateModel clone(){
        PrefsStateModel p = new PrefsStateModel();
        p.s = this.s.clone();
        p.d = this.d.clone();
        ...
        return p;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.