I am working on a very simple implementation of a RecyclerView that displays data stored in a ViewModel. I am still very new to Android development and am trying to learn the fundamentals. In this situation, all the data to be stored in the ViewModel is stored in a simple list, later on I want to use Room to do this but right now I am struggling to get things working. Currently adding an item to the list only adds that item to the private member (_mainList) of the ViewModel, the public member (mainList) is unchanged, and this is the member passed into the adapter constructor call.
ViewModel:
class ListViewModel : ViewModel() { private val _mainList = mutableListOf<String>() val mainList = _mainList.toList() fun addMainListItem(item: String) { _mainList.add(item) } } Adapter:
class MainAdapter(private var list: List<String>) : RecyclerView.Adapter<MainAdapter.ViewHolder>() { class ViewHolder(view: View) : RecyclerView.ViewHolder(view) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val view = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false) return ViewHolder(view) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { holder.itemView.list_item_text.text = list[position] } override fun getItemCount(): Int { return list.size } } Fragment that displays the list:
class MainListFragment : Fragment() { private val viewModel: ListViewModel by activityViewModels() private var _binding: FragmentMainListBinding? = null private val binding get() = _binding!! lateinit var adapter: MainAdapter override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { _binding = FragmentMainListBinding.inflate(inflater, container, false) val root: View = binding.root return root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // Add click listener to floating action button binding.fabMain.setOnClickListener { addListItem() } adapter = MainAdapter(viewModel.mainList) main_list_view.adapter = adapter main_list_view.layoutManager = LinearLayoutManager(requireContext()) } private fun addListItem() { val input = EditText(activity) input.setHint("Enter the name of your new list item") input.inputType = InputType.TYPE_CLASS_TEXT activity?.let { val builder = AlertDialog.Builder(activity) builder.apply { setTitle("Add List Item") setView(input) setPositiveButton( "Add" ) { dialog, id -> val newItem = input.text.toString() viewModel.addMainListItem(newItem) adapter.notifyDataSetChanged() } setNegativeButton("Cancel" ) { dialog, id -> dialog.cancel() } } builder.create() builder.show() } } }
mainListmListonce. But when you add items to_mList, themListstill references to the old items.