Home > Back-end >  Calling method from Fragment in RecyclerView Adapter - Lateinit property textView has not been initi
Calling method from Fragment in RecyclerView Adapter - Lateinit property textView has not been initi

Time:12-03

I have a list of items. When I swipe on an item, I want to update a textView in the Fragment.

I use a RecyclerView. In the Adapter, I detect when a user swipes something, and then I try to call a method in the Fragment to update a textview.

However, when I try it crashes with "LateInit Propery TextView has not been initialized". I have tried initializing the textView in the adapter instead, but I don't think that's correct and it seems impossible as findViewById doesn't really work in an adapter since the specific TextView is not on an item layout, but instead displayed in the Fragment Layout (and it needs to be that way as I don't want the textview on every single item).

My adapter (simplified)

class SwipeAdapter internal constructor(private val mCandidatesArrayList: ArrayList<SwipeCandidate>) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {

private val mSwipeFragment = SwipeFragment() //Here I initialize my fragment

fun createHelperCallback(): ItemTouchHelper.Callback {
    return object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {
        override fun onMove(
            recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder,
            target: RecyclerView.ViewHolder
        ): Boolean {
            return false
        }

        override fun onSwiped(viewHolder: RecyclerView.ViewHolder, swipeDir: Int) {
            val position = viewHolder.bindingAdapterPosition
            mSwipeFragment.updateTextView() //This throws the error
        }
      }
   }
}

}

And my Fragment (simplified):

class SwipeFragment : Fragment() {
         private lateinit var textView : TextView


         override fun onCreateView(
              inflater: LayoutInflater,
              container: ViewGroup?,
              savedInstanceState: Bundle?
              ): View {

              textView = root.findViewById(R.id.textview) //initializing textview

        }

        fun updateTextView() { 
             textView.setText("Hello") //Setting the text
        }
}

CodePudding user response:

You are trying to get view from a fragment that is not open. In our fragment, as I understand it, the adapter is initialize, you need to pass a listener into it, which will be called after the swipe.

class SwipeAdapter internal constructor(var onSwiped: (position: Int) -> Unit = { }, private val mCandidatesArrayList: ArrayList<String>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    fun createHelperCallback(): ItemTouchHelper.Callback {
        return object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {
            override fun onMove(
                    recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder,
                    target: RecyclerView.ViewHolder,
            ): Boolean {
                return false
            }

            override fun onSwiped(viewHolder: RecyclerView.ViewHolder, swipeDir: Int) {
                val position = viewHolder.bindingAdapterPosition
                onSwiped(position)
            }
        }
    }
}

fragment

class SwipeFragment : Fragment() {
    private lateinit var textView: TextView


    override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?,
    ): View {

        textView = root.findViewById(R.id.textview)

        val adapter = SwipeAdapter({ position: Int ->
            textView.setText("Hello") 
        }, arrayListOf())
    }
}
  • Related