react-native学习 Day1_react native setcolormode-程序员宅基地

技术标签: react.js  react native  javascript  

react-native Day1

当我用了2天翻越了无数博客文档才搭建起react-native的开发环境之后(忘记记录踩坑指南了@_@),因为使用的是最新版的mac pro,一部分的坑网上的解决方法已经失效了,第二就是大家都懂得网络问题,这个只能多试试各种方法进行安装一些依赖,另外我使用小米手机报错‘Execution failed for task ':app:installDebug’时,在设置----更多设置----开发者选项----启用MIUI优化 关闭之后就可以解决,那么就可以正式开始我的react-native学习之旅。

Day1 完成一个计时器

首先按照官网进行脚手架创建项目: https://reactnative.dev/docs/environment-setup

如果你很熟悉react,那么react-native的语法应当不成问题,当然react-native在很多地方与web开发还是有很大的区别,例如入口可以用index.ios.js和index.android.js来区分安卓和ios的入口文件,还有ios和安卓的兼容问题,以及调用原生接口的问题等等,先把App.js本身的代码清干净,引入我们的第一天学习的文件代码

app.js

StyleSheet, useColorScheme, View 三个react-native的组件,分别对应api来看一下如何使用的。

StyleSheet 是类似于 CSS StyleSheets 的抽象,常用的就是const styles = StyleSheet.create({ fontSize: 30 }) ,使用时在对应的组件中写style={[ fontSize: 30 ]},在RN中样式布局和web中有一定的区别需要花费一定的时间进行学习。

useColorScheme自定义hooks,React钩子提供并订阅来自Appearance模块的配色方案更新。返回值表示当前用户首选的配色方案。该值可以稍后更新,既可以通过直接的用户操作(例如在设备设置中选择主题),也可以根据时间表(例如,遵循白天和黑夜循环的明暗主题)进行更新。

  • "light": The user prefers a light color theme.
  • "dark": The user prefers a dark color theme.
  • null: The user has not indicated a preferred color theme.

View是构建UI最基本的组件,它是一个容器,支持flexbox布局、样式、一些触摸处理和可访问控件。View直接映射到React native运行的平台上的原生视图,无论是UIView, <div>,android。视图,等等。类似web开发中的div,但是在react-native中布局主要是用flex布局,和web开发有一定的区别。

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow strict-local
 */

import React from 'react';
import {
    Node} from 'react';
import Day1 from './view/day1';

import {
     useColorScheme, View } from 'react-native';

import {
     Colors } from 'react-native/Libraries/NewAppScreen';

const App: () => Node = () => {
    
  const isDarkMode = useColorScheme() === 'dark';

  const backgroundStyle = {
    
    backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
  };

  return (
    <View style={
    backgroundStyle}>
      <Day1 />
    </View>
  );
};

export default App;

Day1.js

Platform, FlatList, StyleSheet, StatusBar, Text, TouchableHighlight 几个react-native的组件,分别对应api来看一下如何使用的。

Platform

Platform用于区分ios系统和Android系统,然后针对ios和android进行兼容。常用:

  1. 特定平台扩展名
React Native会检测某个文件是否具有.ios.或是.android.的扩展名,然后根据当前运行的平台加载正确对应的文件。
假设你的项目中有如下两个文件:
`BigButton.ios.js`
`BigButton.android.js`
这样命名组件后你就可以在其他组件中直接引用,而无需关心当前运行的平台是哪个。
`import BigButton from './components/BigButton';`
  1. 实用的方法是Platform.select()
var {
     Platform } = React;
var styles = StyleSheet.create({
    
  container: {
    
    flex: 1,
    ...Platform.select({
    
      ios: {
    
        backgroundColor: 'red',
      },
      android: {
    
        backgroundColor: 'blue',
      },
    }),
  },
});
//上面的代码会根据平台的不同返回不同的container样式——iOS上背景色为红色,而android为蓝色。
这一方法可以接受任何合法类型的参数,因此你也可以直接用它针对不同平台返回不同的组件,像下面这样:
var Component = Platform.select({
    
  ios: () => require('ComponentIOS'),
  android: () => require('ComponentAndroid'),
})();
<Component />
  1. 平台模块

React Native提供了一个检测当前运行平台的模块。如果组件只有一小部分代码需要依据平台定制,那么这个模块就可以派上用场。

import {
     Platform } from 'react-native';
var styles = StyleSheet.create({
    
  height: (Platform.OS === 'ios') ? 200 : 100,
});
//Platform.OS在iOS上会返回ios,而在Android设备或模拟器上则会返回android。
  1. 检测Android版本
//在Android上,平台模块还可以用来检测当前所运行的Android平台的版本:
import {
     Platform } from 'react-native';
if(Platform.Version === 21){
    
  console.log('Running on Lollipop!');
}

FlatList

StatusBar

  • 控制应用状态栏的组件。

reactNtive中文 StatusBar

Text

  • 一个用于显示文本的 React 组件,并且它也支持嵌套、样式,以及触摸处理。

    reactNative中文 Text

TouchableHighlight

  • 本组件用于封装视图,使其可以正确响应触摸操作。当按下的时候,封装的视图的不透明度会降低,同时会有一个底层的颜色透过而被用户看到,使得视图变暗或变亮。其实就是button

    reactNative中文 TouchableHighlight

/**
 * Day 1
 * A stop watch
 */
'use strict';

import React, {
    Component} from 'react';
import {
    Platform, FlatList, StyleSheet, StatusBar, Text, TouchableHighlight, View} from 'react-native';
import Util from './utils';
import PropTypes from 'prop-types';  // 由于react的propTypes早就被移除了 所以需要从外部引

class WatchFace extends Component {
    
  static propTypes = {
    
    sectionTime: PropTypes.string.isRequired,
    totalTime: PropTypes.string.isRequired,
  };

  render() {
    
    return (
      <View style={
    styles.watchFaceContainer}>
        <Text style={
    styles.sectionTime}>{
    this.props.sectionTime}</Text>
        <Text style={
    styles.totalTime}>{
    this.props.totalTime}</Text>
      </View>
    );
  }
}

class WatchControl extends Component {
    
  static propTypes = {
    
    stopWatch: PropTypes.func.isRequired,
    clearRecord: PropTypes.func.isRequired,
    startWatch: PropTypes.func.isRequired,
    addRecord: PropTypes.func.isRequired,
  };

  constructor(props) {
    
    super(props);
    this.state = {
    
      watchOn: false,
      startBtnText: '启动',
      startBtnColor: '#60B644',
      stopBtnText: '计次',
      underlayColor: '#fff',
    };
  }

  _startWatch() {
    
    if (!this.state.watchOn) {
    
      this.props.startWatch();
      this.setState({
    
        startBtnText: '停止',
        startBtnColor: '#ff0044',
        stopBtnText: '计次',
        underlayColor: '#eee',
        watchOn: true,
      });
    } else {
    
      this.props.stopWatch();
      this.setState({
    
        startBtnText: '启动',
        startBtnColor: '#60B644',
        stopBtnText: '复位',
        underlayColor: '#eee',
        watchOn: false,
      });
    }
  }

  _addRecord() {
    
    if (this.state.watchOn) {
    
      this.props.addRecord();
    } else {
    
      this.props.clearRecord();
      this.setState({
    
        stopBtnText: '计次',
      });
    }
  }

  render() {
    
    return (
      <View style={
    styles.watchControlContainer}>
        <View style={
    {
    flex: 1, alignItems: 'flex-start'}}>
          <TouchableHighlight
            style={
    styles.btnStop}
            underlayColor={
    this.state.underlayColor}
            onPress={
    () => this._addRecord()}>
            <Text style={
    styles.btnStopText}>{
    this.state.stopBtnText}</Text>
          </TouchableHighlight>
        </View>
        <View style={
    {
    flex: 1, alignItems: 'flex-end'}}>
          <TouchableHighlight style={
    styles.btnStart} underlayColor="#eee" onPress={
    () => this._startWatch()}>
            <Text style={
    [styles.btnStartText, {
    color: this.state.startBtnColor}]}>{
    this.state.startBtnText}</Text>
          </TouchableHighlight>
        </View>
      </View>
    );
  }
}

class WatchRecord extends Component {
    
  static propTypes = {
    
    record: PropTypes.array.isRequired,
  };

  constructor(props) {
    
    super(props);
    this.Item = ({
     item}) => {
    
      return (
        <View style={
    styles.recordItem}>
          <Text style={
    styles.recordItemTitle}>{
    item.title || ''}</Text>
          <View style={
    {
    alignItems: 'center'}}>
            <Text style={
    styles.recordItemTime}>{
    item.time || ''}</Text>
          </View>
        </View>
      );
    };
  }

  render() {
    
    return (
      <FlatList
        keyExtractor={
    (item) => `${
      item.title}-${
      item.time}`}
        style={
    styles.recordList}
        data={
    this.props.record}
        renderItem={
    this.Item}
      />
    );
  }
}

export default class extends Component {
    
  constructor() {
    
    super();
    this.state = {
    
      stopWatch: false,
      resetWatch: true,
      intialTime: 0,
      currentTime: 0,
      recordTime: 0,
      timeAccumulation: 0,
      totalTime: '00:00.00',
      sectionTime: '00:00.00',
      recordCounter: 0,
      record: [],
    };
  }

  componentWillUnmount() {
    
    this._stopWatch();
    this._clearRecord();
  }

  componentDidMount() {
    
    if (Platform.OS === 'ios') {
    
      StatusBar.setBarStyle(0);
    }
  }

  _startWatch() {
    
    if (this.state.resetWatch) {
    
      this.setState({
    
        stopWatch: false,
        resetWatch: false,
        timeAccumulation: 0,
        initialTime: new Date().getTime(),
      });
    } else {
    
      this.setState({
    
        stopWatch: false,
        initialTime: new Date().getTime(),
      });
    }
    let milSecond, second, minute, countingTime, secmilSecond, secsecond, secminute, seccountingTime;
    let interval = setInterval(() => {
    
      this.setState({
    
        currentTime: new Date().getTime(),
      });
      countingTime = this.state.timeAccumulation + this.state.currentTime - this.state.initialTime;
      minute = Math.floor(countingTime / (60 * 1000));
      second = Math.floor((countingTime - 6000 * minute) / 1000);
      milSecond = Math.floor((countingTime % 1000) / 10);
      seccountingTime = countingTime - this.state.recordTime;
      secminute = Math.floor(seccountingTime / (60 * 1000));
      secsecond = Math.floor((seccountingTime - 6000 * secminute) / 1000);
      secmilSecond = Math.floor((seccountingTime % 1000) / 10);
      this.setState({
    
        totalTime:
          (minute < 10 ? '0' + minute : minute) +
          ':' +
          (second < 10 ? '0' + second : second) +
          '.' +
          (milSecond < 10 ? '0' + milSecond : milSecond),
        sectionTime:
          (secminute < 10 ? '0' + secminute : secminute) +
          ':' +
          (secsecond < 10 ? '0' + secsecond : secsecond) +
          '.' +
          (secmilSecond < 10 ? '0' + secmilSecond : secmilSecond),
      });
      if (this.state.stopWatch) {
    
        this.setState({
    
          timeAccumulation: countingTime,
        });
        clearInterval(interval);
      }
    }, 10);
  }

  _stopWatch() {
    
    this.setState({
    
      stopWatch: true,
    });
  }

  _addRecord() {
    
    let {
    recordCounter, record} = this.state;
    recordCounter++;
    if (recordCounter > 5) {
    
      record.pop();
    }
    record.unshift({
    title: '计次' + recordCounter, time: this.state.sectionTime});
    this.setState({
    
      recordTime: this.state.timeAccumulation + this.state.currentTime - this.state.initialTime,
      recordCounter: recordCounter,
      record: record,
    });
    //use refs to call functions within other sub component
    //can force to update the states
    // this.refs.record._updateData();
  }

  _clearRecord() {
    
    this.setState({
    
      stopWatch: false,
      resetWatch: true,
      intialTime: 0,
      currentTime: 0,
      recordTime: 0,
      timeAccumulation: 0,
      totalTime: '00:00.00',
      sectionTime: '00:00.00',
      recordCounter: 0,
      record: [],
    });
  }

  render() {
    
    return (
      <View style={
    styles.watchContainer}>
        <WatchFace totalTime={
    this.state.totalTime} sectionTime={
    this.state.sectionTime} />
        <WatchControl
          addRecord={
    () => this._addRecord()}
          clearRecord={
    () => this._clearRecord()}
          startWatch={
    () => this._startWatch()}
          stopWatch={
    () => this._stopWatch()}
        />
        <WatchRecord record={
    this.state.record} />
      </View>
    );
  }
}

const styles = StyleSheet.create({
    
  watchContainer: {
    
    alignItems: 'center',
    backgroundColor: '#f3f3f3',
    marginTop: 60,
  },
  watchFaceContainer: {
    
    width: Util.size.width,
    paddingTop: 50,
    paddingLeft: 30,
    paddingRight: 30,
    paddingBottom: 40,
    backgroundColor: '#fff',
    borderBottomWidth: 1,
    borderBottomColor: '#ddd',
    height: 170,
  },
  sectionTime: {
    
    fontSize: 20,
    fontWeight: '100',
    paddingRight: 30,
    color: '#555',
    position: 'absolute',
    left: Util.size.width - 140,
    top: 30,
  },
  totalTime: {
    
    fontSize: Util.size.width === 375 ? 70 : 60,
    fontWeight: '100',
    color: '#222',
    paddingLeft: 20,
  },
  watchControlContainer: {
    
    width: Util.size.width,
    height: 100,
    flexDirection: 'row',
    backgroundColor: '#f3f3f3',
    paddingTop: 30,
    paddingLeft: 60,
    paddingRight: 60,
    paddingBottom: 0,
  },
  btnStart: {
    
    width: 70,
    height: 70,
    borderRadius: 35,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  btnStop: {
    
    width: 70,
    height: 70,
    borderRadius: 35,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  btnStartText: {
    
    fontSize: 14,
    backgroundColor: 'transparent',
  },
  btnStopText: {
    
    fontSize: 14,
    backgroundColor: 'transparent',
    color: '#555',
  },
  recordList: {
    
    width: Util.size.width,
    height: Util.size.height - 300,
    paddingLeft: 15,
  },
  recordItem: {
    
    height: 40,
    borderBottomWidth: Util.pixel,
    borderBottomColor: '#bbb',
    paddingTop: 5,
    paddingLeft: 10,
    paddingRight: 10,
    paddingBottom: 5,
    flexDirection: 'row',
    alignItems: 'center',
  },
  recordItemTitle: {
    
    backgroundColor: 'transparent',
    flex: 1,
    textAlign: 'left',
    paddingLeft: 20,
    color: '#777',
  },
  recordItemTime: {
    
    backgroundColor: 'transparent',
    flex: 1,
    textAlign: 'right',
    paddingRight: 20,
    color: '#222',
  },
});

效果

在这里插入图片描述

小结

  • 重点要熟悉Native和web布局的区别,学习如何使用Native布局达到想要的效果。
  • 熟悉了一些Native自带的组件的使用方法,总结这个太麻烦了,后面的总结中不再总结组件使用,直接官网阅读即可。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/shadowfall/article/details/122925728

智能推荐

java ee项目案后台模板_12个非常不错的免费HTML后台管理模板-程序员宅基地

文章浏览阅读481次。下面介绍的这些免费后端管理HTML模板,都非常不错。建议您收藏。Charisma是一个响应式管理模板,基于Twitter Bootstrap构建。拥有9种外观主题,包括几乎所有的东西,如表单、图表、按纽、表格、文件管理器、相册等。可到GitHub link下载该模板。INADMIN是一个基于jQuery开发的管理模板,拥有头+顶部导航,提供了tables、forms、messages等样式,还..._java后端查询内容的数据赋值定制的html 模板

vue-amap官网文档链接,vue-amap画圆-程序员宅基地

文章浏览阅读1.7k次。1.4.3 圆 - vue-amap 中文文档 - 文江博客基础示例 组件 | vue-amap

几何光学学习笔记(1)- 1.1 几何光学的基本概念和定律-程序员宅基地

文章浏览阅读5.8k次,点赞11次,收藏33次。几何光学学习笔记(1)1.1 几何光学的基本概念和定律1.绪论2. 几何光学的基本概念3.几何光学的基本规律1.绪论几何光学:直线传播;互不影响;折射反射。物理光学:波动光学,量子光学几何光学和物理光学在一定条件下可以统一起来。例如:几何光学认为光源通过光学系统会成像为一个几何点;而物理光学则认为会成像为一个黑白相间的衍射斑。其中,第一个亮斑的半径为y=1.22λDy=\frac {1.22\lambda} Dy=D1.22λ​当λ→0\lambda\to0λ→0时,y也为0,此时几何光

ios python 越狱_如何使用Frida绕过iOS应用程序中的越狱检测!!!-程序员宅基地

文章浏览阅读685次。注意 注意 请注意:一、Frida介绍Frida是一个可以hook App的动态代码工具包,可以向Windows、macOS、Linux、iOS、Android和QNX的本机应用程序中注入JavaScript或自己的库代码。最开始的时候,它是基于谷歌的V8 Javascript运行,但是从版本9开始,Frida已经开始使用其内部的Duktape运行。列举一些Frida的使用场景:1、hookin..._python hook ios app

shiro权限缓存_shiro-activesessioncache-程序员宅基地

文章浏览阅读935次。在每次操作的时候都会查询一遍权限,说实话,确实有点压力,所以可以考虑采用一下缓存来缓解一下压力Ehcache本地缓存的实现1、<!-- shiro缓存管理器 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <vers_shiro-activesessioncache

好久没有写CSDN上的博客了-程序员宅基地

文章浏览阅读325次。今天搜索关于谷歌所使用的技术的时候看到CSDN上的文章,随便看了看自己的,发现自己有快两年没有写过了,真是汗颜啊,所以决定以后关于技术的全放到程序员宅基地上,同时保留163博客上的内容 还希望各位朋友多多捧场

随便推点

notepad++快捷键_notepad加粗快捷键-程序员宅基地

文章浏览阅读1.6k次,点赞2次,收藏2次。notepad++是一款在windows上表现很不错的编辑器,学习成本低,支持的语言多,可拓展性高。 我原本打算用notepad++做为主编辑器,但是发现他对markdown的支持并不好,况且优秀的编辑器有很多。我打算去探索新的编辑器。 目前,notepad++依然有用武之地,因为通过notepadstarterplugin插件能完全取代记事本,即一些默认打开记事本的程序,将会打开notepad++,非常_notepad加粗快捷键

HarmonyOS —— MD5 摘要计算_harmony md5-程序员宅基地

文章浏览阅读760次,点赞8次,收藏7次。计算 MD5 摘要需要导入HarmonyOs提供的统一的密码算法库加解密相关接口。_harmony md5

Windows 解决cmd/dos窗口中文乱码问题_cmd中文乱码解决方法-程序员宅基地

文章浏览阅读6.5w次,点赞10次,收藏55次。Windows 解决cmd/dos窗口中文乱码问题,本文提供了多种解决方案,总有一款适合你!_cmd中文乱码解决方法

FireFox与IE中CSS兼容技术集绵整理-程序员宅基地

文章浏览阅读87次。1.css在不同浏览器下显示效果不同firefox和IE对某些css样式的认定有不少区别,包括:· ul和ol的默认padding值是不一样的,在Firefox中,padding-left默认值为40px左右,而IE中为0,一般设置ul{margin:0;padding:0;}就能解决大部分问题· ..._火狐 p height 多了 0.45

Scala finally块_scala finally-程序员宅基地

文章浏览阅读657次。finally块用于在异常时释放资源。资源可能是文件,网络连接,数据库连接等,finally块执行代码运行保证。以下程序说明了finally块的用法。Scala finally块示例class ExceptionExample{ def divide(a:Int, b:Int) = { try{ a/b ..._scala finally

QNX学习笔记-Neutrino-QNX-boot启动流程分析_qnx启动时序图-程序员宅基地

文章浏览阅读2.8k次。嵌入式系统的启动都是类似的,先启动一个boot程序,然后又boot控制系统的进一步加载运行_qnx启动时序图

推荐文章

热门文章

相关标签