I'm learning Jetpack by changing the Demo from codelabs.
What I changed is move the code of the MainActivity.kt
into a fragment and jump between fragments.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
replaceFragment(WordListFragment())
}
}
// Extension function to replace fragment
fun AppCompatActivity.replaceFragment(fragment: Fragment){
val fragmentManager = supportFragmentManager
val transaction = fragmentManager.beginTransaction()
transaction.replace(R.id.host,fragment)
transaction.addToBackStack(null)
transaction.commit()
}
When we click the items, we will call replaceFragment
inside WordListAdapter
and go to another fragment as follows:
class WordListAdapter : RecyclerView.Adapter<WordListAdapter.WordViewHolder>() {
...
override fun onBindViewHolder(holder: WordViewHolder, position: Int) {
val current = words[position]
holder.wordItemView.text = current.word
holder.itemView.setOnClickListener {
// fire recyclerView click event
val activity = it.context as AppCompatActivity
val args = Bundle()
// Send string data as key value format
args.putString("word", current.word)
val fragment = WordDefinitionFragment()
fragment.arguments = args
activity.replaceFragment(fragment)
}
}
I just wondering if it's the right way to put replaceFragment
inside the onBindViewHolder
?
In my opinion RecyclerView.Adapter should only bind immutable data and pass clicks via callbacks, and the Activity should be the one to change fragment. In my opinion you should do something like this:
class WordListAdapter(private val onViewHolderClicked: (String) -> Unit) : RecyclerView.Adapter<WordListAdapter.WordViewHolder>() {
...
override fun onBindViewHolder(holder: WordViewHolder, position: Int) {
val current = words[position]
holder.wordItemView.text = current.word
holder.itemView.setOnClickListener {
onViewHolderClicked(current.word)
}
}
and in Activity:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
replaceFragment(WordListFragment())
}
...
fun setupRecyclerView() {
...
val adapter = WordListAdapter() { word ->
val args = Bundle()
// Send string data as key value format
args.putString("word", word)
val fragment = WordDefinitionFragment()
fragment.arguments = args
replaceFragment(fragment)
}
}
}