Почему адаптер RecyclerView обновляет экземпляр списка переданных ему объектов - PullRequest
0 голосов
/ 06 мая 2020
• 1000 1. Отменить и 2. Готово, если пользователь выбирает элементы из recyclerview, которые будут переданы во фрагмент. Теперь предположим, что если у пользователя уже выбраны 2 элемента, и он открывает диалоговое окно для других и выбрал некоторые элементы, но теперь пользователь хочет отменить выбор и go назад (без отмены выбора), чтобы фрагментировать старые данные, но в настоящее время он обновляет список объекта фрагмента.

Вот код диалога.

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

Что я хочу сделать, когда пользователь нажимает кнопку отмены, даже если он выбрал больше элементов из recyclerview, а затем фрагмент recyclerview не должен обновлять элементы. он должен показывать старые предметы. но в настоящее время он обновляет элементы, даже если я не передаю их при нажатии кнопки отмены.

Вот код адаптера.

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

Это основной код адаптера, откуда я передаю данные в адаптер recyclerview диалога.

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

}

1 Ответ

0 голосов
/ 06 мая 2020

Это случается, потому что ваши fragment и recyclreview работают с одним и тем же списком объектов, который называется 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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...