下一个项目公司也打算使用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-smart-alipay 或者 react-native-payment-alipay 或者 react-native-alipay

   微信支付: react-native-wechat

  想要秀操作,通过交互原生支付也可以.

   大神刚出炉的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 = {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 = {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,
},
});

 这个是数据:

[
  {
    "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 = {this.state.dataAry}
 95                     renderItem = {(item) => this.renderRow(item)}
 96                 />
 97             )
 98         }else if(this.state.index == 2){
 99             return(
100                 <FlatList
101                     data = {this.state.dataAryOne}
102                     renderItem = {(item) => this.renderRowOne(item)}
103                 />
104             )
105         }else {
106             //这里横向只能使用ListView或者SctionList.FLatList设置横向属性报错
107             return(
108                 <ListView
109                     dataSource={this.state.dataSource}
110                     renderRow={this.renderRowTwo}
111                     contentContainerStyle={styles.listViewStyle}
112                 />
113             )
114         }
115 
116     }
117 
118 
119     onClickOne =()=>{
120         this.setState({
121             index:1,
122         })
123     }
124     onClickTwo =()=>{
125         this.setState({
126             index:2,
127         })
128     }
129     onClickThree =()=>{
130         this.setState({
131             index:3,
132         })
133     }
134 
135 
136     renderRow =(item) =>{
137         return(
138             <View style={{flexDirection:'row',marginTop:5,marginLeft:5,borderWidth:1,marginRight:5,borderColor:'#DEDEDE',backgroundColor:'white'}}>
139                 <View style={{flexDirection:'column',justifyContent:'space-around',marginLeft:5}}>
140                     <Text style={{fontSize:16}}>歌名: 彩虹彼岸</Text>
141                     <View style={{flexDirection:'row'}}>
142                         <Text style={{fontSize:14,color:'#BDBDBD'}}>歌手:虚拟歌姬</Text>
143                         <Text style={{fontSize:14,color:'#BDBDBD',marginLeft:10}}>专辑:react native</Text>
144                     </View>
145                 </View>
146             </View>
147         )
148 
149     }
150 
151     renderRowOne =(item) =>{
152         return(
153             <View style={{flexDirection:'row',marginTop:5,marginLeft:5,borderWidth:1,marginRight:5,borderColor:'#DEDEDE',backgroundColor:'white'}}>
154                 <View style={{flexDirection:'row'}}>
155                     <Text style={{fontSize:14,color:'#BDBDBD'}}>歌手:虚拟歌姬</Text>
156                     <Text style={{fontSize:14,color:'#BDBDBD',marginLeft:10}}>专辑:react native</Text>
157                 </View>
158             </View>
159         )
160 
161     }
162 
163     renderRowTwo(rowData){
164         return(
165                 <View style={styles.innerViewStyle}>
166                     <Image source={require('./2.jpeg')} style={{width:150,height:150}} />
167                     <Text>你的名字</Text>
168                 </View>
169         );
170     }
171     //
172     // renderRowTwo =(item) =>{
173     //
174     //     return (
175     //         <View>
176     //             {
177     //                 dataAryTwo.map(function (item, i) {
178     //                 return (
179     //                     <View style={{marginLeft:5}} key={i}>
180     //                         <Image source={require('./2.jpeg')} style={{width:150,height:150}} />
181     //                         <Text>你的名字</Text>
182     //                     </View>
183     //                 );
184     //             })
185     //             }
186     //         </View>
187     //     )
188     // }
189 
190 
191 }
192 
193 const styles = StyleSheet.create({
194     container: {
195         flex: 1,
196         justifyContent: 'center',
197         alignItems: 'center',
198         backgroundColor: '#F5FCFF',
199     },
200     welcome: {
201         fontSize: 20,
202         textAlign: 'center',
203         margin: 10,
204     },
205     instructions: {
206         textAlign: 'center',
207         color: '#333333',
208         marginBottom: 5,
209     },
210     listViewStyle:{
211         //改变主轴方向
212         flexDirection:'row',
213         //多行显示
214         flexWrap:'wrap'
215     },
216 });

 

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中遇到几个难点:

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

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

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

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

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

/**
 * 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条内容.