首页 > 代码库 > React Native八大Demo

React Native八大Demo




 参考资料:http://www.cnblogs.com/shaoting/p/7148240.html

下一个项目公司也打算使用react native.大致看了下原型设计,写几个小demo先试试水.特此记录下.

1.微信及朋友圈分享.QQ及朋友圈分享,微博分享,微信支付,支付宝支付.

2.导航条渐隐

3.通讯录

4.卡片式轮播

5.时间轴

6.图片+列表的组合效果

7.图片下拉放大

8.原生视频播放器

9.react-navigation的使用和变更

10.倒计时

11.多张图片查看

12.自定义页面加载指示器

......

1.微信及朋友圈分享,微信支付: https://github.com/yorkie/react-native-wechat

  QQ分享:https://github.com/reactnativecn/react-native-qq

  微博分享: https://github.com/reactnativecn/react-native-weibo

   支付宝支付没有找到,只能跳转原生进行支付.

   大神刚出炉的React Native 分享功能封装【一行代码,双平台分享】 支持平台:【QQ】【QQ空间】【微信】【朋友圈】【微博】         https://github.com/songxiaoliang/react-native-share

2.导航条渐隐,该项目我们打算使用react-navigation,但是该库的导航条使用不了渐隐,于是只能在需要导航条渐隐的地方,改用自己定义的导航条.

基本代码如下:

 

  1 /**
  2  * Created by shaotingzhou on 2017/5/9.
  3  */
  4 import React, { Component } from ‘react‘;
  5 import {
  6     AppRegistry,
  7     StyleSheet,
  8     Text,
  9     View,
 10     Image,
 11     TouchableOpacity,
 12     Platform,
 13     Dimensions,
 14     RefreshControl,
 15     FlatList,
 16     ActivityIndicator,
 17     ScrollView,
 18     TextInput
 19 } from ‘react-native‘;
 20 var {width,height} = Dimensions.get(‘window‘);
 21 var dataAry = []
 22 var start  = 0
 23 
 24 export default class OneDetailsFlat extends Component{
 25     //返回首页方法需要修改react-navigation库的源码.修改方法见:http://www.jianshu.com/p/2f575cc35780
 26     static navigationOptions = ({ navigation }) => ({
 27         header:null,
 28         title: ‘FlatList‘,
 29         headerStyle:{backgroundColor:‘rgba(255,255,255,0.0)‘},
 30         headerTintColor: ‘black‘,
 31         headerLeft:(
 32             <Text onPress={()=>navigation.goBack("Tab")}>返回首页</Text>
 33         ),
 34     })
 35 
 36     // 构造
 37     constructor(props) {
 38         super(props);
 39         // 初始状态
 40         for(start = 0;start<20;start++){
 41             var obj = {}
 42             obj.key = start
 43             dataAry.push(obj)
 44         }
 45 
 46         this.state = {
 47             opacity:0,
 48             dataAry: dataAry,
 50         };
 51     }
 52     render() {
 53         return (
 54             <View>
 55                 <FlatList
 56                     onScroll = {(e)=>{this.onScroll(e)}}
 57                     data = http://www.mamicode.com/{this.state.dataAry}
 58                     renderItem = {(item) => this.renderRow(item)}
 59                 />
 60                 <View style={{width:width,height:69,alignItems:‘center‘,flexDirection:‘row‘,position:‘absolute‘,top:0,backgroundColor:‘rgba(122,233,111,‘ + this.state.opacity + ‘)‘}}>
 61                     <Text style={{width:60,color:‘red‘}} onPress={()=>this.props.navigation.goBack(null)}>返回</Text>
 62                 </View>
 63             </View>
 64         );
 65     }
 66 
 67     //listView的renderRow
 68     renderRow =(item) =>{
 69             return(
 70                 <View style={{flexDirection:‘row‘,marginTop:5,marginLeft:5,borderWidth:1,marginRight:5,borderColor:‘#DEDEDE‘,backgroundColor:‘white‘}}>
 71                     <Image source={require(‘../image/one_selected.png‘)} style={{width:60,height:60,borderRadius:30,marginTop:5,marginBottom:5}}/>
 72                     <View style={{flexDirection:‘column‘,justifyContent:‘space-around‘,marginLeft:5}}>
 73                         <Text style={{fontSize:16}}>歌名: 彩虹彼岸</Text>
 74                         <View style={{flexDirection:‘row‘}}>
 75                             <Text style={{fontSize:14,color:‘#BDBDBD‘}}>歌手:虚拟歌姬</Text>
 76                             <Text style={{fontSize:14,color:‘#BDBDBD‘,marginLeft:10}}>专辑:react native</Text>
 77                         </View>
 78                     </View>
 79                 </View>
 80             )
 81     }
 82     onScroll =(e) =>{
 83         let y = e.nativeEvent.contentOffset.y;
 84         if(y < 10 ){
 85             this.setState({
 86                 opacity:0
 87             })
 88         }else if( y <= 69 && y>= 10){
 89             console.log(y/100)
 90             this.setState({
 91                 opacity:y/100
 92             })
 93         }else {
 94             this.setState({
 95                 opacity:1
 96             })
 97          }
 98     }
 99 
100 };
101 
102 var styles = StyleSheet.create({
103     container: {
104         flex: 1,
105         backgroundColor: ‘#F5FCFF‘,
106     },
107     welcome: {
108         fontSize: 20,
109         textAlign: ‘center‘,
110         margin: 10,
111     },
112     instructions: {
113         textAlign: ‘center‘,
114         color: ‘#333333‘,
115         marginBottom: 5,
116     }
117 });

 

技术分享

 

3.通讯录采用三方库即可满足.https://github.com/sunnylqm/react-native-alphabetlistview

4.卡片式轮播采用三方库即可满足.https://github.com/archriss/react-native-snap-carousel

5.时间轴效果. 该效果采用FlatList打造即可.

/**
* Created by shaotingzhou on 2017/7/10.
*/
import React, { Component } from ‘react‘;
import {
AppRegistry,
StyleSheet,
Text,
View,
FlatList,
Dimensions,
Image
} from ‘react-native‘;
var {width,height} = Dimensions.get(‘window‘);
var dataAry = []
import data from ‘./data.json‘
export default class TimerShaft extends Component {
// 构造
constructor(props) {
super(props);
// 初始状态
this.state = {
dataAry: dataAry,
};
}

render() {
return (
<View style={{marginTop:30}}>
<FlatList
data = http://www.mamicode.com/{this.state.dataAry}
renderItem = {(item) => this.renderRow(item)}
keyExtractor={this.keyExtractor}
/>
<View style={{width:1,height:height,backgroundColor:‘red‘,position:‘absolute‘,left:50}}></View>
</View>
);
}

renderRow =(item) =>{
if(item.item.text){
return(
<View style={{marginBottom:10,marginLeft:60}}>
<Text>{item.item.text}</Text>
</View>
)
}else{
return(
<View style={{flexDirection:‘row‘,marginBottom:10}}>
{/*左边*/}
<View style={{width:60,marginBottom:10}}>
<View style={{flexDirection:‘row‘,alignItems:‘center‘}}>
<Text>{item.item.time}</Text>
<View style={{width:10,height:10,borderRadius:5,backgroundColor:‘red‘,position:‘absolute‘,left:45}}></View>
</View>
</View>
{/*右边*/}
<View style={{backgroundColor:"#F2F2F2",marginLeft:5,width:width-70}} onLayout = {(event)=>this.onLayout(event)} >
<Text style={{}}>{item.item.content}</Text>
<View style={{flexDirection:‘row‘,flexWrap:‘wrap‘}}>
{this.renderImg(item.item.image)}
</View>
</View>
</View>
)

}



}

keyExtractor(item: Object, index: number) {
return item.id
}

onLayout = (event)=>{
console.log(event.nativeEvent.layout.height)
}

renderImg = (imgAry) =>{
var renderAry = []
for(var i = 0;i < imgAry.length; i++){
if(imgAry.length == 1){
renderAry.push(
<Image key={i} source={{uri:imgAry[0].url}} style={{width:200,height:200}}/>
)
}else if(imgAry.length == 2 || imgAry.length == 4){
renderAry.push(
<Image key={i} source={{uri:imgAry[i].url}} style={{width:(width-70)*0.5-2,height:(width-70)*0.5-2,marginLeft:1,marginTop:1}}/>
)
}else {
renderAry.push(
<Image key={i} source={{uri:imgAry[i].url}} style={{width:(width-70)/3-2,height:(width-70)/3-2,marginLeft:1,marginTop:1}}/>
)
}
}

return renderAry
}

componentDidMount() {
this.setState({
dataAry:data
})
}
}

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: ‘center‘,
alignItems: ‘center‘,
backgroundColor: ‘#F5FCFF‘,
},
welcome: {
fontSize: 20,
textAlign: ‘center‘,
margin: 10,
},
instructions: {
textAlign: ‘center‘,
color: ‘#333333‘,
marginBottom: 5,
},
});

 这个是数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
[
  {
    "id":1,
    "time":"01-05",
    "content":"今天,带二哈去节育,再不节育的话,就要被泰迪榨干了(ps:只有累死的牛,没有耕坏的地),关键一路上,那只小区里面的泰迪一路尾随.....这..这个.这是哪个女人养的泰迪,请告诉我你的职业和联系方式,你对我二哈做的,我十倍还你!!!夕阳西下,俩狗一路走,二哈好像知道自己的下场,一脸委屈的看着我,就像许仙看法海似得看着我,二哈,不是哥不成全你们俩,而是哥看着你心疼啊...........",
    "image":[
      {
        "imageId":47,
        "url":"https://ws1.sinaimg.cn/mw690/610dc034ly1ffwb7npldpj20u00u076z.jpg"
      }
    ]
  },
  {
    "id":2,
    "time":"01-04",
    "content":"今天在家躺尸,二哈在家吃刚买的狗粮,我蹲在旁边看着它吃,二哈看看我,看看碗,于是往旁边挪了挪",
    "image":[
      {
        "imageId":3,
        "url":"https://ws1.sinaimg.cn/large/610dc034gy1fh9utulf4kj20u011itbo.jpg"
      },
      {
        "imageId":4,
        "url":"https://ws1.sinaimg.cn/large/610dc034ly1fh8ox6bmjlj20u00u0mz7.jpg"
      },
      {
        "imageId":5,
        "url":"https://ws1.sinaimg.cn/large/610dc034ly1fh7hwi9lhzj20u011hqa9.jpg"
      },
      {
        "imageId":6,
        "url":"https://ws1.sinaimg.cn/large/610dc034ly1fgj7jho031j20u011itci.jpg"
      }
    ]
  },
  {
    "id":3,
    "time":"01-03",
    "content":"今天上班,把狗丢在家里,回来家没了~~~",
    "image":[
      {
        "imageId":7,
        "url":"https://ws1.sinaimg.cn/large/610dc034ly1fgi3vd6irmj20u011i439.jpg"
      },
      {
        "imageId":8,
        "url":"https://ws1.sinaimg.cn/large/610dc034ly1fgepc1lpvfj20u011i0wv.jpg"
      },
      {
        "imageId":9,
        "url":"https://ws1.sinaimg.cn/large/610dc034ly1fgchgnfn7dj20u00uvgnj.jpg"
      },
      {
        "imageId":10,
        "url":"https://ws1.sinaimg.cn/large/610dc034ly1fga6auw8ycj20u00u00uw.jpg"
      },
      {
        "imageId":11,
        "url":"https://ws1.sinaimg.cn/large/d23c7564ly1fg7ow5jtl9j20pb0pb4gw.jpg"
      },
      {
        "imageId":12,
        "url":"https://ws1.sinaimg.cn/large/610dc034ly1fgepc1lpvfj20u011i0wv.jpg"
      },
      {
        "imageId":13,
        "url":"https://ws1.sinaimg.cn/large/d23c7564ly1fg6qckyqxkj20u00zmaf1.jpg"
      },
      {
        "imageId":14,
        "url":"https://ws1.sinaimg.cn/large/610dc034ly1ffyp4g2vwxj20u00tu77b.jpg"
      },
      {
        "imageId":15,
        "url":"https://ws1.sinaimg.cn/large/610dc034ly1ffxjlvinj5j20u011igri.jpg"
      }
    ]
  },
  {
    "id":4,
    "time":"01-02",
    "content":"今天是2017年的第二天,两只单身狗在家附近的公园里的亭子躲雨,然后,来了只泰迪.然后亭子里就剩一只单身狗了(ps:我??).......",
    "image":[
      {
        "imageId":17,
        "url":"https://ws1.sinaimg.cn/large/610dc034ly1fgdmpxi7erj20qy0qyjtr.jpg"
      },
      {
        "imageId":27,
        "url":"https://ws1.sinaimg.cn/large/610dc034ly1ffla9ostxuj20ku0q2abt.jpg"
      },
      {
        "imageId":37,
        "url":"https://ws1.sinaimg.cn/large/d23c7564ly1fg6qckyqxkj20u00zmaf1.jpg"
      }
    ]
  },
  {
    "id":5,
    "time":"01-01",
    "content":"养狗前,钱是我的,养狗后,钱是它的~",
    "image":[
 
    ]
  },
  {
    "id":6,
    "text":"2017"
  },
  {
    "id":7,
    "time":"12-28",
    "content":"",
    "image":[
      {
        "imageId":1,
        "url":"https://ws1.sinaimg.cn/large/610dc034ly1fhegpeu0h5j20u011iae5.jpg"
      },
      {
        "imageId":2,
        "url":"https://ws1.sinaimg.cn/large/610dc034ly1fhb0t7ob2mj20u011itd9.jpg"
      }
    ]
  },
  {
    "id":8,
    "time":"12-25",
    "content":"今天下大雨,适合逛街,途中,遇见了一只二哈,于是花了2000买了下来",
    "image":[
      {
        "imageId":47,
        "url":"https://ws1.sinaimg.cn/large/610dc034ly1fgdmpxi7erj20qy0qyjtr.jpg"
      }
    ]
  }
]

  

 

 技术分享

 

6.图片+列表的组合效果

该效果采用ScrollView包含两个FlatList和一个ListView完成(ps:第三个横向的cell的单独使用FlatList可以,但是和其他组件搭配就错误.....)

 

  1 /**
  2  * Created by shaotingzhou on 2017/7/6.
  3  */
  4 /**
  5  * Sample React Native App
  6  * https://github.com/facebook/react-native
  7  * @flow
  8  */
  9 
 10 import React, { Component } from ‘react‘;
 11 import {
 12     AppRegistry,
 13     StyleSheet,
 14     Text,
 15     View,
 16     ScrollView,
 17     Dimensions,
 18     FlatList,
 19     SectionList,
 20     Image,
 21     ListView
 22 } from ‘react-native‘;
 23 var {width,height} = Dimensions.get(‘window‘);
 24 var dataAry = []
 25 var dataAryOne = []
 26 var dataAryTwo = []
 27 var ds = new ListView.DataSource({rowHasChanged:(r1,r2)=> r1 !== r2});
 28 
 29 export default class Main extends Component {
 30     // 构造
 31     constructor(props) {
 32         super(props);
 33         // 初始状态
 34         for(var i = 0;i<100;i++){
 35             var obj = {}
 36             obj.key = i
 37             dataAry.push(obj)
 38         }
 39 
 40         // 初始状态
 41         for(var i = 0;i<10;i++){
 42             var obj = {}
 43             obj.key = i
 44             dataAryOne.push(obj)
 45         }
 46 
 47         // 初始状态
 48         for(var i = 0;i<5;i++){
 49             var obj = {}
 50             obj.key = i
 51             dataAryTwo.push(obj)
 52         }
 53 
 54         this.state = {
 55             index:1,
 56             dataAry: dataAry,
 57             dataAryOne:dataAryOne,
 58             dataSource:ds.cloneWithRows(dataAryTwo)
 59         };
 60     }
 61 
 62     render() {
 63         return (
 64             <View style={{flex:1}}>
 65                 <View style={{backgroundColor:‘cyan‘,height:69,justifyContent:‘center‘,alignItems:‘center‘}}>
 66                     <Text>导航条</Text>
 67                 </View>
 68                 <ScrollView
 69                     style={{flex:1}}
 70                     stickyHeaderIndices = {[1]}
 71                 >
 72 
 73                     <Image source={require(‘./1.gif‘)} style={{width:width,height:200}} />
 74 
 75                     <View style={{backgroundColor:‘yellow‘}}>
 76                         <View style={{flexDirection:‘row‘,justifyContent:‘space-around‘,marginTop:20}}>
 77                             <Text onPress={()=>{this.onClickOne()}} style={{color:this.state.index == 1 ? ‘red‘ : ‘cyan‘}}>11111</Text>
 78                             <Text onPress={()=>{this.onClickTwo()}} style={{color:this.state.index == 2 ? ‘red‘ : ‘cyan‘}}>22222</Text>
 79                             <Text onPress={()=>{this.onClickThree()}} style={{color:this.state.index == 3 ? ‘red‘ : ‘cyan‘}}>33333</Text>
 80                         </View>
 81                     </View>
 82 
 83                     {this.bottomViewRender()}
 84 
 85                 </ScrollView>
 86 
 87             </View>
 88         );
 89     }
 90     bottomViewRender = ()=>{
 91         if(this.state.index == 1){
 92             return(
 93                 <FlatList
 94                     data = http://www.mamicode.com/{this.state.dataAry}
 95                     renderItem = {(item) => this.renderRow(item)}
 96                 />
 97             )
 98         }else if(this.state.index == 2){
 99             return(
100                 <FlatList
101                     data = http://www.mamicode.com/{this.state.dataAryOne}>

 

技术分享

7.图片上拉放大:https://github.com/lelandrichardson/react-native-parallax-view

8.原生视频播放器:https://github.com/cornedor/react-native-video-player

9.react-navigation的使用和变更:

使用介绍:  http://www.jianshu.com/p/2f575cc35780

demo: https://github.com/pheromone/navigationDemo 

 在使用react-navigation中遇到几个难点:

  • 1.跳至相应路由(如返回首页功能).  http://www.jianshu.com/p/2f575cc35780
  • 2.防止点击过快,跳界面两次.  https://github.com/react-community/react-navigation/pull/1348/files
  • 3.static中使用this.  http://www.jianshu.com/p/2f575cc35780

10.倒计时:https://github.com/kkkelicheng/ReactNative-CountDownButton

优点:  不会因为进入后台而停止读秒

         支持同个页面再次进入时,智能的判断读秒时间,显示是否继续计时

11.多张图片查看:https://github.com/ascoders/react-native-image-viewer

12.因为下个项目是有关狗狗的,页面加载需要一个指示器.在不考虑性能上暂时使用gif图+Modal实现.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */
 
import React, { Component } from ‘react‘;
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
    Modal,
    Image,
    Dimensions
} from ‘react-native‘;
var {width,height} = Dimensions.get(‘window‘);
 
export default class model extends Component {
  // 构造
    constructor(props) {
      super(props);
      // 初始状态
      this.state = {
          visible:true
      };
    }
  render() {
    return (
      <View>
        <Modal
            visible={this.state.visible}    // 根据isModal决定是否显示
        >
          <View style={{backgroundColor:‘rgba(0,0,0,0.4)‘,width:width,height:height,justifyContent:‘center‘,alignItems:‘center‘}}>
            <Image source={require(‘./food.gif‘)} style={{width:120,height:120,borderRadius:5}}/>
            <Text style={{color:‘white‘}}>狗生思考中...</Text>
          </View>
        </Modal>
      </View>
    );
  }
 
 
    componentDidMount() {
      //模拟请求数据,请求OK,把visible置为false即可
        this.timer = setTimeout(
            () => {
                this.setState({
                    visible:false
                })
            },
            1000
        );
    }
 
 
    componentWillUnmount() {
        this.timer && clearTimeout(this.timer);
    }
 
}
 
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: ‘center‘,
    alignItems: ‘center‘,
    backgroundColor: ‘#F5FCFF‘,
  },
  welcome: {
    fontSize: 20,
    textAlign: ‘center‘,
    margin: 10,
  },
  instructions: {
    textAlign: ‘center‘,
    color: ‘#333333‘,
    marginBottom: 5,
  },
});
 
AppRegistry.registerComponent(‘model‘, () => model);

  技术分享

其中,关于Android下使用gif图需要简单配置下,请查看http://www.cnblogs.com/shaoting/p/5934725.html的第25条内容.

React Native八大Demo