feat: support contentInset on Android#49145
feat: support contentInset on Android#49145kirillzyusko wants to merge 3 commits intofacebook:mainfrom
contentInset on Android#49145Conversation
cipolleschi
left a comment
There was a problem hiding this comment.
Hi @kirillzyusko, thanks for the PR.
Have you checked whether this works properly in the New Arch?
| post(new Runnable() { | ||
| @Override | ||
| public void run() { | ||
| int maxScrollY = getMaxScrollY(); | ||
| // If the current scroll offset is now beyond the new maximum, | ||
| // adjust it to the new maximum. | ||
| if (getScrollY() > maxScrollY) { | ||
| scrollTo(getScrollX(), maxScrollY); | ||
| } | ||
| } | ||
| }); |
There was a problem hiding this comment.
would this show a flicker or an animation or does it happen immediately? 🤔
There was a problem hiding this comment.
I'd say it happens immediately. Basically it fixes a very strange problem. Without this code problems looks like this:
telegram-cloud-document-2-5264877611309358434.mp4
Even though I can clearly see that setter gets called:
There is still a frozen area of the contentInset. But it disappear as soon as I start scrolling. So I thought to add scrollTo programmatically. Maybe there is a better fix for this problem - let me know if you find one 🙌
I tested only new architecture 🙂 However I have a question about In fact it's very draft changes, because I assume at the moment |
Great, thanks for confirming!
No, we have a script to generate it, but it only runs in the internal infra, sadly. So we have to run it ourselves after we import PRs
I don't have a lot of context on the why. I also don't know about all those implications as android is not really my area of expertise. But I'll make sure to pass this around to other Android engineers that might have context/knowledge on this. |
|
@cipolleschi has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
Awesome! Thank you! As I said before - I'm ready to implement missing pieces, just would like to know what exactly I should implement 🙌 😊 Thank you for your assistance ❤️ |
|
@javache Mentioned that, for sure we need to have the HorizontalScrollView implementation (but you knew about that!) There might be some other gotchas, and he is definitely more expert on Android than me. |
b1c1f8e to
0ee7413
Compare
|
@javache @cipolleschi I encountered one problem and I really don't understand the root cause 🤔 Basically if I apply - item 0
- item 1
- ...
- item N
- (paddingTop)
- (paddingBottom)I've tried to workaround that problem by: View content = getContentView();
content.setTranslationY(top);
setPadding(left, top, right, bottom);
scrollBy(0, top);
// simulate iOS behavior
setClipToPadding(false);And it kind of works, but since we shift the content of My other idea was to add - marginTop
- item 0
- item 1
- ...
- item N
- (paddingBottom) <-- `paddingTop` will be compensated by `marginTop`However that approach doesn't work at all 🙃 I'm not allowed to change paddings of React views because they are laid out by YOGA and all my manual changes get ignored? We can also have a conversation in discord, if you think that it'll be easier/faster for you 🙂 |
|
This PR is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days. |
|
This PR is stale because it has been open for 180 days with no activity. It will be closed in 7 days unless you comment on it or remove the "Stale" label. |
|
I'm going to close this PR for now, because I came up with a solution just in keyboard-controller codebase: kirillzyusko/react-native-keyboard-controller#1289 I'll test how it works there and will backport changes to original |
## 📜 Description
Added `ClippingScrollView` component (on Android only) that is supposed
to act as a polyfill for `contentInset: {bottom}` property of
`ScrollView`.
## 💡 Motivation and Context
Those changes are based on my PR from
facebook/react-native#49145
The big problem with original PR is that it wasn't working correctly, if
we specify all insets/paddings simultaneously. But! It worked well for
`bottom` inset property (keyboard-controller case, because keyboard
appears from the bottom of the screen). I think it's risky to ship a
code in this state into facebook codebase, so I decided to add those
changes into `react-native-keyboard-controller` first. It's good
because:
- I have a full ownership of the code and I can fix bugs quickly
(without waiting for a new RN release);
- we don't ship buggy code in react-native repository;
- we don't depend on react-native version and we don't need to write a
conditional code, like "if prop is supported, then use new approach and
if not, then fallback to old implementation".
The approach that I've choose is based on "decorator" approach - this
approach has been used in many other libs, such as
`advanced-input-mask`, `live-markdown` etc. The idea is that we create
our custom view that wraps our target view and then we access a target
view as a children (and we can modify behavior/props of this view).
I'm going to use this component in `KeyboardAwareScrollView` and in new
`ChatKit` component. From lessons learned from the previous experience I
can confidently say, that additional view near children will cause
issues and this polyfill for `contentInset: {bottom}` should hopefully
solve all the issues that we had. I'll continue experiments with this
view in
#797
## 📢 Changelog
<!-- High level overview of important changes -->
<!-- For example: fixed status bar manipulation; added new types
declarations; -->
<!-- If your changes don't affect one of platform/language below - then
remove this platform/language -->
### JS
- added codegen component;
- added new types props for new component;
- added jsdoc for new component;
### Android
- added `ClippingScrollView`;
## 🤔 How Has This Been Tested?
Tested in example app in `KeyboardAwareScrollView` screen and in new
component that is currently under active development 😊 Everywhere works
stable on both architectures 🤞
## 📸 Screenshots (if appropriate):
|KeyboardAwareScollView|Non inverted chat list|
|--------------------------|---------------------|
|<video
src="https://github.com/user-attachments/assets/0f7efef7-ec15-4fe6-96cb-40334f0c91ad">|<video
src="https://github.com/user-attachments/assets/92093e87-434a-4c82-91d5-1c7e9706e5f0">|
## 📝 Checklist
- [x] CI successfully passed
- [x] I added new mocks and corresponding unit-tests if library API was
changed
Summary:
At the moment
contentInsetproperty is available only on iOS. In this PR I'm adding the support for this property via applying additional padding directly toScrollViewnative component.Changelog:
[ANDROID] [ADDED] - support
contentInseton AndroidTest Plan:
Simulator.Screen.Recording.-.iPhone.15.Pro.-.2025-02-03.at.19.18.35.mp4
telegram-cloud-document-2-5262625811495674255.mp4