Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for visibility tracking in model groups #1091

Merged
merged 8 commits into from
Nov 25, 2020

Conversation

pmecho
Copy link
Collaborator

@pmecho pmecho commented Nov 21, 2020

Epoxy models nested inside a model group don't get visibility callbacks, only the outer group gets one. This change iterates through the children of the model group and calls the same visibility checks as top level children, only with the model group view as the parent.

One thing to note is that model removals from the group won't currently get notified of visibility changes. This also means they won't get re-notified if they are added back in. This is due to the EpoxyModelGroup not knowing when a model is removed or not. It'll take a bit more work to handle that but I'm not sure if we have any use cases for adding/removing views from a model group at this time. I added a comment in the docs for EpoxyVisibilityTracker that this isn't yet supported.

I created a new test inside epoxy-integrationtest that uses ActivityScenario so we don't add more that use the deprecated Robolectric.setupActivity method. I copied the TrackerTestModel, AssertHelper and associated helper methods from the existing EpoxyVisibilityTrackerTest, with some minor modifications. This should make it easy to move those over to the integration test module in the near future.

@pmecho pmecho force-pushed the pmecho--model-group-visibility-tracking branch from 4d1fc7d to ad95284 Compare November 22, 2020 15:28
@eboudrant
Copy link
Contributor

@pmecho, just a heads-up. I am fixing EpoxyVisibilityTrackerNestedTest. It is broken (but passes because the test have if (true) return, I can't remember why).

Once fixed, I will be able to validate this change by adding a test case where the carousel is in a group.

@pmecho
Copy link
Collaborator Author

pmecho commented Nov 23, 2020

@eboudrant oh great! I noticed that was broken early today and put it on my list to fix for this. I'm working on adding tests for this model group change in the epoxy-integrationtest module so we can use ActivityScenario and reduce the amount of tests we have to port over. I'll not worry about the nested test for now. Trying to get these tests wrapped up before tomorrow morning.

@pmecho pmecho marked this pull request as ready for review November 24, 2020 06:09
@pmecho pmecho changed the title [WIP] Support for visibility tracking in model groups Support for visibility tracking in model groups Nov 24, 2020
@pmecho pmecho requested a review from elihart November 24, 2020 14:22
@pmecho
Copy link
Collaborator Author

pmecho commented Nov 24, 2020

@elihart and @eboudrant this should be good to go now.

CHANGELOG.md Show resolved Hide resolved
* Note that support for visibility events on an [EpoxyModelGroup] is somewhat limited. Only model
* additions will receive visibility events. Models that are removed from the group will not receive
* events (e.g. [VisibilityState.INVISIBLE]) because the model group does not keep a reference,
* nor does it get notified of model removals.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hum, I am wondering if we can make it works. What are the conditions when we won't receive INVISIBLE event?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eboudrant If the model group no longer has the model in it, it will not find that model's view on a view change, thus not re-compute visibility on it. If the model group does still retain the model but the visibility changes then I think it should work just fine. I can try to add a test for that case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A test case would be nice.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eboudrant just added a couple of test cases for this. Hiding/showing models works as expected. The only outstanding problem is when the model is completely removed from the group. Looking into Eli's suggestion to see if we can do something there.

class EpoxyVisibilityTrackerModelGroupTest {

@get:Rule
var activityRule = activityScenarioRule<TestActivity>()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I am not super familiar with activityRule, do you think we should migrate the existing tests in epoxy-adapter to epoxy-integrationtest too? They only rely on Robolectric. I am worried this change will introduce code duplication for the assert helper part.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this module still uses Robolectric. I do think we should move the existing tests over but was planning on doing that in a separate PR to keep this one focused. ActivityScenario will be the replacement for the now deprecated Robolectric.setupActivity()

Copy link
Contributor

@elihart elihart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

regarding detecting added or removed models within the group, there is ModelGroupHolder.bindGroupIfNeeded which checks for changes to the models and using the data there we should be able to tell if a model is removed or added (based on model id). not sure how hard it would be to link up that code though

Copy link
Contributor

@elihart elihart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pmecho the change itself looks really clean. I feel comfortable with it seeing all the tests you've added, so thanks a ton for those :)

eventOriginForDebug: String,
viewHolder: EpoxyViewHolder
) {
val recyclerView = attachedRecyclerView ?: return
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it looks like we could pass the recyclerview through from where this is called to avoid having this be nullable.

@pmecho
Copy link
Collaborator Author

pmecho commented Nov 25, 2020

I looked a bit into ModelGroupHolder.bindGroupIfNeeded and other code in that class and I'm not seeing a clean way to utilize that without bleeding a visibility tracker into there. The main problem is we don't know when the visibility tracker will be called in relation to models getting added or removed from the group.

I thought about trying to keep a reference to the epoxy holders in a given model group in the visibility tracker. When processing the group we could iterate through the children and detach those that don't exist anymore. However, since these may not be changes on the recycler view adapter, we likely won't get callbacks to reprocess the visibility of the model group. I'm going to go ahead and merge this for now and we can invest time to improve that should we need to.

@pmecho pmecho merged commit 0c7fdc7 into airbnb:master Nov 25, 2020
@pmecho pmecho deleted the pmecho--model-group-visibility-tracking branch November 25, 2020 00:57
@elihart elihart mentioned this pull request Dec 2, 2020
@eboudrant
Copy link
Contributor

@pmecho @elihart we just realized the doc is not up to date and this section could probably be removed by now : https://github.com/airbnb/epoxy/wiki/Grouping-Models#visibility-events

@pmecho
Copy link
Collaborator Author

pmecho commented Jan 6, 2021

@eboudrant great catch! I can get that updated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants