react native社区项目知识点

栏目: IOS · Android · 发布时间: 5年前

内容简介:本来想的上一个React项目做完,从容过完1月迎接新年,IT行业的快节奏真是不容许有这种想法;公司把3月上线的xcode配置篇TabBar配置篇

本来想的上一个React项目做完,从容过完1月迎接新年,IT行业的快节奏真是不容许有这种想法;公司把3月上线的 react native 项目,时间周期活生生压缩到1月底,真是哭笑不得。这样只能加加班而且保质保量地完成,还是在接口各种报错的前提下利用Mock数据。 言归正传,回到 react native 项目中来

xcode配置篇

一、iOS APP图标配置

react native社区项目知识点

二、iOS启动页配置、各种尺寸封面大小

react native社区项目知识点
react native社区项目知识点
react native社区项目知识点

TabBar配置篇

一、iPhone X 适配小技巧

  • 应对iphone刘海屏statusbar颜色处理,利用 SafeAreaView 包裹整个render
<SafeAreaView style={{backgroundColor:'red'}}></SafeAreaView>
复制代码
  • 上面方法虽然能达到效果,但除了statusbar,整个背景都会被color覆盖,解决办法如下。(附上 stackoverflow参考链接
<Fragment>
      <SafeAreaView style={{ flex:0, backgroundColor: 'red' }} />
      <SafeAreaView style={{ flex:1, backgroundColor: 'gray' }}>
        <View style={{ flex: 1, backgroundColor: 'white' }} />
      </SafeAreaView>
    </Fragment>
复制代码
react native社区项目知识点

二、createBottomTabNavigator 个性化图标

1、所需要显现的效果,中间“检测”图标比较难定位

react native社区项目知识点

2、代码

import { createBottomTabNavigator, createAppContainer, createStackNavigator } from 'react-navigation' // 引入依赖
    
    const TabNavigator = createBottomTabNavigator({
      Home: {
        screen: Home,
        navigationOptions:()=>({
          title:'首页',
          tabBarIcon: ({tintColor,focused}) => (
            focused ?
              <Image source={require('...')} style={style.nav_icon}/> :
              <Image source={require('...')} style={style.nav_icon}/>
          )
        }),
      },
      Community: {
        screen: Community,
        navigationOptions:()=>({
          title:'社区',
          tabBarIcon: ({tintColor,focused}) => (
            focused ?
              <Image source={require('...')} style={style.nav_icon}/> :
              <Image source={require('...')} style={style.nav_icon}/>
          ),
          tabBarOnPress: ({ navigation, defaultHandler }) => {
            /** 触发器
             * defaultHandler()、navigation.navigate('Community')
             * 两个方法都能实现相同效果,跳转至 Community Component
             */
            defaultHandler()
            navigation.state.params.triggerAvatar()
          }
        })
      },
      Detection: {
        screen: Detection,
        navigationOptions:()=>({
          title:'检测',
          tabBarLabel: ({tintColor,focused}) => (
            focused ?
              <ImageBackground
                resizeMode="cover"
                source={require('...')}
                imageStyle={styles.midIcon_img_wrap}
                style={styles.midIcon_wrap}>
                <Image source={require('...')} style={styles.midIcon}/>
                <Text style={styles.midIcon_word}>检测</Text>
              </ImageBackground>
              :
              <ImageBackground
                resizeMode="cover"
                source={require('...')}
                imageStyle={styles.midIcon_img_wrap}
                style={styles.midIcon_wrap}>
                <Image source={require('...')} style={styles.midIcon}/>
                <Text style={styles.midIcon_word}>检测</Text>
              </ImageBackground>
          )
        }),
      },
      Recover: {
        screen: Recover,
        navigationOptions:()=>({
          title:'康复',
          tabBarIcon: ({tintColor,focused}) => (
            focused ?
              <Image source={require('...')} style={style.nav_icon}/> :
              <Image source={require('...')} style={style.nav_icon}/>
          )
        }),
      },
      Me: {
        screen: Me,
        navigationOptions:()=>({
          title:'我的',
          tabBarIcon: ({tintColor,focused}) => (
            focused ?
              <View style={style.nav_icon_wrap}>
                <Image source={require('...')} style={style.nav_icon}/>
                <MsgSpot/>
              </View>
              :
              <View style={style.nav_icon_wrap}>
                <Image source={require('...')} style={style.nav_icon}/>
                <MsgSpot/>
              </View>
          )
        })
      }
    },{
      initialRouteName:'Home', // 路由最开始访问
      lazy:true,               // 是否懒加载
      tabBarOptions:{
        activeTintColor:'#0168F5',
        style:{
          borderTopWidth:0,
          shadowOpacity: 0.1,
          shadowRadius: 5,
          shadowColor: '#8B8B8B',
          shadowOffset:{ width:0,height:-4 },
          paddingHorizontal:16
        },
        labelStyle:{fontSize:10,position:'relative',top:-2},
        tabStyle:{paddingTop:2}
      }
    })
    
    //StackNavigator
    const App = createStackNavigator({
      TabNavigator: {screen: TabNavigator, navigationOptions: () => ({gesturesEnabled: true,header: null})},
      HomeDetail: {screen: HomeDetail, navigationOptions: () => ({gesturesEnabled: true,header: null})}
    })
    
    console.disableYellowBox = true // 屏蔽warning弹窗
    export default createAppContainer(App)
复制代码

三、TabNavigator站内消息提示小红点

思路:这种跨组件间事件操作,可以利用 Redux 实现,但官方给出的是最新版本不会默认集成,那么就自己找方法怎么简单怎么来,首先考虑到的是 DeviceEventEmitter

import { DeviceEventEmitter } from 'react-native' // 引入
复制代码
// spot红点事件注册
class MsgSpot extends Component<Props> {
  state = { spotShow:false }
  componentDidMount(){  // tabbar首次渲染订阅事件
    DeviceEventEmitter.addListener('message',param => {
      this.setState({spotShow:param.spotShow})
      console.log(param)
    })
  }
  render() {
    const {spotShow} = this.state
    return (
      <Fragment>
      {spotShow?<View style={[style.redSpot,style.redSpot_nav]}></View>:null}
      </Fragment>
    )
  }
}
复制代码
DeviceEventEmitter.emit('message', {spotShow:true/false}) // 触发事件
复制代码

四、TabNavigator点击触发事情

// 详情看上面tabbar
tabBarOnPress: ({ navigation, defaultHandler }) => {
/** 触发器
 * defaultHandler()、navigation.navigate('Community')
 * 两个方法都能实现相同效果,跳转至 Community Component
 */
defaultHandler()
navigation.state.params.triggerAvatar()
}
复制代码

五、页面订阅事件

componentDidMount(){
    // 订阅生命周期
    this._listeners = this.props.navigation.addListener('willFocus', ()=>this.xxx())
}
componentWillUnmount(){
    this._listeners.remove() // 移除事件订阅
}
复制代码

react-navigation链接参考

六、导航callback与导航事件注册

// 跳转前页面
startScan = (param) => {}     // 1、注册回调
navigate('xxx',{ startScan:this.startScan ,callback:()=>{}})

// 跳转后 xxx 页面
state.params.startScan(param) // 1、触发回调
state.params.callback({})     // 2、触发callback    
复制代码

滚动事件、布局篇

一、底部按钮与ScrollView样式

<SafeAreaView style={{flex:1}}>
    <ScrollView></ScrollView>
    <Text>Button</Text>
</SafeAreaView>
复制代码

二、FlatList 上拉、下拉实现

import {
  FlatList,
  RefreshControl
} from 'react-native'   // 引入

constructor(props){
super(props)
this.dataListFake = []  // 列表数据
this.page     = 1       // 页码
this.state = {
  dataList : [],        // 渲染数据
  refresh : true,
  pullDown: false,
  isLast:   false,
  loading:  false       // 正在加载
}
}
componentDidMount() {
    this._onRefresh()
}
renderItem = ({item}) => { return () }
renderFooter = () => {
// 显示时机
// 1、刚开始加载、之后,不显示
// 2、下刷新,消失
// 3、上拉加载,动画出现
//    加载完,动画消失;没有数据,显示"暂无更多"
const { pullDown, isLast } = this.state
return (
      <View style={[style.footLoad,{paddingBottom:200}]}>
        {pullDown?<Image source={require('../../assets/loading.gif')} style={style.footImg}/>:null}
        {isLast?<Text style={style.footWord}>暂无更多~</Text>:null}
      </View>
    )
}
renderEmpty = () => {
    return (
        <View style={style.renderEmpty}>
            <Text>暂无数据</Text>
        </View>
    )
}

// 下拉刷新
_onRefresh = () => {
    const {loading} = this.state
    // 是否正在loading
    if (!loading){
      this.page = 1
      this.dataListFake = []
      this.setState({refresh:true,isLast:false})
      this.dataList(dataListCallBack)
    }
    function dataListCallBack(){
      // Toast.success('刷新成功',800)
    }
}

// 上拉加载
_onEndReached = () => {
    return false // 没有分页
    const {isLast,loading} = this.state
    if (!loading){// 是否正在loading
      if (isLast){
        // Toast.sad('暂无更多数据~')
      }else{
        this.page++
        this.setState({pullDown:true})
        this.dataList(dataListCallBack)
      }
    }
    function dataListCallBack(){
      // Toast.message(`第${_this.page}页`,null,'center')
    }
}

  // 网络请求
  async dataList(callBack) {
    try {
      this.setState({loading:true})
      ...
      let data = {
        ...,
        page:this.page,
        r:10
      }
      let data_string = queryString.stringify(data)
      let url = ...+'?'+data_string
      const response = await axios.get(url)
      setTimeout(()=>{this.setState({loading:false})},800) // complete

      let code = Number(response.data.code)
      let info = response.data.info

      if (code===0){
        let dataList = response.data.data
        this.dataListFake = this.dataListFake.concat(dataList)
        this.setState({dataList:this.dataListFake})
      }else if (code===9000){ // 根据接口情况而定
        setTimeout(()=>{this.setState({isLast:true})},800)
      }else{
        Toast.sad(info)
      }
      setTimeout(()=>{
        this.setState({
          refresh:false,
          pullDown:false
        }) // 不管数据请求如何,状态归位
      },800)

      console.log(response.data)
      console.log(this.page)
      callBack()  // 假回调

    } catch (error) {
      this.setState({refresh:false,pullDown:false,loading:false})
      Toast.fail('网络请求异常')
    }
  }
复制代码
render() {
    const { dataList, refresh } = this.state
    return (
      <SafeAreaView style={[style.container,{flex:1}]}>
        <StatusBar barStyle="dark-content"/>
        <FlatList
          contentContainerStyle={styles.introduction}
          data={ dataList }
          renderItem={this.renderItem}
          ListFooterComponent={this.renderFooter}
          ListEmptyComponent={this.renderEmpty}
          keyExtractor={this._keyExtractor}
          onEndReached={ this._onEndReached }
          onEndReachedThreshold={0}
          refreshing={refresh}
          refreshControl={
            <RefreshControl
              refreshing={ refresh }
              colors={['#ff0000', '#00ff00', '#0000ff']}
              progressBackgroundColor={"#ffffff"}
              onRefresh={ this._onRefresh }
            />
          }
        />
      </SafeAreaView>
    )
  }

复制代码
react native社区项目知识点

杂文篇

一、条形码扫描 iOS版本

react-native-smart-barcode 可以解决大部分问题,集成时因为propTypes的引入没有兼容高版本导致报错,可以去Barcode.js注释掉 static propTypes

react native社区项目知识点
// 同时利用页面订阅,达到每次显示页面重新扫描的目的
this._listeners = this.props.navigation.addListener('didFocus', ()=> this._startScan())
复制代码

二、富文本解析显示 react-native-htmlview

import HTMLView from 'react-native-htmlview' // 引入
复制代码
<HTMLView
    value={htmlContent}
    addLineBreaks={false} // 去掉每行之间的空格
    stylesheet={styles}/>
复制代码
p:{
    color:'#666666',
    fontSize:15,
    fontWeight:'400',
    lineHeight:20,
    paddingHorizontal: 0,
    marginTop:5,
    marginBottom:5
  }
复制代码

三、swiper滑动应用 react-native-swiper

四、上传多图

要注意的是传多图时axios需要配置的地方

let config = {headers:{'Content-Type':'multipart/form-data'}}
let formData=new FormData()
xxx.forEach((val,key)=>{
  let file = {uri:val.path,type:val.mime,name:val.filename?val.filename:'CAMERA_PHOTO.JPG'}
  formData.append(`img${key}`,file)
})
await axios.post(url,formData,config)
复制代码

五、调起打电话

Linking.openURL(`tel:110`)
复制代码

六、 react-native-image-crop-picker 图片上传遇到的iOS原生问题

1、cd /guyu/ios/podfile
2、cocoapods 安装配置
	sudo gem install cocoapods
	pod setup
	cd ios
	pod init
# 3、配置下面文件
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
# 添加至pod文件里面的配置
target 'guyu' do
    pod 'RSKImageCropper'
    pod 'QBImagePickerController'
end
复制代码

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Designing Data-Intensive Applications

Designing Data-Intensive Applications

Martin Kleppmann / O'Reilly Media / 2017-4-2 / USD 44.99

Data is at the center of many challenges in system design today. Difficult issues need to be figured out, such as scalability, consistency, reliability, efficiency, and maintainability. In addition, w......一起来看看 《Designing Data-Intensive Applications》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具