airbnb / epoxy

Epoxy is an Android library for building complex screens in a RecyclerView
https://goo.gl/eIK82p
Apache License 2.0
8.5k stars 733 forks source link

When I know that Epoxy rows are created #578

Closed qbait closed 5 years ago

qbait commented 5 years ago

I'm using MvRx and I'm defining my Carousel

    override fun epoxyController() = simpleController(viewModel) { state ->

        val list = listOf("A", "B", "C", "D", "E")

        carousel {
            id("carousel")
            numViewsToShowOnScreen(1f)
            withModelsFrom(list) {
                MarqueeModel_()
                        .id(it)
                        .title(it)
            }
        }
     }

I want to perform an action on this Carousel after creating it so I added it in OnViewCreated. However, at this point my recyclerView.childCount is 0. I added ugly delay by now.

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        Handler().postDelayed({
            if (recyclerView.childCount > 0) {
                val carousel = recyclerView.asSequence().filterIsInstance(Carousel::class.java).first()
                // do sth with carousel
            }
        }, 200)
    }

Is there a better solution to this problem?

elihart commented 5 years ago

this isn't really related to epoxy or mvrx.

For Recyclerview in general you could use addOnLayoutChangeListener and addOnChildAttachStateChangeListener

with epoxy you can use EpoxyController#addModelBuildListener but that will be after recyclerview is notified of changes and before it is laid out, so you would have to wait for it to lay itself out

qbait commented 5 years ago

Thanks again @elihart

HsuHsiaoHsuan commented 4 years ago

I use IdleHandler to fix my problem :)

Looper.myQueue().addIdleHandler {
    // do something
    false
}