Permalink
Browse files

Open source SwipeRefreshLayoutAndroid

Reviewed By: mkonicek

Differential Revision: D2679605

fb-gh-sync-id: 7f3e7384b37f29002ddd8cb7a4567fa96c76f047
  • Loading branch information...
bestander authored and facebook-github-bot-8 committed Nov 24, 2015
1 parent e55d707 commit 37f81341a006458d84d934882485c2a0a8838497
@@ -0,0 +1,127 @@
/**
* The examples provided by Facebook are for non-commercial testing and
* evaluation purposes only.
*
* Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
'use strict';
const React = require('react-native');
const {
ScrollView,
StyleSheet,
PullToRefreshLayoutAndroid,
Text,
TouchableWithoutFeedback,
View,
} = React;
const styles = StyleSheet.create({
row: {
borderColor: 'grey',
borderWidth: 1,
padding: 20,
backgroundColor: '#3a5795',
margin: 5,
},
text: {
alignSelf: 'center',
color: '#fff',
},
layout: {
flex: 1,
},
scrollview: {
flex: 1,
},
});
const Row = React.createClass({
_onClick: function() {
this.props.onClick(this.props.data);
},
render: function() {
return (
<TouchableWithoutFeedback onPress={this._onClick} >
<View style={styles.row}>
<Text style={styles.text}>
{this.props.data.text + ' (' + this.props.data.clicks + ' clicks)'}
</Text>
</View>
</TouchableWithoutFeedback>
);
},
});
const PullToRefreshLayoutAndroidExample = React.createClass({
statics: {
title: '<PullToRefreshLayoutAndroid>',
description: 'Container that adds pull-to-refresh support to its child view.'
},
getInitialState() {
return {
isRefreshing: false,
loaded: 0,
rowData: Array.from(new Array(20)).map(
(val, i) => {return {text: 'Initial row' + i, clicks: 0}}),
};
},
_onClick(row) {
row.clicks++;
this.setState({
rowData: this.state.rowData,
});
},
render() {
const rows = this.state.rowData.map((row) => {
return <Row data={row} onClick={this._onClick}/>;
});
return (
<PullToRefreshLayoutAndroid
style={styles.layout}
refreshing={this.state.isRefreshing}
onRefresh={this._onRefresh}
colors={['#ff0000', '#00ff00', '#0000ff']}
progressBackgroundColor={'#ffff00'}
>
<ScrollView style={styles.scrollview}>
{rows}
</ScrollView>
</PullToRefreshLayoutAndroid>
);
},
_onRefresh() {
this.setState({isRefreshing: true});
setTimeout(() => {
// prepend 10 items
const rowData = Array.from(new Array(10))
.map((val, i) => {return {
text: 'Loaded row' + (+this.state.loaded + i),
clicks: 0,
}})
.concat(this.state.rowData);
this.setState({
loaded: this.state.loaded + 10,
isRefreshing: false,
rowData: rowData,
});
}, 5000);
},
});
module.exports = PullToRefreshLayoutAndroidExample;
@@ -27,6 +27,7 @@ var COMPONENTS = [
require('./ProgressBarAndroidExample'),
require('./ScrollViewSimpleExample'),
require('./SwitchAndroidExample'),
require('./PullToRefreshLayoutAndroidExample.android'),
require('./TextExample.android'),
require('./TextInputExample.android'),
require('./ToolbarAndroidExample'),
@@ -0,0 +1,87 @@
/**
* 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.
*
* @providesModule PullToRefreshLayoutAndroid
*/
'use strict';
var React = require('React');
var RefreshLayoutConsts = require('NativeModules').UIManager.AndroidSwipeRefreshLayout.Constants;
var View = require('View');
var onlyChild = require('onlyChild');
var processColor = require('processColor');
var requireNativeComponent = require('requireNativeComponent');
var NATIVE_REF = 'native_swiperefreshlayout';
/**
* React view that supports a single scrollable child view (e.g. `ScrollView`). When this child
* view is at `scrollY: 0`, swiping down triggers an `onRefresh` event.
*/
var PullToRefreshLayoutAndroid = React.createClass({
statics: {
SIZE: RefreshLayoutConsts.SIZE,
},
propTypes: {
...View.propTypes,
/**
* Whether the pull to refresh functionality is enabled
*/
enabled: React.PropTypes.bool,
/**
* The colors (at least one) that will be used to draw the refresh indicator
*/
colors: React.PropTypes.arrayOf(React.PropTypes.string),
/**
* The background color of the refresh indicator
*/
progressBackgroundColor: React.PropTypes.string,
/**
* Whether the view should be indicating an active refresh
*/
refreshing: React.PropTypes.bool,
/**
* Size of the refresh indicator, see PullToRefreshLayoutAndroid.SIZE
*/
size: React.PropTypes.oneOf(RefreshLayoutConsts.SIZE.DEFAULT, RefreshLayoutConsts.SIZE.LARGE),
},
getInnerViewNode: function() {
return this.refs[NATIVE_REF];
},
render: function() {
return (
<NativePullToRefresh
colors={this.props.colors && this.props.colors.map(processColor)}
enabled={this.props.enabled}
onRefresh={this._onRefresh}
progressBackgroundColor={this.props.progressBackgroundColor}
ref={NATIVE_REF}
refreshing={this.props.refreshing}
size={this.props.size}
style={this.props.style}>
{onlyChild(this.props.children)}
</NativePullToRefresh>
);
},
_onRefresh: function() {
this.props.onRefresh && this.props.onRefresh();
this.refs[NATIVE_REF].setNativeProps({refreshing: !!this.props.refreshing});
}
});
var NativePullToRefresh = requireNativeComponent(
'AndroidSwipeRefreshLayout',
PullToRefreshLayoutAndroid
);
module.exports = PullToRefreshLayoutAndroid;
@@ -0,0 +1,13 @@
/**
* 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.
*
* @providesModule PullToRefreshLayoutAndroid
*/
'use strict';
module.exports = require('UnimplementedView');
@@ -37,6 +37,7 @@ var ReactNative = Object.assign(Object.create(require('React')), {
SliderIOS: require('SliderIOS'),
SnapshotViewIOS: require('SnapshotViewIOS'),
Switch: require('Switch'),
PullToRefreshLayoutAndroid: require('PullToRefreshLayoutAndroid'),
SwitchAndroid: require('SwitchAndroid'),
SwitchIOS: require('SwitchIOS'),
TabBarIOS: require('TabBarIOS'),
@@ -39,6 +39,7 @@
import com.facebook.react.views.toolbar.ReactToolbarManager;
import com.facebook.react.views.view.ReactViewManager;
import com.facebook.react.views.viewpager.ReactViewPagerManager;
import com.facebook.react.views.swiperefresh.SwipeRefreshLayoutManager;
/**
* Package defining basic modules and view managers.
@@ -78,6 +79,7 @@
new ReactViewManager(),
new ReactViewPagerManager(),
new ReactTextInlineImageViewManager(),
new ReactVirtualTextViewManager());
new ReactVirtualTextViewManager(),
new SwipeRefreshLayoutManager());
}
}
@@ -0,0 +1,35 @@
/**
* 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.swiperefresh;
import android.support.v4.widget.SwipeRefreshLayout;
import android.view.MotionEvent;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.uimanager.events.NativeGestureUtil;
/**
* Basic extension of {@link SwipeRefreshLayout} with ReactNative-specific functionality.
*/
public class ReactSwipeRefreshLayout extends SwipeRefreshLayout {
public ReactSwipeRefreshLayout(ReactContext reactContext) {
super(reactContext);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (super.onInterceptTouchEvent(ev)) {
NativeGestureUtil.notifyNativeGestureStarted(this, ev);
return true;
}
return false;
}
}
@@ -0,0 +1,30 @@
/**
* 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.swiperefresh;
import com.facebook.react.uimanager.events.Event;
import com.facebook.react.uimanager.events.RCTEventEmitter;
public class RefreshEvent extends Event<RefreshEvent> {
protected RefreshEvent(int viewTag, long timestampMs) {
super(viewTag, timestampMs);
}
@Override
public String getEventName() {
return "topRefresh";
}
@Override
public void dispatch(RCTEventEmitter rctEventEmitter) {
rctEventEmitter.receiveEvent(getViewTag(), getEventName(), null);
}
}
Oops, something went wrong.

5 comments on commit 37f8134

@Richard-Cao

This comment has been minimized.

Show comment
Hide comment
@Richard-Cao

Richard-Cao Dec 9, 2015

Waring:Failed propType:Invalid prop 'colors[0]' of type 'number' supplied to 'AndroidSwipeRefreshLayout', expected 'string'.Check the render method of 'PullToRefreshViewAndroid'.

Richard-Cao replied Dec 9, 2015

Waring:Failed propType:Invalid prop 'colors[0]' of type 'number' supplied to 'AndroidSwipeRefreshLayout', expected 'string'.Check the render method of 'PullToRefreshViewAndroid'.

@bestander

This comment has been minimized.

Show comment
Hide comment
@bestander

bestander Dec 9, 2015

Contributor

The component expects colors to be strignified numbers.

Contributor

bestander replied Dec 9, 2015

The component expects colors to be strignified numbers.

@morenoh149

This comment has been minimized.

Show comment
Hide comment
@morenoh149

morenoh149 Dec 16, 2015

Contributor

I'm seeing the same error Warning:Failed propType:Invalid prop 'colors[0]' of type 'number' supplied to 'AndroidSwipeRefreshLayout', expected 'string'.Check the render method of 'PullToRefreshViewAndroid'.

when using colors={['#ff0000', '#00ff00', '#0000ff']} as demonstrated in http://facebook.github.io/react-native/docs/pulltorefreshviewandroid.html

Contributor

morenoh149 replied Dec 16, 2015

I'm seeing the same error Warning:Failed propType:Invalid prop 'colors[0]' of type 'number' supplied to 'AndroidSwipeRefreshLayout', expected 'string'.Check the render method of 'PullToRefreshViewAndroid'.

when using colors={['#ff0000', '#00ff00', '#0000ff']} as demonstrated in http://facebook.github.io/react-native/docs/pulltorefreshviewandroid.html

@bestander

This comment has been minimized.

Show comment
Hide comment
@bestander

bestander Dec 17, 2015

Contributor

I'll have a look at this, created a task internally

Contributor

bestander replied Dec 17, 2015

I'll have a look at this, created a task internally

@ide

This comment has been minimized.

Show comment
Hide comment
@ide

ide Dec 17, 2015

Collaborator

That's just a warning. Not urgent but would be nice to fix. See #4547

Collaborator

ide replied Dec 17, 2015

That's just a warning. Not urgent but would be nice to fix. See #4547

Please sign in to comment.