de组件 native react_react native react-router 组件跳转 - CSDN
  • 列表作为移动应用中承载主题内容信息的重要组件React Native早先出道的ListView坑了不少人,今天让我们一起来学习一下,打开React Native列表组件的正确姿势。本场Chat的内容包括: 我们什么时候需要用列表组件 ...

    ListView,FlatList,SectionList...是否傻傻分不清楚?超长列表怎么优化?下拉刷新怎么玩?列表作为移动应用中承载主题内容信息的重要组件,React Native早先出道的ListView坑了不少人,今天让我们一起来学习一下,打开React Native列表组件的正确姿势。本场Chat的内容包括:

    • 我们什么时候需要用列表组件
    • 认识列表组件:ListView, FlatList, SectionList, VirtualizedList
    • 基本用法
    • 常用属性
    • Multi-column
    • 下拉刷新
    • 超长列表的优化
    • 可展开的多级列表
    • 你还可能需要知道的事

    阅读全文: http://gitbook.cn/gitchat/activity/5913324de530257800238ad8

    您还可以下载 CSDN 旗下精品原创内容社区 GitChat App ,阅读更多 GitChat 专享技术内容哦。

    FtooAtPSkEJwnW-9xkCLqSTRpBKX

    展开全文
  • 组件进行封装成React Native平台播放器Video组件,大家可以使用该组件进行播放视频啦~不过支持React Native的版本最低0.19版本。二.1.1. 运行命令进行安装npm install react-native-video --save1.2.i

    开源项目地址: https://github.com/brentvatne/react-native-login

    一.

    项目介绍

    该组件进行封装成React Native平台播放器Video组件,大家可以使用该组件进行播放视频啦~不过支持React Native的版本最低0.19版本。


    二.

    1.1. 运行命令进行安装

    npm install react-native-video --save

    1.2.iOS版本

    以上的命令运行完成安装组件之后,如果你需要其他的应用也可以在你的Video组件上面播放音乐,视频等。你可以在AppDelegate.m文件作如下处理:

    #import <AVFoundation/AVFoundation.h>  // import
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
      ...
      [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];  // allow
      ...
    }

    1.3.Android版本

    首先复制你的Video文件到android项目的 android/app/src/main/res/raw/的文件夹中,然后做如下相关处理:

    1.4.android/settings.gradle文件

    include ':RCTVideo', ':app'
    project(':RCTVideo').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-video/android')

    1.5.android/app/build.gradle文件

    dependencies {
       ...
       compile project(':RCTVideo')
    }

    1.6.MainActivity.java文件修改

    首先在文件的头部,导入相关包:

    import com.brentvatne.react.ReactVideoPackage;
    

    然后在方法中添加:

    .addPackage(new ReactVideoPackage())

    三. 实例

    
    import React, { Component } from 'react';
    import {
        AppRegistry,
        StyleSheet,
        TextInput,
        ListView,
        TouchableOpacity,
        Image,
        ScrollView,
        Text,
        Alert,
        View
    } from 'react-native';
    import  Video from 'react-native-video'
    
    
    
    export default class extends Component  {
    
    
            render(){
    
                return(
                     //方法一:
    
    
                     <Video source={{uri: "http://14.29.86.13/vlive.qqvideo.tc.qq.com/n00151ljmvl.p202.5.mp4?sdtfrom=v1010&amp;guid=68f3b8fc1fcc716ee248eba5de706f32&amp;vkey=AB781962EAB8A3E80E7F48B5D1864BCFE4C577B072E96C21A88E032765C2DDCC5F3399F4C846EF005E5017347C5F05369F49C83C1FC833077BCCF336962264F25805A09F04693E6028296F3D6F5CCBFA6FF7AD78C6040BE86A5CCB26F9F20DAA37B3DFBFB84768B4E07BD4E9EB30F10483ECAAB57ABFF271#t=198"}} // Can be a URL or a local file.
                       rate={1.0}                   // 控制暂停/播放,0 代表暂停
                       volume={1.0}                 // 声音的放大倍数,0 代表没有声音,就是静音muted, 1 代表正常音量 normal,更大的数字表示放大的倍数
                       muted={false}                //true代表静音,默认为false.
                       paused={false}               // Pauses playback entirely.
                       resizeMode="cover"           // 视频的自适应伸缩铺放行为,
                       repeat={true}                // 是否重复播放
                       onLoadStart={this.loadStart} // 当视频开始加载时的回调函数
                       onLoad={this.setDuration}    // 当视频加载完毕时的回调函数
                       onProgress={this.setTime}    // 进度控制,每250ms调用一次,以获取视频播放的进度
                       onEnd={this.onEnd}           // 当视频播放完毕后的回调函数
                       onError={this.videoError}    // 当视频不能加载,或出错后的回调函数
                       style={styles.backgroundVideo}
                     />
    
    
    
                );
    
            }
    
    }
    
    const styles = StyleSheet.create({
        backgroundVideo: {
            position: 'absolute',
            top: 0,
            left: 0,
            bottom: 0,
            right: 0,
        },
    });
    
    
    
    
    

    关于更多例子,大家可以去https://github.com/brentvatne/react-native-login 下载实例使用

    展开全文
  • 一、视频组件 这里用:react-native-video,详见官网:https://github.com/react-native-community/react-native-video 添加组件 yarn add --save react-native-video react-native link我很幸运,两个命令都成功了...

    一、视频组件

    yarn add --save react-native-video
    react-native link

    我很幸运,两个命令都成功了,如果link不成功,跟着这篇文章:https://www.npmjs.com/package/react-native-video

    • 编码
    import Video from 'react-native-video';
    ...
    <Video ref="myvideo" 
                              source={{uri:"http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"}}
                              style={{width:width,height:180, top: 0, left: 0, bottom: 0, right: 0,}}
                              rate={1.0}                              // 0 is paused, 1 is normal. 
                              volume={1.0}                            // 0 is muted, 1 is normal. 
                              muted={false}                           // Mutes the audio entirely. 
                              paused={false}                          // Pauses playback entirely. 
                              resizeMode="cover"                      // Fill the whole screen at aspect ratio.* 
                              repeat={true}                           // Repeat forever. 
                              playInBackground={false}                // Audio continues to play when app entering background. 
                              playWhenInactive={false}                // [iOS] Video continues to play when control or notification center are shown. 
                              ignoreSilentSwitch={"ignore"}           // [iOS] ignore | obey - When 'ignore', audio will still play with the iOS hard silent switch set to silent. When 'obey', audio will toggle with the switch. When not specified, will inherit audio settings as usual. 
                              progressUpdateInterval={250.0}          // [iOS] Interval to fire onProgress (default to ~250ms) 
                              onLoadStart={this.loadStart}            // Callback when video starts to load 
                              onLoad={this.setDuration}               // Callback when video loads 
                              onProgress={this.setTime}               // Callback every ~250ms with currentTime 
                              onEnd={this.onEnd}                      // Callback when playback finishes 
                              onError={this.videoError}               // Callback when video cannot be loaded 
                              onBuffer={this.onBuffer}                // Callback when remote video is buffering 
                              onTimedMetadata={this.onTimedMetadata}  // Callback when the stream receive some metadata 

    官网都讲解的挺详细的,具体还是看官网吧!


    二、样式布局
    react-native的布局常用的有4个:flexDirection、justifyContent、flex、alignItems,其中flex最简单,就是代表所占的比例,比如有两个,上下排列,其中一个flex:1,另一个flex:2, 则两者在一个屏幕里面的比例是1:2,第一个占了1/(1+2)个屏幕,第二个占了2/(1+2),如果两者都是flex:1,则它们所占的面积相等。其它3个布局有点复杂,看下图的说明:


    这里写图片描述


    这里写图片描述


    这里写图片描述


    这里还有一点,我是直接把View理解为div的,所以我们的首页布局,可以设计成如下:


    这里写图片描述


    首页是由轮播图在顶部,大约占1/4,下面是循环的用户内容,每个内容看成一个整体,我把它定为一个类叫做:,这个的布局分为4部分,第一部分是最上面用户信息部分,第二是视频部分,第三是点赞、评论、分享,第4部分是前3条评论,每个部分都有黑色的底部边界。

    类如下,忽略视频部分,可以用图片代替:

      class COLL extends Component{
          constructor(props){
            super(props);
            this.state = { detailTitle:'aaaa'};
          }
          render(){
            return(
                  /*总体的布局,沿着竖轴排列*/
                  <View style={{flexDirection:'column', backgroundColor:'#363636',borderBottomWidth:3,borderBottomColor:'#121212'}}>
    
                      {/* 第一部分:信息部分,里面分为3个列,沿着水平轴排列 */}
                      <View style={{flexDirection:'row',padding:10, justifyContent:'center',flex:1,alignItems:'center'}} >
                          {/*头像*/}
                          <View style={{flexDirection: 'row',flex:1}} >
                               <Image source={require('./img/profile.jpg')} style={styles.imgProfile}></Image>
                          </View>
                          {/*作者信息和发布时间/观看信息*/}
                          <View style={{flexDirection:'row',justifyContent:'center',flex:6,alignItems:'center'}} >
                              {/* 作者信息 */}
                              <View style={{flexDirection:'column',flex:1,justifyContent:'flex-start'}} >
                                  <Text style={{flex:1,color:'#fff',fontSize: 12,color:'#1C86EE',textAlign:'left'}}>刘邦</Text>
                                  <Text style={{flex:1,color:'#fff',fontSize: 10,textAlign:'left'}}>Duang</Text>
                              </View>
                              {/* 发布时间/观看信息 */}
                              <View style={{flexDirection:'column',flex:1,justifyContent:'flex-end'}} >
                                  {/* 发布时间 */}
                                  <Text style={{flex:1,color:'#fff',fontSize: 12,textAlign:'right'}}>4天前</Text>
                                  {/* 观看 */}
                                  <View style={{flexDirection:'row',justifyContent:'flex-end',flex:1}} >
                                      <Text style={{flex:4}}></Text>
                                      <Image source={require('./img/view.png')} style={{width:16,height:16}}></Image>
                                      <Text style={{flex:1,color:'#fff',fontSize: 10,textAlign:'left'}}>4563</Text>
                                  </View>
                              </View>
                          </View>
                      </View>
    
                      {/* 第二部分:视频 就一个View*/}
                      <View style={{flexDirection:'row',justifyContent:'center',flex:1,alignItems:'center'}} >
                             {/* <Image source={require('./img/profile.jpg')} style={{width:width,height:150}}></Image> */}
                              <Video ref="myvideo" 
                              source={{uri:"http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"}}
                              style={{width:width,height:180, top: 0, left: 0, bottom: 0, right: 0,}}
                              rate={1.0}                              // 0 is paused, 1 is normal. 
                              volume={1.0}                            // 0 is muted, 1 is normal. 
                              muted={false}                           // Mutes the audio entirely. 
                              paused={false}                          // Pauses playback entirely. 
                              resizeMode="cover"                      // Fill the whole screen at aspect ratio.* 
                              repeat={true}                           // Repeat forever. 
                              playInBackground={false}                // Audio continues to play when app entering background. 
                              playWhenInactive={false}                // [iOS] Video continues to play when control or notification center are shown. 
                              ignoreSilentSwitch={"ignore"}           // [iOS] ignore | obey - When 'ignore', audio will still play with the iOS hard silent switch set to silent. When 'obey', audio will toggle with the switch. When not specified, will inherit audio settings as usual. 
                              progressUpdateInterval={250.0}          // [iOS] Interval to fire onProgress (default to ~250ms) 
                              onLoadStart={this.loadStart}            // Callback when video starts to load 
                              onLoad={this.setDuration}               // Callback when video loads 
                              onProgress={this.setTime}               // Callback every ~250ms with currentTime 
                              onEnd={this.onEnd}                      // Callback when playback finishes 
                              onError={this.videoError}               // Callback when video cannot be loaded 
                              onBuffer={this.onBuffer}                // Callback when remote video is buffering 
                              onTimedMetadata={this.onTimedMetadata}  // Callback when the stream receive some metadata 
                              />
                      </View>
    
                      {/* 第三部分: 点赞评论分享 */}
                      <View style={{flexDirection:'row',justifyContent:'center',flex:1,alignItems:'center',borderBottomWidth:1,borderBottomColor:'#87CEFA'}} >
                          <View style={styles.icon} borderRightWidth={1} borderRightColor={'#87CEFA'}>
                               <View style={{flexDirection:'row',justifyContent:'flex-end',flex:1,alignItems:'center'}} >
                                   <Image source={require('./img/zan.jpg')} style={styles.imgIcon}></Image>
                               </View>
                               <Text style={styles.iconIcon}>41</Text>
                          </View>
                          <View style={styles.icon} borderRightWidth={1} borderRightColor={'#87CEFA'}>
                               <View style={{flexDirection:'row',justifyContent:'flex-end',flex:1,alignItems:'center'}} >
                                   <Image source={require('./img/comment.jpg')} style={styles.imgIcon}></Image>
                               </View>
                               <Text style={styles.iconIcon}>26</Text>
                          </View>
                          <View style={styles.icon} >
                               <View style={{flexDirection:'row',justifyContent:'flex-end',flex:1,alignItems:'center'}} >
                                   <Image source={require('./img/share.jpg')} style={styles.imgIcon}></Image>
                               </View>
                               <Text style={styles.iconIcon}>分享</Text>
                          </View>
                      </View>
    
                      {/* 第四部分: 评论内容 */}
                      <View style={{flexDirection:'row',justifyContent:'flex-start',flex:1,alignItems:'center'}} >
                          <View style={{flexDirection:'column',justifyContent:'flex-start',alignItems:'center'}}>
                              <View style={{flexDirection:'row',justifyContent:'flex-start',flex:1,alignItems:'center',paddingTop:10,paddingLeft:10}} >
                                  <Text style={{fontSize: 11,color:'#1C86EE'}}>刘邦2</Text>
                                  <Text style={{color:'#fff',fontSize: 11}}>回复</Text>
                                  <Text style={{fontSize: 11,color:'#1C86EE'}}>刘邦</Text>
                                  <Text style={{color:'#fff',fontSize: 11}}>:刘邦</Text>
                              </View>
                              <View style={{flexDirection:'row',justifyContent:'flex-start',flex:1,alignItems:'center',paddingLeft:10}} >
                                  <Text style={{fontSize: 11,color:'#1C86EE'}}>刘邦</Text>
                                  <Text style={{color:'#fff',fontSize: 11}}>回复</Text>
                                  <Text style={{fontSize: 11,color:'#1C86EE'}}>刘邦</Text>
                                  <Text style={{color:'#fff',fontSize: 11}}>:刘邦</Text>
                              </View>
                              <View style={{flexDirection:'row',justifyContent:'flex-start',flex:1,alignItems:'center',paddingLeft:10,paddingBottom:10}} >
                                  <Text style={{fontSize: 11,color:'#1C86EE'}}>刘邦</Text>
                                  <Text style={{color:'#fff',fontSize: 11}}>回复</Text>
                                  <Text style={{fontSize: 11,color:'#1C86EE'}}>刘邦</Text>
                                  <Text style={{color:'#fff',fontSize: 11}}>:刘邦</Text>
                              </View>
                          </View>
                      </View>
    
                  </View>
              );
          }
    }
    


    三、注意事项

    1.如果出现视频读取不出来的问题,看看有没有遗漏了设置
    2.如果配置都对,重新在android studio中编译一下项目
    3.如果以上两个方法试了还是不行,换个小点的视频,可能是格式和大小
    4.如果发现在模拟器可以看视频,到了真机读取不出来,我也不知道是什么原因


    下一篇:开发一个基于React Native的简易demo–读取网络数据并展示

    展开全文
  • 1.在index.Android.js下书写 /**  * Created by TinySymphony on 2017-...import React, {Component} from 'react'; import {  StyleSheet,  AppRegistry,  View,  Text,  Easing,  Sc

    1.在index.Android.js下书写

    /**
     * Created by TinySymphony on 2017-03-23.
     */

    import React, {Component} from 'react';
    import {
      StyleSheet,
      AppRegistry,
      View,
      Text,
      Easing,
      ScrollView
    from 'react-native';

    import ZoomImage from './ZoomImage';

    export default class App extends Component {
      constructor(props) {
        super(props);
        this.text = '';
      }
      render() {
        return (
          <ScrollView>
            <View style={styles.content}>
              <Text style={styles.txt}>Zoom Image Examples! Try to click them~</Text>

              <View style={styles.imgItem}>
                <ZoomImage
                  source={{uri: 'https://avatars2.githubusercontent.com/u/7685233?v=3&s=460'}}
                  imgStyle={{width: 220, height: 220}}
                  style={styles.img}
                  />
              </View>

              <View style={styles.imgItem}>
                <ZoomImage
                  source={{uri: 'https://ooo.0o0.ooo/2017/03/31/58de0e9b287f6.jpg'}}
                  imgStyle={{width: 250, height: 230}}
                  style={styles.img}
                  enableScaling={true}
                  />
              </View>

              <View style={styles.imgItem}>
                <ZoomImage
                  source={{uri: 'https://ooo.0o0.ooo/2017/03/31/58de0e9b28328.jpg'}}
                  imgStyle={{width: 250, height: 240}}
                  style={styles.img}
                  easingFunc={Easing.bounce}
                  />
              </View>

            </View>
          </ScrollView>
        );
      }
    }

    const styles = StyleSheet.create({
      content: {
        justifyContent: 'center',
        alignItems: 'center'
      },
      txt: {
        fontSize: 16,
        marginTop: 50,
        color: '#333'
      },
      img: {
        borderWidth: 3,
        borderColor: '#45b7d5'
      },
      imgItem: {
        justifyContent: 'center',
        alignItems: 'center',
        margin: 20
      }
    });

    AppRegistry.registerComponent('App', () => App);
    // export default App;
    // import { AppRegistry } from 'react-native';

    // import App from './App';

    // AppRegistry.registerComponent('Example', (): App => App);

    2.ZoomImage.js文件

    import React, {PropTypes, Component} from 'react';
    import {
      View,
      Text,
      Image,
      Modal,
      Easing,
      StyleSheet,
      PanResponder,
      NativeModules,
      findNodeHandle,
      Dimensions,
      TouchableWithoutFeedback
    from 'react-native';
    import Animation from './Animation';
    const winWidth = Dimensions.get('window').width;
    const winHeight = Dimensions.get('window').height;
    const winRatio = winWidth / winHeight;

    const RCTUIManager = NativeModules.UIManager;

    class ZoomImage extends Component {
      static propTypes = {
        startCapture: PropTypes.bool,
        moveCapture: PropTypes.bool,
        responderNegotiate: PropTypes.func,
        easingFunc: PropTypes.func,
        duration: PropTypes.number,
        enableScaling: PropTypes.bool
      }
      static defaultProps = {
        startCapture: false,
        moveCapture: false,
        duration: 800,
        easingFunc: Easing.ease,
        enableScaling: false
      }
      constructor(props) {
        super(props);
        this.state = {
          maxSize: {
            width: 0,
            height: 0
          },
          isModalVisible: false
        };
        this.enableModal = false;
        this.closeModal = this.closeModal.bind(this);
        this.openModal = this.openModal.bind(this);
        this.getMaxSizeByRatio = this.getMaxSizeByRatio.bind(this);
      }
      getMaxSizeByRatio (ratio) {
        return {
          width: ratio >= winRatio ? winWidth : winWidth / ratio,
          height: ratio >= winRatio ? winWidth / ratio : winHeight
        };
      }
      componentDidMount () {
        if (this.props.source.uri) {
          Image.getSize(this.props.source.uri, (wh=> {
            this.setState((state=> {
              state.maxSize = this.getMaxSizeByRatio(w / h);
              this.enableModal = true;
            });
          });
        } else {
          this.setState((state=> {
            state.maxSize = this.getMaxSizeByRatio(this.props.imgStyle.width / this.props.imgStyle.height);
            this.enableModal = true;
          });
        }
      }
      openModal () {
        if (!this.refs.view || !this.enableModal) return;
        RCTUIManager.measure(findNodeHandle(this.refs.view), (xywhpxpy=> {
          this.originPosition = {x, y, w, h, px, py};
        });
        this.setState({
          isModalVisible: true
        });
      }
      closeModal () {
        this.setState({
          isModalVisible: false
        });
      }
      render () {
        return (
          <TouchableWithoutFeedback style={this.props.imgStyle}
            onPress={this.openModal}
            ref="view">
            <View style={this.props.style}>
              <Image
                source={this.props.source}
                resizeMode={this.props.resizeMode}
                style={this.props.imgStyle}/>
              <ImageModal
                visible={this.state.isModalVisible}
                onClose={this.closeModal}
                originPosition={this.originPosition}
                size={this.state.maxSize}
                minAlpha={this.props.minAlpha}
                source={this.props.source}
                duration={this.props.duration}
                easingFunc={this.props.easingFunc}
                enableScaling={this.props.enableScaling}/>
            </View>
          </TouchableWithoutFeedback>
        );
      }
    }

    class ImageModal extends Component {
      constructor(props) {
        super(props);
        this._initModalStyle = {
          style: {
            backgroundColor: 'rgba(0, 0, 0, 1)'
          }
        };
        this._modalStyle = JSON.parse(JSON.stringify(this._initModalStyle));
        this._initContentStyle = {
          style: {
            top: 0,
            bottom: 0,
            left: 0,
            right: 0
          }
        };
        this._contentStyle = JSON.parse(JSON.stringify(this._initContentStyle));
        this._initImgSize = {
          style: this.props.size
        };
        this._imgSize = JSON.parse(JSON.stringify(this._initImgSize));
        this._inAnimation = false;
        this._setNativeProps = this._setNativeProps.bind(this);
        this._closeModalByTap = this._closeModalByTap.bind(this);
        this._closeModal = this._closeModal.bind(this);
        this._rebounce = this._rebounce.bind(this);
        this._touchPositionCheck = this._touchPositionCheck.bind(this);
        this._updateNativeStyles = this._updateNativeStyles.bind(this);
        this._pan = PanResponder.create({
          onStartShouldSetPanResponder: this._onStartShouldSetPanResponder.bind(this),
          onStartShouldSetPanResponderCapture: (evtgestureState=> this.props.startCapture,
          onMoveShouldSetPanResponder: this._onMoveShouldSetPanResponder.bind(this),
          onMoveShouldSetPanResponderCapture: (evtgestureState=> this.props.moveCapture,
          onPanResponderTerminationRequest: (evtgestureState=> true,
          onPanResponderGrant: this._handlePanResponderGrant.bind(this),
          onPanResponderMove: this._handlePanResponderMove.bind(this),
          onPanResponderRelease: this._handlePanResponderEnd.bind(this),
          onPanResponderTerminate: this._handlePanResponderEnd.bind(this),
          onShouldBlockNativeResponder: (evtgestureState=> true
        });
      }
      _onStartShouldSetPanResponder (evtgestureState) {
        // set responder for tapping when the drawer is open
        // TODO: tap close
        if (this._inAnimation) return;
        return false;
      }
      _onMoveShouldSetPanResponder (evtgestureState) {
        // custom pan responder condition function
        if (this._inAnimation) return;
        if (this.props.responderNegotiate && this.props.responderNegotiate(evt, gestureState) === falsereturn false;
        if (this._touchPositionCheck(gestureState)) {
          return true;
        }
        return false;
      }
      _handlePanResponderGrant(evtgestureState) {
      }
      _handlePanResponderMove (evtgestureState) {
        const {dy= gestureState;
        this._updateNativeStyles(dy);
      }
      _handlePanResponderEnd (evtgestureState) {
        const {dy= gestureState;
        if (dy > 0.4 * winHeight) {
          this._closeModal(true);
        } else if (-dy > 0.4 * winHeight) {
          this._closeModal(false);
        } else {
          this._rebounce();
        }
      }
      _touchPositionCheck(gestureState) {
        const {dxdy= gestureState;
        if (Math.abs(dy) <= Math.abs(dx)) {
          return false;
        }
        return true;
      }
      _closeModal(isDown) {
        const {easingFunconClose= this.props;
        let current = this._contentStyle.style.top;
        this._inAnimation = true;
        new Animation({
          start: current,
          end: isDown ? winHeight : -winHeight,
          duration: 140,
          easingFunc,
          onAnimationFrame: (val=> {
            this._updateNativeStyles(val);
          },
          onAnimationEnd: () => {
            this._inAnimation = false;
            onClose();
            this._setNativeProps(true);
          }
        }).start();
      }
      _closeModalByTap() {
        if (this._inAnimation) {
          return false;
        }
        this._closeModal(true);
      }
      _rebounce(isDown) {
        const {durationeasingFunc= this.props;
        let current = this._contentStyle.style.top;
        this._inAnimation = true;
        new Animation({
          start: current,
          end: 0,
          duration: Math.abs(current / winHeight) * duration,
          easingFunc,
          onAnimationFrame: (val=> {
            this._updateNativeStyles(val);
          },
          onAnimationEnd: () => {
            this._inAnimation = false;
          }
        }).start();
      }
      _updateNativeStyles(dy) {
        const {
          width,
          height
        } = this.props.size;
        // this._contentStyle.style.left = dx;
        // this._contentStyle.style.right = -dx;
        this._contentStyle.style.top = dy;
        this._contentStyle.style.bottom = -dy;
        this._modalStyle.style.backgroundColor = `rgba(0, 0, 0, ${1 - Math.abs(dy) / winHeight * 0.9})`;
        if (this.props.enableScaling) {
          this._imgSize.style.width = width * (1 - Math.abs(dy / winHeight) * 0.6);
          this._imgSize.style.height = height * (1 - Math.abs(dy / winHeight) * 0.6);
        } else {
          this._imgSize.style.width = width;
          this._imgSize.style.height = height;
        }
        this._setNativeProps();
      }
      _setNativeProps(isReset) {
        if (isReset) {
          this._contentStyle = JSON.parse(JSON.stringify(this._initContentStyle));
          this._modalStyle = JSON.parse(JSON.stringify(this._initModalStyle));
          this._imgSize = JSON.parse(JSON.stringify(this._initImgSize));
        }
        this.content && this.content.setNativeProps(this._contentStyle);
        this.mask && this.mask.setNativeProps(this._modalStyle);
        this.img && this.img.setNativeProps(this._imgSize);
      }
      componentDidUpdate () {
        new Animation({
          start: 0,
          end: 1,
          duration: 100,
          easingFunc: Easing.ease,
          onAnimationFrame: (val=> {
            this.mask && this.mask.setNativeProps({style: {
              opacity: val
            }});
          },
          onAnimationEnd: () => {
            this._inAnimation = false;
          }
        }).start();
      }
      render () {
        const {
          visible,
          onClose,
          source,
          size  // origin size of the image
        } = this.props;
        if (visible) { this._inAnimation = true; }
        this._initImgSize.style = size;
        return (
          <Modal
            visible={visible}
            transparent={true}
            onRequestClose={onClose}>
            <View style={styles.mask} ref={mask => {this.mask = mask;}} {...this._pan.panHandlers}>
              <TouchableWithoutFeedback
                ref={ref => {this.imgContainer = ref;}}
                onPress={this._closeModalByTap}>
                <View
                  ref={ref => {this.content = ref;}}
                  style={styles.content}>
                  <Image ref={img => {this.img = img;}} source={source} style={[size, styles.img]}/>
                </View>
              </TouchableWithoutFeedback>
            </View>
          </Modal>
        );
      }
    }

    const styles = StyleSheet.create({
      mask: {
        position: 'absolute',
        right: 0,
        left: 0,
        top: 0,
        bottom: 0,
        backgroundColor: 'rgba(0, 0, 0, 1)',
        opacity: 0
      },
      content: {
        position: 'absolute',
        right: 0,
        left: 0,
        top: 0,
        bottom: 0,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: 'transparent'
      },
      toucharea: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        alignSelf: 'stretch'
      },
      modalText: {
        color: '#fff'
      },
      img: {
      }
    });

    ZoomImage.ImageModal = ImageModal;

    export default ZoomImage;


    3.Animation.js

    export default function Animation(option) {
      this.animate = this.animate.bind(this);
      this.start = this.start.bind(this);
      this.option = option;
    }

    Animation.prototype.animate = function (now) {
      const {
        start,
        end,
        duration,
        onAnimationFrame,
        onAnimationEnd = () => {},
        easingFunc = t => t
      } = this.option;
      var currentDuration = now - this.startTime;
      if (currentDuration >= duration) {
        onAnimationFrame(end);
        onAnimationEnd();
        return;
      }
      let value;
      if (start > end) {
        value = start - (start - end) * easingFunc(currentDuration / duration);
      } else {
        value = (end - start) * easingFunc(currentDuration / duration) + start;
      }
      onAnimationFrame(value);
      requestAnimationFrame(this.animate);
    };

    Animation.prototype.start = function () {
      this.startTime = new Date();
      this.animate(this.startTime);
    };

    Examples效果如下

    项目原地址https://github.com/Tinysymphony/react-native-zoom-image
    展开全文
  • 在过去的一年中React Native经历了从v0.40到v0.52的十几次的版本迭代,可以看到,特别是0.50之后,React Native组件库在不断地壮大,React Native也正在越来越稳定。 随着版本的升级,React Native引进了一些新的...
  • 在官方没提供侧滑组件之前,要实现侧滑效果需要使用第三方库,如react-native-swipe-list-view。不过随着React Native 0.50版本的发布,系统新添加SwipeableFlatList组件,SwipeableFlatList是在FlatList基础上实现...
  • React-Native学习资料

    2018-05-27 13:35:53
    React Native 构建 Facebook F8 2016 App / React Native 开发指南 http://f8-app.liaohuqiu.net/ React-Native入门指南 https://github.com/vczero/react-native-lesson 30天学习React Native教程 ...
  • http://www.jianshu.com/p/681090de6856 视频:http://v.youku.com/v_show/id_XMjQzNjM2NzgwOA==.html 源代码:... ...组件: ...react-native-vector-icons:https://github.com/o
  • 之前写了些RN的第三方插件的教程,(比如react-native-baidu-map iOS端集成:http://www.jianshu.com/p/eceb7e66fa5e ,RN升级配置说明:http://www.jianshu.com/p/0c30e94de69b ) ,我觉得写博客来帮网友解决...
  • (一)前言 今天我们一起来看一下Touchable*系列组件的使用详解,该系列组件包括四种分别为:TouchableHighlight,TouchableNativeFeedback,TouchableOpacity,TouchableWithoutFeedback。其中最后一个控件是触摸点击不...
  • 前言转载https://github.com/amandakelake/blog/issues/49最近在进行RN项目重构,通过查阅各种资料,从RN底层出发,思考总结了一些从reactreact-native的性能优化相关问题Performance · React Native请先认真查看...
  • React Native学习心得

    2019-04-15 18:24:37
    目前通过《React Native移动开发实战-向洪治版》进行基础学习 结合网址进行学习:https://reactnative.cn/ 讨论社区:https://www.facebook.com/groups/react.native.community React Native - 调试技巧及调试...
  • 一、React-Native介绍简介: React Native (简称RN)是Facebook于2015年4月开源的跨平台移动应用开发框架,是Facebook早先开源的UI框架 React 在原生移动应用平台的衍生产物,目前支持iOS和安卓两大平台。RN使用...
  • 欢迎一起来学习React Native,QQ群:672509442 属性 大多数组件在创建时就可以使用各种参数来进行定制。用于定制的这些参数就称为props(属性)。 原生组件的prop 以常见的基础组件Image为例,在创建一个...
  • react native 版本升级降级 查看版本 react-native –version 查看npm包管理的React Native 版本 npm info react-native 根据package.json 的版本更新 npm install react native 升级 npm WARN React-native@...
  • RN通过onLayout属性获取当前组件的位置和属性信息
  • react-native组件ScrollView

    2018-06-21 21:25:52
    效果图代码示例import React, { Component } from 'react'; import { Dimensions, StyleSheet, View, Text, Alert, TouchableOpacity, Image, Button, ScrollView } from 'react-nativ...
  • GitHub:https://github.com/crazycodeboy/react-native-splash-screen 安装以及自动添加依赖 npm i react-native-...react-native link react-native-splash-screen 手动添加 Android 1、在android/se...
1 2 3 4 5 ... 20
收藏数 628
精华内容 251
关键字:

de组件 native react