I have two fragments: (1) Library Fragment, (2) Book Fragment
The library fragments displays all available books via a RecyclerView. The user can tab on each of the RecyclerView Items, which will set the LiveData to the corresponding book. At the same time the Book Fragment will be opened and the contents of that book will be shown.
I set up an onClickListener in the ViewHolder class inside the RecyclerView.Adapter of the Library Fragment. So, when an item is clicked, the livedata is being set and then navigated to the Book fragment via Navigation Component. The Book Fragment has an observer on the Live Data and shows it.
As you can see in the following code, I am passing viewmodel instance to the adapter, which is not correct....? Or is it? How should this be done?
Library Fragment Code Snippet
class LibraryFragment : Fragment() {
[...]
private val model: SharedViewModel by activityViewModels()
private lateinit var gridlayoutManager: GridLayoutManager
private lateinit var thumbnailAdapter: ThumbnailAdapter
private lateinit var thumbnailRecyclerView: RecyclerView
private lateinit var selectedFolder: Uri
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = layoutInflater.inflate(R.layout.fragment_thumbnail_viewer, container, false)
initRecyclerView(view)
view.allFolderPicker.setOnClickListener {
pickFolder()
}
view.switchFragment.setOnClickListener {
findNavController().navigate(R.id.action_allFoldersFragment_to_oneFolderFragment)
}
return view
}
private fun initRecyclerView(view: View) {
thumbnailRecyclerView = view.findViewById(R.id.thumbnail_recycler_view)
gridlayoutManager =
GridLayoutManager(requireContext(), 3, LinearLayoutManager.VERTICAL, false)
thumbnailRecyclerView.layoutManager = gridlayoutManager
thumbnailAdapter = ThumbnailAdapter(model)
thumbnailAdapter.setThumbnailList(listOf())
thumbnailRecyclerView.adapter = thumbnailAdapter
}
[...]
}
Adapter Class Code Snippet
class ThumbnailAdapter(model: SharedViewModel) :
RecyclerView.Adapter<ThumbnailAdapter.CustomViewHolder>() {
private var thumbnailList = listOf<Pair<String, File>>()
private val myModel = model
inner class CustomViewHolder(view: View) : RecyclerView.ViewHolder(view) {
private val thumbnail = view.thumbnail
private val title = view.title
fun bind(item: Pair<String, File>) {
val titleToSet = item.first
val bitmapToSet = Util.uriToBitmap(item.second)
val resizedBitmapToSet = Bitmap.createScaledBitmap(bitmapToSet, 150, 150, false)
thumbnail.setImageBitmap(resizedBitmapToSet)
title.text = titleToSet
itemView.setOnClickListener {
val folderWithImages = thumbnailList[adapterPosition].second.parentFile
folderWithImages?.let {
myModel.setLibraryFolderList(it)
itemView.findNavController()
.navigate(R.id.action_allFoldersFragment_to_oneFolderFragment)
}
}
}
}
[...]
}
Book Fragment Code Snippet
[...]
class BookViewFragment : Fragment() {
private lateinit var viewPager: ViewPager2
private lateinit var viewPagerAdapter: ViewPager2Adapter
private val model: SharedViewModel by activityViewModels()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_image_viewer, container, false)
initRecyclerView(view)
return view
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
model.selectedBookFile.observe(viewLifecycleOwner, androidx.lifecycle.Observer {
viewPagerAdapter.setImageList(getImageList(it))
viewPagerAdapter.notifyDataSetChanged()
})
}
private fun initRecyclerView(view: View) {
viewPager = view.findViewById(R.id.main_image)
viewPagerAdapter = ViewPager2Adapter()
viewPagerAdapter.setImageList(listOf())
viewPager.adapter = viewPagerAdapter
}
[...]
}