I'm currently trying to implement editing items in Recyclerview on imageView click in a single Recyclerview row, but I can't figure out how to solve the reference for adapter outside of onCreateView in a fragment. How do I fix this issue and get rid of the error? What is the cause of this problem?
RecyclerviewFragment.kt:
class RecyclerviewFragment : Fragment() {
private lateinit var mUserViewModel: UserViewModel
private lateinit var viewHolder: ViewHolder
private var _binding: FragmentRecyclerviewBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
_binding = FragmentRecyclerviewBinding.inflate(inflater, container, false)
mUserViewModel = ViewModelProvider(this)[UserViewModel::class.java]
val adapter = ListAdapter{showUpdateDialog()}
val recyclerView = binding.recyclerView
recyclerView.adapter = adapter
recyclerView.layoutManager = LinearLayoutManager(requireContext())
// Creates a controller responsible for swiping and moving the views in recyclerview
val itemTouchController = ItemTouchHelper(
object : ItemTouchHelper.SimpleCallback(
ItemTouchHelper.UP or ItemTouchHelper.DOWN, ItemTouchHelper.LEFT
) {
override fun onMove(
recyclerView: RecyclerView,
viewHolder: ViewHolder, target: ViewHolder,
): Boolean {
// Move specific item from "fromPos" to "toPos" in recyclerview adapter
val fromPos = viewHolder.bindingAdapterPosition
val toPos = target.bindingAdapterPosition
adapter.notifyItemMoved(fromPos, toPos)
return true // true if moved, false otherwise
}
override fun onSwiped(viewHolder: ViewHolder, direction: Int) {
mUserViewModel.deleteUser(adapter.getTaskPosition(viewHolder.bindingAdapterPosition))
Toast.makeText(context, "Task deleted", Toast.LENGTH_SHORT).show()
adapter.notifyItemRemoved(viewHolder.bindingAdapterPosition)
}
})
itemTouchController.attachToRecyclerView(binding.recyclerView)
mUserViewModel.readAllData.observe(viewLifecycleOwner) { user ->
adapter.setData(user)
}
return binding.root
}
private fun updateItemInDatabase(dialog: DialogInterface) {
val editText = (dialog as AlertDialog).findViewById<EditText>(R.id.editTextDialog)
val task = editText?.text.toString()
if(inputCheck(task)) {
// Update an entity
mUserViewModel.updateUser(adapter.getTaskPosition(viewHolder.bindingAdapterPosition))
Toast.makeText(context, "Task updated", Toast.LENGTH_SHORT).show()
}
else {
Toast.makeText(context, "Please fill out required fields", Toast.LENGTH_SHORT).show()
}
}
private fun inputCheck(task: String): Boolean {
return !(TextUtils.isEmpty(task))
}
private fun showUpdateDialog() {
MaterialAlertDialogBuilder(requireContext())
.setView(R.layout.fragment_add)
.setNegativeButton(getString(R.string.cancel)) { _, _ ->
// Respond to negative button press
Toast.makeText(context, getString(R.string.cancelled), Toast.LENGTH_SHORT).show()
}
.setPositiveButton(getString(R.string.ok)) { dialogInterface, _ ->
// Respond to positive button press
updateItemInDatabase(dialogInterface)
}
.show()
}
}
Do you require a global reference to your adapter? Where exactly do you want to use the adapter? If thats the case then declare your adapter above onCreateView
as
private lateinit var adapter
then on your onCreateView
initialise the adapter as
adapter = ListAdapter{showUpdateDialog()}
You can then use the adapter reference anywhere you want on that class