REACT-NATIVE小白日记(四)

191 阅读6分钟

今天注定是不平凡的一天

今天呢,我准备挑选大部分RN上的组件,来实现一下,但是聪明机智的我知道今天肯定弄不完,但是我会尽量弄,争取总结一些组件快速使用的方法,为下周开发省一些时间。我目前只能开发安卓环境,下面我会按照RN API文档的顺序做,我估计文档内大部分组件都是我会使用的,所以我也就不浪费时间挑选了,如果真的用不到我就跳过去。

LOADING

同志们,上午我说了大话,对不起。我本来以为经过前三天的磨练,我今天会顺畅无比。但是第一个组件就消耗我将近一天的时间。好的,我来描述一下我今天到底有多废物。

首先呢,我打开了文档看见了第一个组件,ActivityIndicator,这个组件本身呢很简单,简单到,文档都不用看,直接拿过名字来就能用。但是呢,这个组件涉及到一个很常用的功能,就是全局loading。就是请求接口或者进行交互的时候,要给用户显示等待的时间。

那我就开始想方法呗,我想了两种方法

  1. redux
  2. 组件暴露方法

我估计也就这两种方式,那既然用了dva对吧,那dva-loading这么好用的东西当然要用了。可是我一上午都在找loading这个东西他为什么就是undefined,

dva-loading会自己根据effects进行loading的赋值,使用呢就是这样@connect(({model,loading})=>({model,loading}))是吧,这很简单,也很好理解。可是这个loading他就是undefined。原理呢我肯定是不懂的,但是我会百度啊,可是百度上没有RN+dva-loading的问题或者一丁点东西。所以我得到了我的答案,这俩玩应应该没人一起用,所以我就只能用最普通的state值来做了(我刚开始就放弃了组件暴露方法这种方式,看着太low了)。

下面看一下代码吧,毕竟是我从早上写到2点半的代码,我的青春都浪费在了删除键上啊。

model/loading

export default {
    namespace: 'loading',
    state: {
        loading: false
    },
    reducers: {
        SET_LOADING(state, { payload }) {
            return { ...state, loading: payload }
        }
    },
    effects: {
        * setLoading(payload, {put}) {
            yield put({
                type: 'SET_LOADING',
                payload
            })
        }
    }
}

dva的model

然后是 loading组件

import React, { Component } from 'react'
import { StyleSheet, View, ActivityIndicator, Dimensions, Text } from 'react-native'
import { connect } from 'react-redux'
const { width, height } = Dimensions.get('window')

@connect(({ loading }) => ({ loading: loading.loading }))
class Loading extends Component {
    render() {
        const visible = this.props.loading
        return (
            <>
                {
                    visible ?
                        <View style={styles.loadingWrapper}>
                            <View style={styles.loadingContent}>
                                <ActivityIndicator size="large" color="#1296db" />
                                <Text>加载中...</Text>
                            </View>
                        </View> :
                        <View />
                }
            </>

        )
    }
}
export default Loading

const styles = StyleSheet.create({
    loadingWrapper: {
        position: 'absolute',
        display: 'flex',
        top: 0,
        left: 0,
        width: width,
        height: height,
        backgroundColor: 'rgba(0,0,0,0)',
        justifyContent: 'center',
        alignItems: 'center',
    },
    loadingContent: {
        width: 100,
        height: 100,
        borderRadius: 10,
        backgroundColor: 'rgba(0,0,0,0.1)',
        justifyContent: 'center',
        alignItems: 'center',
    }
})

这里有个坑,也是浪费了我将近1个小时的时间,先看组件引用,我放在了dva中。

export default function (options) {
   ...
    app.start = container => () =>
        <Provider store={store}>
            <Loading />
            {container}
        </Provider>
    ...
}

原来呢,我把loading组件放在了上面,可是怎么调试都没有效果。我以为是我的样式有问题,我就不断地调整样式。最后我放弃了我百度了一下,然后1分钟没用上我就解决了。原因是安卓对position:absolute的显示有要求,必须放在最下面。所以如下:

export default function (options) {
   ...
    app.start = container => () =>
        <Provider store={store}>
            {container}
            <Loading />
        </Provider>
    ...
}

他就好使了。我因为我的无知感到生气。 然后是触发Loading的显示。虽然没有dva-loading那么方便,但是我觉得还可以,如下:

    effects: {
        * fetchUserInfo(_, { put, call,select }) {
            yield put({
                type: 'loading/SET_LOADING',
                payload: true
            })
            const UserInfo = yield call(fetchUserInfo)
            yield put({
                type: 'SET_USER_INFO',
                payload: UserInfo.result
            })
            yield put({
                type: 'loading/SET_LOADING',
                payload: false
            })
        }
    }

以上呢,就是全局loading了,我太难了。

Button

这个按钮是固定样式的,只能修改宽度和title,宽度会根据父元素的宽度自适应,我觉得是flex:1,毕竟RN到处都在说推荐使用flex:1。下面就是这个按钮的展示,文档中说如果这个样式不能满足需求,那还有另外两种方式来实现按钮,这个肯定要验证一下。

import React, { Component } from 'react'
import { Button, View } from 'react-native'

export default class Buttons extends Component {
    render() {
        return (
            <View>
                <View style={{ width: 100, margin: 20 }}>
                    <Button title="确定" />
                </View>
                <View style={{ width: 200, margin: 20 }}>
                    <Button title="确定" />
                </View>
                <View style={{ width: 400, height: 50, margin: 20 }}>
                    <Button title="确定" />
                </View>
                <Button title="确定" />
            </View>
        )
    }
}

另外的两个组件分别是TouchableOpacityTouchableNativeFeedback

TouchableOpacity

这个组件的点击效果是让按钮(按钮里面的所有的东西都会)变得透明,文档中有修改透明度的API,详细可以看文档。

//使用图片作为按钮
<TouchableOpacity style={{ margin: 50 }}>
    <Image source={require('../../assets/img/news.png')} />
</TouchableOpacity>

//使用View和Text作为按钮
<TouchableOpacity style={{ margin: 50 }}>
    <View style={{width:50,height:50,backgroundColor:'#000'}}>
        <Text style={{color:'yellow'}}>PRESS</Text>
    </View>
</TouchableOpacity>

TouchableNativeFeedback

这个仅限安卓,详细看文档吧,我觉得我可能不会用它,他只能接收View

<TouchableNativeFeedback>
    <View style={{ backgroundColor: '#432575',height: 50 }}>
        <Text style={{textAlign:'center',lineHeight:50,color:'#FFF'}}>PRESS</Text>
    </View>
</TouchableNativeFeedback>

当我写道这里的时候,由于按钮太多了,一屏已经显示不下了,但是并没有出现滚动条。已经成长的我,就知道事情没有那么简单,所以,我找到了下一个要学习的组件 ScrollView

ScrollView

这个组件呢,文档呢有很多说明,要给什么样的高度,要给自适应,我怕踩坑,就按照文档的要求,一顿给。然后看模拟器,不好使。嗯,开心。 然后我就把给了的高度和自适应全删了,然后准备好好捋顺一下,重新给值。删了之后呢,我就随便看了一眼模拟器,竟然可以滚动了。不知所措,满脸微笑。我不知道别人都是怎么整出来的,不多说了 看代码吧。

  render() {
    const { name, remark, email } = this.props.user.userInfo
    return (
      <View>
        <ScrollView>
          <Text>我是一个首页,请看看我吧</Text>
          <Text>姓名: {name}</Text>
          <Text>签名: {remark}</Text>
          <Text>E-MAIL: {email}</Text>
          <Button title={'获取数据'} onPress={this.fetchData} />
          <Buttons />
        </ScrollView>
      </View>
    )
  }

ScrollView外面只有一层View。现在是可以滚动的,我不是很懂了,有人指点一下它为什么好使吗??????????????????home页的外层就是Provider了,没有其他我给过高度的元素,恍恍惚惚。

今天结束了

这周都结束了,我太难了。下周不知道需求能不能来,如果不来的话,我还有时间能多学一点,如果来了我可能就要谢顶了。我对不起我的头发,抱歉,十分抱歉。下周见吧。