mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-30 22:12:42 +08:00
Add onPageScrollStateChanged for ViewPagerAndroid
Summary: I have an issue when combining `PullToRefreshViewAndroid` and `ViewPagerAndroid`. `ViewPagerAndroid` will not able to scroll that gesture handler is being taken by `PullToRefreshViewAndroid` One solution is to disable `PullToRefreshViewAndroid` if `ViewPagerAndroid` is scrolling (i.e. not idle). [Reference solution here](http://stackoverflow.com/a/29946734/2590265) So here need to expose the `onPageScrollStateChanged` event. Some code referenced from DrawerLayoutAndroid, especially the `VIEWPAGER_PAGE_SCROLL_STATES` array. Please feel free give me comments. Thanks. Closes https://github.com/facebook/react-native/pull/5026 Reviewed By: svcscm Differential Revision: D2830623 Pulled By: andreicoman11 fb-gh-sync-id: c2a6920c6f4c7daab0115f13864db83b93b31abf
This commit is contained in:
committed by
facebook-github-bot-9
parent
5e82094fcb
commit
8de86a0d65
@@ -25,6 +25,8 @@ var {
|
||||
ViewPagerAndroid,
|
||||
} = React;
|
||||
|
||||
import type { ViewPagerScrollState } from 'ViewPagerAndroid';
|
||||
|
||||
var PAGES = 5;
|
||||
var BGCOLOR = ['#fdc08e', '#fff6b9', '#99d1b7', '#dde5fe', '#f79273'];
|
||||
var IMAGE_URIS = [
|
||||
@@ -114,6 +116,10 @@ var ViewPagerAndroidExample = React.createClass({
|
||||
this.setState({progress: e.nativeEvent});
|
||||
},
|
||||
|
||||
onPageScrollStateChanged: function(state : ViewPagerScrollState) {
|
||||
this.setState({scrollState: state});
|
||||
},
|
||||
|
||||
move: function(delta) {
|
||||
var page = this.state.page + delta;
|
||||
this.go(page);
|
||||
@@ -155,6 +161,7 @@ var ViewPagerAndroidExample = React.createClass({
|
||||
initialPage={0}
|
||||
onPageScroll={this.onPageScroll}
|
||||
onPageSelected={this.onPageSelected}
|
||||
onPageScrollStateChanged={this.onPageScrollStateChanged}
|
||||
ref={viewPager => { this.viewPager = viewPager; }}>
|
||||
{pages}
|
||||
</ViewPagerAndroid>
|
||||
@@ -170,6 +177,7 @@ var ViewPagerAndroidExample = React.createClass({
|
||||
enabled={true}
|
||||
onPress={() => this.setState({animationsAreEnabled: true})}
|
||||
/> }
|
||||
<Text style={styles.scrollStateText}>ScrollState[ {this.state.scrollState} ]</Text>
|
||||
</View>
|
||||
<View style={styles.buttons}>
|
||||
<Button text="Start" enabled={page > 0} onPress={() => this.go(0)}/>
|
||||
@@ -207,6 +215,9 @@ var styles = StyleSheet.create({
|
||||
buttonText: {
|
||||
color: 'white',
|
||||
},
|
||||
scrollStateText: {
|
||||
color: '#99d1b7',
|
||||
},
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: 'white',
|
||||
|
||||
@@ -19,6 +19,14 @@ var requireNativeComponent = require('requireNativeComponent');
|
||||
|
||||
var VIEWPAGER_REF = 'viewPager';
|
||||
|
||||
type Event = Object;
|
||||
|
||||
export type ViewPagerScrollState = $Enum<{
|
||||
idle: string;
|
||||
dragging: string;
|
||||
settling: string;
|
||||
}>;
|
||||
|
||||
/**
|
||||
* Container that allows to flip left and right between child views. Each
|
||||
* child view of the `ViewPagerAndroid` will be treated as a separate page
|
||||
@@ -78,6 +86,16 @@ var ViewPagerAndroid = React.createClass({
|
||||
*/
|
||||
onPageScroll: ReactPropTypes.func,
|
||||
|
||||
/**
|
||||
* Function called when the page scrolling state has changed.
|
||||
* The page scrolling state can be in 3 states:
|
||||
* - idle, meaning there is no interaction with the page scroller happening at the time
|
||||
* - dragging, meaning there is currently an interaction with the page scroller
|
||||
* - settling, meaning that there was an interaction with the page scroller, and the
|
||||
* page scroller is now finishing it's closing or opening animation
|
||||
*/
|
||||
onPageScrollStateChanged: ReactPropTypes.func,
|
||||
|
||||
/**
|
||||
* This callback will be called once ViewPager finish navigating to selected page
|
||||
* (when user swipes between pages). The `event.nativeEvent` object passed to this
|
||||
@@ -147,6 +165,12 @@ var ViewPagerAndroid = React.createClass({
|
||||
}
|
||||
},
|
||||
|
||||
_onPageScrollStateChanged: function(e: Event) {
|
||||
if (this.props.onPageScrollStateChanged) {
|
||||
this.props.onPageScrollStateChanged(e.nativeEvent.pageScrollState);
|
||||
}
|
||||
},
|
||||
|
||||
_onPageSelected: function(e: Event) {
|
||||
if (this.props.onPageSelected) {
|
||||
this.props.onPageSelected(e);
|
||||
@@ -183,6 +207,7 @@ var ViewPagerAndroid = React.createClass({
|
||||
ref={VIEWPAGER_REF}
|
||||
style={this.props.style}
|
||||
onPageScroll={this._onPageScroll}
|
||||
onPageScrollStateChanged={this._onPageScrollStateChanged}
|
||||
onPageSelected={this._onPageSelected}
|
||||
children={this._childrenWithOverridenStyle()}
|
||||
/>
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
package com.facebook.react.views.viewpager;
|
||||
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.uimanager.events.Event;
|
||||
import com.facebook.react.uimanager.events.RCTEventEmitter;
|
||||
|
||||
/**
|
||||
* Event emitted by {@link ReactViewPager} when user scrolling state changed.
|
||||
*
|
||||
* Additional data provided by this event:
|
||||
* - pageScrollState - {Idle,Dragging,Settling}
|
||||
*/
|
||||
class PageScrollStateChangedEvent extends Event<PageScrollStateChangedEvent> {
|
||||
|
||||
public static final String EVENT_NAME = "topPageScrollStateChanged";
|
||||
|
||||
private final String mPageScrollState;
|
||||
|
||||
protected PageScrollStateChangedEvent(int viewTag, long timestampMs, String pageScrollState) {
|
||||
super(viewTag, timestampMs);
|
||||
mPageScrollState = pageScrollState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventName() {
|
||||
return EVENT_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatch(RCTEventEmitter rctEventEmitter) {
|
||||
rctEventEmitter.receiveEvent(getViewTag(), getEventName(), serializeEventData());
|
||||
}
|
||||
|
||||
private WritableMap serializeEventData() {
|
||||
WritableMap eventData = Arguments.createMap();
|
||||
eventData.putString("pageScrollState", mPageScrollState);
|
||||
return eventData;
|
||||
}
|
||||
}
|
||||
@@ -104,7 +104,22 @@ import com.facebook.react.uimanager.events.NativeGestureUtil;
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state) {
|
||||
// don't send events
|
||||
String pageScrollState;
|
||||
switch (state) {
|
||||
case SCROLL_STATE_IDLE:
|
||||
pageScrollState = "idle";
|
||||
break;
|
||||
case SCROLL_STATE_DRAGGING:
|
||||
pageScrollState = "dragging";
|
||||
break;
|
||||
case SCROLL_STATE_SETTLING:
|
||||
pageScrollState = "settling";
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unsupported pageScrollState");
|
||||
}
|
||||
mEventDispatcher.dispatchEvent(
|
||||
new PageScrollStateChangedEvent(getId(), SystemClock.uptimeMillis(), pageScrollState));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ public class ReactViewPagerManager extends ViewGroupManager<ReactViewPager> {
|
||||
public Map getExportedCustomDirectEventTypeConstants() {
|
||||
return MapBuilder.of(
|
||||
PageScrollEvent.EVENT_NAME, MapBuilder.of("registrationName", "onPageScroll"),
|
||||
PageScrollStateChangedEvent.EVENT_NAME, MapBuilder.of("registrationName", "onPageScrollStateChanged"),
|
||||
PageSelectedEvent.EVENT_NAME, MapBuilder.of("registrationName", "onPageSelected")
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user