johnny_crq
johnny_crq

Reputation: 4391

kotlin android fragment empty recycler view after back

I have this android fragment:

class MainFragment: BaseFragment(){

private val recyclerView by lazy { find<RecyclerView>(R.id.recyclerView) }
private val fab by lazy { find<FloatingActionButton>(R.id.fab) }

private val myLayoutManager by lazy { LinearLayoutManager(ctx, LinearLayoutManager.VERTICAL, false) }
private val myAdapter by lazy { MainCardAdapter(ctx, ArrayList<MainCardAdapterItem>(), R.layout.card_main_item) }

override val fragmentLayout = R.layout.fragment_main_layout

val DUMMY_TEXT = "Lorem ipsum dolor sit amet, consectetur adipiscing"

)

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    val view = super.onCreateView(inflater, container, savedInstanceState)
    setHasOptionsMenu(true)
    return view
}

override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
    Log.i("TAG", "onViewCreated")
    super.onViewCreated(view, savedInstanceState)
    (act as MainActivity).run { showWidgetStars(true) }

    recyclerView
            .linkToLayoutManager(myLayoutManager)
            .linkToAdapter(myAdapter)
            .addItemDecorator(removedSwipeLeftDecorator)
            .setOnItemChangedDuration(500)

    myAdapter.run {
        setAdapterItems(dummyList)
    }
}

override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
    inflater.inflate(R.menu.activity_main_context, menu)
    menu.findItem(R.id.action_secundary_menu).run {
        isVisible = true
        icon.setTintCompat(ctx, act.colorFromRes(R.color.appGreyDark))
    }
    super.onCreateOptionsMenu(menu, inflater)
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    when(item.itemId){
        R.id.action_secundary_menu -> {
            act.showSnackBar("Clicked Secondary Menu!")
            return true
        }
        else -> return super.onOptionsItemSelected(item)
    }
  }
}                               

Everything works good except after i come back to this fragment (replaced in fragment manager by another, added to the backstack). When i return, i get an error saying: E/RecyclerView: No adapter attached; skipping layout. My bet is that its something to do with lazy properties but i can't figure it why. The fragment shows good on first run, only when going back it shows no recycler view items and display this message

Upvotes: 4

Views: 2720

Answers (1)

johnny_crq
johnny_crq

Reputation: 4391

So as my properties are declared as lazy { find<View>(R.id.xxx} that basically means they will only be inflated from the layout one time. If the fragment's view somehow needs to be created again, the recyclerview property will point to an old view.

I'm not sure how a null pointer exception in that case was not thrown. Simply change the lazy to a var, and re-assign it on onCreateView. Another thing, if we want to use the same LayoutManager for the new inflated recyclerview, we must clear it from the previous recyclerview recyclerView.layoutManager = null, otherwise, an exception will be thrown saying that that layoutManager is already binded to another recyclerView.

Upvotes: 3

Related Questions