-
Notifications
You must be signed in to change notification settings - Fork 24.3k
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
[Android] Implement ScrollView sticky headers on Android #9456
[Android] Implement ScrollView sticky headers on Android #9456
Conversation
cc @brentvatne :D |
@janicduplessis - tried it out, seems great! any idea about the CI failures? |
Looks like the instrumentation tests are failing, I'll run them locally to see what is going on. |
Did you consider implementing this with the new native-driven Animated.event? Seems like it would be a little awkward to describe with Animated, but doable. |
@sahrens - probably doable, but I think we should wait for offload Animated and Animated event stuff to be more mature first, then switch the iOS and Android implementations of sticky headers at the same time. |
bravo |
@sahrens I agree with @brentvatne, it would be really nice to eventually convert it but for now I think this is better. |
@@ -152,6 +175,22 @@ protected void onScrollChanged(int x, int y, int oldX, int oldY) { | |||
} | |||
|
|||
@Override | |||
public View hitTest(float[] coordinates) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this needed because our touch handling doesn't respect drawing order? If so, can we just make our normal touch handling handle drawing order so that we don't have to add a new touch handling code path?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, good idea, I just checked and AOSP does use getChildDrawingOrder when dispatching a touch event to subviews.
Re collapsableChildren vs cloning for the collapsable prop: is there actually a perf concern here? If possible, I'd really rather not add another prop we need to support. |
@janicduplessis updated the pull request - view changes |
7f8275a
to
09655e6
Compare
@janicduplessis updated the pull request - view changes |
@janicduplessis updated the pull request - view changes |
09655e6
to
886b17e
Compare
@janicduplessis updated the pull request - view changes |
@astreet Yea, unfounded perf concerns :), changed it to cloning child elements in JS. We can change it in tthe future if it is actually an issue. |
886b17e
to
aed01ae
Compare
@janicduplessis updated the pull request - view changes |
OMG, failing still? |
0e8b75b
Landed now :D |
since facebook#9456 has been landed, it's the time to add ListViewPagingExample to the example list for Android
Been waiting for this. Thank you! |
Summary: This adds support for sticky headers on Android. The implementation if based primarily on the iOS one (https://github.com/facebook/react-native/blob/master/React/Views/RCTScrollView.m#L272) and adds some stuff that was missing to be able to handle z-index, view clipping, view hierarchy optimization and touch handling properly. Some notable changes: - Add `ChildDrawingOrderDelegate` interface to allow changing the `ViewGroup` drawing order using `ViewGroup#getChildDrawingOrder`. This is used to change the content view drawing order to make sure headers are drawn over the other cells. Right now I'm only reversing the drawing order as drawing only the header views last added a lot of complexity especially because of view clipping and I don't think it should cause issues. - Add `collapsableChildren` prop that works like `collapsable` but applies to every child of the view. This is needed to be able to reference sticky headers by their indices otherwise some subviews can get optimized out and break indexes. Closes #9456 Differential Revision: D3827366 Pulled By: fred2028 fbshipit-source-id: d346068734c5b987518794ab23e13914ed13b5c4
Yep, sorry for posting after the fact, this got reverted after I left for the day. We hit a couple problems after this landed:
|
Looking into this more, one of the things that broke was that ListView automatically enables sticky headers for section headers. Some of the code in adsmanager for android apparently doesn't properly identify what things are section headers vs. normal rows and we now have random rows sticking to the top ha. I think before this diff lands, we need to have whether stick headers are enabled for ListView customizable. And, given the design patterns on the two platforms, it should probably be enabled by default on iOS (as it is currently) and DISABLED by default on Android. Blindly copying design patterns from iOS to Android, like with sticky headers, is one of those things that identifies your framework as a lowest-common denominator crossplatform solution which we don't want. That being said, I think there are legit use cases for it, I just don't want it to become a 'thing' for RN apps on Android. |
I haven't been able to get a repro for the rendering issue that was described to me (where B renders over A), but I have a feeling it's because stickyHeaderIndices is causing us to identify the wrong View as being sticky somehow. I'd really feel a lot better about this API if, instead of passing in indices, we wrapped the views that are supposed to be sticky in a custom native view that the ScrollView can identify. That way, we aren't hurt by collapsable optimizations and don't need to make sure stickyHeaderIndices and the ListView dataSource stay in sync. |
ScrollView Sticky Header on Android is really important to me, I'm building a cross-platform app, it's really ugly without sticky header on Android, I've made a js workaround but far from satisfaction, so I build RN from source to use this feature, and it works great, although there are still some bugs but it's fine in my case. I think it's deserve to be kept in the master branch for further improvement, while providing an option to disable it on Android for consistency, e.g. |
And I've noticed the random sticking issue in |
@astreet I think I know why tbe rendering but you describe happens. Gonna have a look at this as well as the issues @nihgwu found out today. I also agree that we should make this disabled by default on android and add a flag to listview to enable it. Thisatches better what is common on the platform and will also avoid making this a breaking change. |
Also for using a custom native view for headers I agree this would be a better and more reliable API but it should still be possible to make indices work, it's just a matter of fixing a few remaining bugs then it will be stable. |
I add a |
I'll close this PR and open a new one since we already shipped this, not sure if the bot will work properly. |
Summary: This adds support for sticky headers on Android. The implementation if based primarily on the iOS one (https://github.com/facebook/react-native/blob/master/React/Views/RCTScrollView.m#L272) and adds some stuff that was missing to be able to handle z-index, view clipping, view hierarchy optimization and touch handling properly. Some notable changes: - Add `ChildDrawingOrderDelegate` interface to allow changing the `ViewGroup` drawing order using `ViewGroup#getChildDrawingOrder`. This is used to change the content view drawing order to make sure headers are drawn over the other cells. Right now I'm only reversing the drawing order as drawing only the header views last added a lot of complexity especially because of view clipping and I don't think it should cause issues. - Add `collapsableChildren` prop that works like `collapsable` but applies to every child of the view. This is needed to be able to reference sticky headers by their indices otherwise some subviews can get optimized out and break indexes. Closes facebook/react-native#9456 Differential Revision: D3827366 fbshipit-source-id: cab044cfdbe2ccb98e1ecd3e02ed3ceaa253eb78
Summary: This adds support for sticky headers on Android. The implementation if based primarily on the iOS one (https://github.com/facebook/react-native/blob/master/React/Views/RCTScrollView.m#L272) and adds some stuff that was missing to be able to handle z-index, view clipping, view hierarchy optimization and touch handling properly. Some notable changes: - Add `ChildDrawingOrderDelegate` interface to allow changing the `ViewGroup` drawing order using `ViewGroup#getChildDrawingOrder`. This is used to change the content view drawing order to make sure headers are drawn over the other cells. Right now I'm only reversing the drawing order as drawing only the header views last added a lot of complexity especially because of view clipping and I don't think it should cause issues. - Add `collapsableChildren` prop that works like `collapsable` but applies to every child of the view. This is needed to be able to reference sticky headers by their indices otherwise some subviews can get optimized out and break indexes. Closes facebook/react-native#9456 Differential Revision: D3827366 Pulled By: fred2028 fbshipit-source-id: d346068734c5b987518794ab23e13914ed13b5c4
This adds support for sticky headers on Android. The implementation if based primarily on the iOS one (https://github.com/facebook/react-native/blob/master/React/Views/RCTScrollView.m#L272) and adds some stuff that was missing to be able to handle z-index, view clipping, view hierarchy optimization and touch handling properly.
Some notable changes:
ChildDrawingOrderDelegate
interface to allow changing theViewGroup
drawing order usingViewGroup#getChildDrawingOrder
. This is used to change the content view drawing order to make sure headers are drawn over the other cells. Right now I'm only reversing the drawing order as drawing only the header views last added a lot of complexity especially because of view clipping and I don't think it should cause issues.collapsableChildren
prop that works likecollapsable
but applies to every child of the view. This is needed to be able to reference sticky headers by their indices otherwise some subviews can get optimized out and break indexes.TouchTargetHelper
take drawing order into consideration when finding the touch target.Test plan
Tested using the UIExplorer main menu on android.
Tested that touches get dispatched to the sticky header when over other touchable views.
Tested that touchables inside a sticky header work properly.