Spectator
Spectator

Reputation: 332

How can i pass ViewModel into Adapter?

I have a reminders app with using room. And i have a recycler view which contains all reminders by getting them from room db. In each element exist the planning date of ending reminder. I am want to check for overdue date when elements starting to setting up to them position. But i'm has only one idea how to do this.

I think im need to check for overdue date in adapter, and then in adapter call the view model and send data into db. But, i cannot pass the view model into adapter. Anyway im read some topics and they said about bad experience of passing adapter in view model.

Any ideas?

Here is my adapter class

class MainPageAdapter : RecyclerView.Adapter<MainPageAdapter.MyViewHolder>() {

    private var remList = emptyList<ReminderModel>()
    private lateinit var reminder : OverdueReminderModel

    class MyViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView) {}

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        return MyViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.main_page_reminders_row, parent, false))
    }

    @SuppressLint("SetTextI18n")
    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        val list = remList[position]

        val sdf = SimpleDateFormat("dd.M.yyyy")

        holder.itemView.idForDelete.text = list.id.toString()
        holder.itemView.rowHeader.text = list.header
        holder.itemView.goneDescription.text = list.description
        holder.itemView.rowStartTime.text = list.startTime
        holder.itemView.rowEndTime.text = sdf.format(list.endTime.toLong())

        //redirect with safe args to show reminder
        holder.itemView.rowOfMainPageItems.setOnClickListener {
            val action = MainPageRemindersDirections.actionMainPageRemindersToShowFullReminder(list)
            holder.itemView.findNavController().navigate(action)
        }

        val currentDate = Calendar.getInstance().timeInMillis.toString()

        if(currentDate.toLong() > getDateInMills(holder.itemView.rowEndTime.text.toString())){
            reminder = OverdueReminderModel(
                0,
                holder.itemView.rowHeader.text.toString(),
                holder.itemView.goneDescription.text.toString(),
                getDateInMills(holder.itemView.rowEndTime.text.toString()).toString()
            )
        }
//there are two methods which i want to use for sending and deleting data
        /*
        TODO:
            overdueViewModel.addOverdueReminder(reminder)
            deleteReminderFromDatabase(Integer.parseInt(viewHolder.itemView.idForDelete.text.toString()))
         */
    }

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

    @SuppressLint("NotifyDataSetChanged")
    fun setData(reminder : List<ReminderModel>){
        this.remList = reminder
        notifyDataSetChanged()
    }


    @SuppressLint("SimpleDateFormat")
    fun getDateInMills(date : String) : Long{
        val sdf = SimpleDateFormat("dd.M.yyyy")
        val dateParse = sdf.parse(date)
        val dateInMills = dateParse.time
        return dateInMills
    }
}

That's how im send data in adapter

        private lateinit var viewModel : ReminderViewModel


        viewModel = ViewModelProvider(this).get(ReminderViewModel::class.java)


        viewModel.readAllReminders.observe(viewLifecycleOwner, Observer {
            adapter.setData(it)
        })

Upvotes: 0

Views: 2124

Answers (1)

Gouse Mohiddin
Gouse Mohiddin

Reputation: 424

You can simply make use of Kotlin lambda functions,

Add these functions and properties in your Adapter Class

private lateinit var overdueCallback : (item: ReminderModel) -> Unit

fun overdueListener(callback: (item: ReminderModel) -> Unit){
    overdueCallback = callback
}

Call the function in ViewModel as follows, to handle the item.

adapter.overdueListener{
       //it: Reminder Model
       // Code to handle the item from adapter
}

When you want to pass item to ViewModel, Then call

overdueCallback(reminderItem)

Upvotes: 2

Related Questions