javascript - 如何移植 iOS 索引文件以响应原生到 android

标签 javascript android ios react-native

我的 index.io.js 文件有以下代码。我是 React Native 的新手,不太了解如何将其移植到 index.android.js。是否有我可以遵循的特定标准将其迁移到 android 版本?具体需要做什么?

'use strict';
var ShakeEvent = require('react-native-shake-event-ios');
var NetworkImage = require('react-native-image-progress');
var Progress = require('react-native-progress');
var Swiper = require('react-native-swiper');
var RandManager = require('./RandManager.js');
var Utils = require('./Utils.js');
var React = require('react-native');

// Components 
var ProgressHUD = require('./ProgressHUD.js');

var {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Component,
  ActivityIndicatorIOS,
  Dimensions,
  PanResponder,
  CameraRoll,
  AlertIOS
} = React;

var {width, height} = Dimensions.get('window');

const NUM_WALLPAPERS = 5;
const DOUBLE_TAP_DELAY = 300; // milliseconds
const DOUBLE_TAP_RADIUS = 20;

class SplashWalls extends Component{
  constructor(props) {
    super(props);

    this.state = {
      wallsJSON: [],
      isLoading: true,
      isHudVisible: false
    };

    this.imagePanResponder = {};

    // Previous touch information
    this.prevTouchInfo = {
      prevTouchX: 0,
      prevTouchY: 0,
      prevTouchTimeStamp: 0
    };

    this.currentWallIndex = 0;

    // Binding this to methods
    this.handlePanResponderGrant = this.handlePanResponderGrant.bind(this);
    this.onMomentumScrollEnd = this.onMomentumScrollEnd.bind(this);

  }

  componentDidMount() {
    this.fetchWallsJSON();      
  }

  componentWillMount() {
    this.imagePanResponder = PanResponder.create({
      onStartShouldSetPanResponder: this.handleStartShouldSetPanResponder,
      onPanResponderGrant: this.handlePanResponderGrant,
      onPanResponderRelease: this.handlePanResponderEnd,
      onPanResponderTerminate: this.handlePanResponderEnd
    });

    // Fetch new wallpapers on shake
    ShakeEvent.addEventListener('shake', () => {
      this.initialize();
      this.fetchWallsJSON();
    });
  }

  render() {
    var {isLoading} = this.state;
    if(isLoading)
      return this.renderLoadingMessage();
    else
      return this.renderResults();
  }

  initialize() {
    this.setState({
      wallsJSON: [],
      isLoading: true,
      isHudVisible: false
    });

    this.currentWallIndex = 0;
  }

  fetchWallsJSON() {
    var url = 'http://unsplash.it/list';
    fetch(url)
      .then( response => response.json() )
      .then( jsonData => {
        var randomIds = RandManager.uniqueRandomNumbers(NUM_WALLPAPERS, 0, jsonData.length);
        var walls = [];
        randomIds.forEach(randomId => {
          walls.push(jsonData[randomId]);
        });

        this.setState({
          isLoading: false,
          wallsJSON: [].concat(walls)
        });
      })
      .catch( error => console.log('JSON Fetch error : ' + error) );
  }

  renderLoadingMessage() {
    return (
      <View style={styles.loadingContainer}>
        <ActivityIndicatorIOS
          animating={true}
          color={'#fff'}
          size={'small'} 
          style={{margin: 15}} />
          <Text style={{color: '#fff'}}>Contacting Unsplash</Text>
      </View>
    );
  }

  saveCurrentWallpaperToCameraRoll() {
    // Make Progress HUD visible
    this.setState({isHudVisible: true});

    var {wallsJSON} = this.state;
    var currentWall = wallsJSON[this.currentWallIndex];
    var currentWallURL = `http://unsplash.it/${currentWall.width}/${currentWall.height}?image=${currentWall.id}`;

    CameraRoll.saveImageWithTag(currentWallURL, (data) => {
      // Hide Progress HUD
      this.setState({isHudVisible: false});

      AlertIOS.alert(
        'Saved',
        'Wallpaper successfully saved to Camera Roll',
        [
          {text: 'High 5!', onPress: () => console.log('OK Pressed!')}
        ]
      );
    },(err) =>{
      console.log('Error saving to camera roll', err);
    });
  }

  onMomentumScrollEnd(e, state, context) {
    this.currentWallIndex = state.index;
  }

  renderResults() {
    var {wallsJSON, isHudVisible} = this.state;
    return (
      <View>
      <Swiper
        dot={<View style={{backgroundColor:'rgba(255,255,255,.4)', width: 8, height: 8,borderRadius: 10, marginLeft: 3, marginRight: 3, marginTop: 3, marginBottom: 3,}} />}
        activeDot={<View style={{backgroundColor: '#fff', width: 13, height: 13, borderRadius: 7, marginLeft: 7, marginRight: 7}} />}
        onMomentumScrollEnd={this.onMomentumScrollEnd}
        index={this.currentWallIndex}
        loop={false}>
        {wallsJSON.map((wallpaper, index) => {
          return(
            <View key={wallpaper.id}>
              <NetworkImage
                source={{uri: `https://unsplash.it/${wallpaper.width}/${wallpaper.height}?image=${wallpaper.id}`}}
                indicator={Progress.Circle}
                indicatorProps={{
                  color: 'rgba(255, 255, 255)',
                  size: 60,
                  thickness: 7
                }}
                threshold={0}
                style={styles.wallpaperImage}
                {...this.imagePanResponder.panHandlers}>

                  <Text style={styles.label}>Photo by</Text>
                  <Text style={styles.label_authorName}>{wallpaper.author}</Text>

              </NetworkImage>
            </View>
          );
        })}
      </Swiper>
      <ProgressHUD width={width} height={height} isVisible={isHudVisible}/>
      </View>
    );
  }

  // Pan Handler methods
  handleStartShouldSetPanResponder(e, gestureState){
    return true;
  }

  handlePanResponderGrant(e, gestureState) {
    var currentTouchTimeStamp = Date.now();

    if( this.isDoubleTap(currentTouchTimeStamp, gestureState) ) 
      this.saveCurrentWallpaperToCameraRoll();

    this.prevTouchInfo = {
      prevTouchX: gestureState.x0,
      prevTouchY: gestureState.y0,
      prevTouchTimeStamp: currentTouchTimeStamp
    };
  }

  handlePanResponderEnd(e, gestureState) {
    // When finger is pulled up from the screen
  }

  isDoubleTap(currentTouchTimeStamp, {x0, y0}) {
    var {prevTouchX, prevTouchY, prevTouchTimeStamp} = this.prevTouchInfo;
    var dt = currentTouchTimeStamp - prevTouchTimeStamp;

    return (dt < DOUBLE_TAP_DELAY && Utils.distance(prevTouchX, prevTouchY, x0, y0) < DOUBLE_TAP_RADIUS);
  }


};

var styles = StyleSheet.create({
  loadingContainer: {
    flexDirection: 'row',
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#000'
  },
  wallpaperImage: {
    flex: 1,
    width: width,
    height: height,
    backgroundColor: '#000'
  },
  label: {
    position: 'absolute',
    color: '#fff',
    fontSize: 13,
    backgroundColor: 'rgba(0, 0, 0, 0.8)',
    padding: 2,
    paddingLeft: 5,
    top: 20,
    left: 20,
    width: width/2
  },
  label_authorName: {
    position: 'absolute',
    color: '#fff',
    fontSize: 15,
    backgroundColor: 'rgba(0, 0, 0, 0.8)',
    padding: 2,
    paddingLeft: 5,
    top: 41,
    left: 20,
    fontWeight: 'bold',
    width: width/2
  }
});

AppRegistry.registerComponent('SplashWalls', () => SplashWalls);

最佳答案

  1. 先将index.ios.js的内容复制到index.android.js。如果它不包含任何 iOS 特定代码/库,它就会正常工作。如果不是,请转到第 2 步。

  2. 调整代码以使用 Android 特定代码或 lib API - 如果存在此类代码。如果不是,请转到第 3 步。

  3. 要么将 iOS 代码/库换成 Android 代码,要么自己编写所需的代码。

关于javascript - 如何移植 iOS 索引文件以响应原生到 android,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41534946/

相关文章:

javascript - 如何从客户端向树莓派发送数据?

ios - 如何确定磁力计是否需要对 CoreMotion 引用系进行校准?

javascript - 是否可以在 TypeScript 中创建 "weak export"

javascript - 我如何使用 jquery 根据 url 中的关键字更改 css 类

java - 如何改变CollapsingToolbarLayout 标题的方向?

AndroidX - 程序类型已经存在 : androidx. annotation.BoolRes

android - 启动时绕过主要 Activity

ios - UIViewController 不会因为动画循环而解除分配

ios - 在 UITableViewController 中使用不同类型的单元格和不同的行数

javascript - 如何每天在特定时间运行node.js cron?