-
Notifications
You must be signed in to change notification settings - Fork 24.4k
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 RefreshControl in RecyclerViewBackedScrollView in Android #8639
Conversation
return React.cloneElement( | ||
refreshControl, | ||
{style: props.style}, | ||
<NativeAndroidRecyclerView {...props}> |
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.
Can you add a style with flex: 1
to NativeAndroidRecyclerView
to make sure it fills the AndroidSwipeRefreshLayout
.
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.
This style is already in props.
console.log('props.style', props.style[0])
=> props.style Object {flex: 1}
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.
I'm mostly concerned about passing props.style to both AndroidSwipeRefreshLayout and NativeAndroidRecyclerView. Styles like margin could cause issues because they will get applied twice. Adding style after ...props will prevent that.
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.
Ok, got it. Just added the style in the last commit.
…he AndroidSwipeRefreshLayout
// Wrap the NativeAndroidRecyclerView with a AndroidSwipeRefreshLayout. | ||
return React.cloneElement( | ||
refreshControl, | ||
{style: props.style}, |
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.
Can you remove props.style above in theprops
definition and instead pass in this.props.style
(and add flex: 1 if it's necessary).
And set style
in the props
definition above to just {flex: 1}
.
Also rename props
to recyclerProps
.
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.
Sorry, i'm a litte bit confused... it should became something like this?
const refreshControl = this.props.refreshControl;
if (refreshControl) {
// Wrap the NativeAndroidRecyclerView with a AndroidSwipeRefreshLayout.
return React.cloneElement(
refreshControl,
{style: {flex: 1}},
<NativeAndroidRecyclerView {...props}>
{wrappedChildren}
</NativeAndroidRecyclerView>
);
}
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.
I think the clearer way to do this is not include style in the props
declaration (line 95). This way we can be explicit about what style we want for each case.
Should look like
const recyclerProps = { ... };
...
const refreshControl = this.props.refreshControl;
if (refreshControl) {
// Wrap the NativeAndroidRecyclerView with a AndroidSwipeRefreshLayout.
return React.cloneElement(
refreshControl,
{style: [styles.base, this.props.style]},
<NativeAndroidRecyclerView {...recyclerProps} style={styles.base}>
{wrappedChildren}
</NativeAndroidRecyclerView>
);
}
styles.base
being {flex: 1}
We'll also have to change the case where there is no refreshControl to style={[styles.base, this.props.style]}
and {...recyclerProps}
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.
Yeah, one way to think of it is: how would this code be most clearly written from scratch?
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.
Ok, I've understood now, it is more clear indeed. Just pushed the changes.
Thanks, this looks good! @facebook-github-bot shipit |
Thanks for importing. If you are an FB employee go to Phabricator to review. |
0c0ac6e
is that issue fixed? |
This is in 0.31.0-rc |
Summary: In Android, `RecyclerViewBackedScrollView` wasn't using `refreshControl` prop. If a ListView were created with `RecyclerViewBackedScrollView` as its `renderScrollComponent`, then the `refreshControl` wouldn't work. example: ```js <ListView dataSource={this.props.dataSource} renderRow={this._renderRow.bind(this)} refreshControl={ <RefreshControl refreshing={this.props.isRefreshing} onRefresh={this._onRefresh.bind(this)} /> } renderScrollComponent={props => <RecyclerViewBackedScrollView {...props} />}/>; ``` This works in iOS, since the `RecyclerViewBackedScrollView` just returns an `ScrollView`. This pull request uses the `refreshControl` to decide whether it should wrap the `NativeAndroidRecyclerView` with an `AndroidSwipeRefreshLayout` or not. This fixes the issue facebook#7134. Closes facebook#8639 Differential Revision: D3564158 fbshipit-source-id: c10a880ea61cd80b8af789b00be90d46d63eaf9a
Summary: In Android, `RecyclerViewBackedScrollView` wasn't using `refreshControl` prop. If a ListView were created with `RecyclerViewBackedScrollView` as its `renderScrollComponent`, then the `refreshControl` wouldn't work. example: ```js <ListView dataSource={this.props.dataSource} renderRow={this._renderRow.bind(this)} refreshControl={ <RefreshControl refreshing={this.props.isRefreshing} onRefresh={this._onRefresh.bind(this)} /> } renderScrollComponent={props => <RecyclerViewBackedScrollView {...props} />}/>; ``` This works in iOS, since the `RecyclerViewBackedScrollView` just returns an `ScrollView`. This pull request uses the `refreshControl` to decide whether it should wrap the `NativeAndroidRecyclerView` with an `AndroidSwipeRefreshLayout` or not. This fixes the issue facebook#7134. Closes facebook#8639 Differential Revision: D3564158 fbshipit-source-id: c10a880ea61cd80b8af789b00be90d46d63eaf9a
Summary: In Android, `RecyclerViewBackedScrollView` wasn't using `refreshControl` prop. If a ListView were created with `RecyclerViewBackedScrollView` as its `renderScrollComponent`, then the `refreshControl` wouldn't work. example: ```js <ListView dataSource={this.props.dataSource} renderRow={this._renderRow.bind(this)} refreshControl={ <RefreshControl refreshing={this.props.isRefreshing} onRefresh={this._onRefresh.bind(this)} /> } renderScrollComponent={props => <RecyclerViewBackedScrollView {...props} />}/>; ``` This works in iOS, since the `RecyclerViewBackedScrollView` just returns an `ScrollView`. This pull request uses the `refreshControl` to decide whether it should wrap the `NativeAndroidRecyclerView` with an `AndroidSwipeRefreshLayout` or not. This fixes the issue #7134. Closes facebook/react-native#8639 Differential Revision: D3564158 fbshipit-source-id: c10a880ea61cd80b8af789b00be90d46d63eaf9a
In Android,
RecyclerViewBackedScrollView
wasn't usingrefreshControl
prop.If a ListView were created with
RecyclerViewBackedScrollView
as itsrenderScrollComponent
, then therefreshControl
wouldn't work.example:
This works in iOS, since the
RecyclerViewBackedScrollView
just returns anScrollView
.This pull request uses the
refreshControl
to decide whether it should wrap theNativeAndroidRecyclerView
with anAndroidSwipeRefreshLayout
or not.This fixes the issue #7134.