ReactNative入门(安卓)——API(上)

ReactNative入门(安卓)——API(上)Alert-弹窗通过Alert.alert()方法调用唤起原生弹窗,点击会触发onPress回调(参考下方代码)并清除弹窗。importReact,{AppRegistry,C

大家好,又见面了,我是你们的朋友全栈君。

Alert – 弹窗

通过 Alert.alert() 方法调用唤起原生弹窗,点击会触发 onPress 回调(参考下方代码)并清除弹窗。

<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)
<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)

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

class AwesomeProject extends Component {
    componentDidMount(){
        Alert.alert(
            'Alert标题',
            '一些正文内容',
            [
                //{text: '稍后询问', onPress: () => console.log('Ask me later pressed')},
                //{text: '取消', onPress: () => console.log('Cancel Pressed')},
                {text: 'OK', onPress: () => console.log('OK Pressed')}
            ]
        )
    }
    render() {
        return (
            <View style={styles.container}>
                <Text style={styles.text}>
                    DEMO
                </Text>
            </View>
        );
    }
}

View Code

按钮数量将决定其排版(下图),不同于ios,安卓无法定义按钮样式:

<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)

(单个按钮情况)

<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)

(两个按钮情况)

<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)

(三个按钮情况)

<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)

Animated – 动画接口

篇幅较大,故独立写了两篇文章:

ReactNative入门 —— 动画篇(上)

ReactNative入门 —— 动画篇(下)

<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)

AppRegistry – APP注册接口

最常用的接口,特别是 AppRegistry.registerComponent 方法,用于注册根组件到当前APP,进而让原生系统加载时可以执行对应的bundle文件:

AppRegistry.registerComponent('AppName', () => RootComponent);

除了 registerComponent 之外,还提供了其它一些比较少用的接口:

registerConfig(config<Array>)  //注册配置
registerRunnable(appKey<String>, func<Function>)  //注册函数监听
getAppKeys()  //获取registerRunnable注册的监听键
runApplication(appKey<String>, appParams<any>)  //运行App

<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)

AppState – 应用状态

通过此接口可以获悉应用在当前处于后台还是前台激活的状态,常用方法和应用场景类似于h5的visibilitychange。

注意该接口要最新版本(2.0+)的 react-native 才能调用。

获取到的应用状态常规有:

active:表示应用处于前台运行状态;
background:表示应用处于后台挂起状态;
inactive:过渡状态,常规不会发生,可以先忽略该状态。

我们可以使用 AppState.addEventListenerAppState.removeEventListener 方法来监听、移除应用状态的 change 事件。

另外也可以直接使用 AppState.currentState 来获得应用当前的状态:

<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)
<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)

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

class AwesomeProject extends Component {
    componentDidMount() {
        AppState.addEventListener('change', this._handleAppStateChange);
        //组件挂载时获取当前状态
        Alert.alert('当前状态', AppState.currentState, [{text: 'OK'}]);
    }

    componentWillUnmount() {
        AppState.removeEventListener('change', this._handleAppStateChange);
    }

    _handleAppStateChange(currentAppState) {
        currentAppState==='active' && Alert.alert('状态转变', currentAppState, [{text: 'OK'}])
    }

    render() {
        return (
            <View style={styles.container}>
                <Text style={styles.text}>
                    DEMO
                </Text>
            </View>
        );
    }
}

View Code

<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)

注:如果在模拟器中出现“screenPhysicalPixels undefined”的问题,试着执行 react-native upgrade 来更新gradle(见此issue

<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)

AsyncStorage – 异步存储

类似于 localStorage,常用于本地存储一些键值对类型的数据,这些存储的数据对应整个应用本身而已是全局性质的(类似 localStorage 在同个域下共享)

其对外方法主要有:

getItem(key<String>, [callback<Function(error, result)>])
获取单个数据,返回一个 Promise 对象

setItem(key<String>, [callback<Function(error)>])
设置单个数据,返回一个 Promise 对象

removeItem(key<String>, [callback<Function(error)>])
移除单个数据,返回一个 Promise 对象

mergeItem(key<String>, value<String>, [callback<Function(error)>])
合并某个已存在的数据项,通常该项为stringified json格式。该接口返回一个 Promise 对象

clear([callback<Function(error)>])
清除全部 AsyncStorage 数据,返回一个 Promise 对象

getAllKeys(callback<Function(error, keys)>)
获取所有键,返回一个 Promise 对象
flushGetRequests() 清空所有进行中的查询 multiGet(keys<Array>, [callback<Function(error, keys)>]) 
获取多项,查询 keys(字符串数组)指定的多个键来查询对应的值。该接口返回一个 Promise 对象

multiGet(keys<Array>, [callback<Function(error, keyValuePairs)>]) 
获取多项,参数 keys 是一个字符串数组,回调里的形参 keyValuePairs 是字符串的二维数组,表示最终获得的键值对组。该接口返回一个 Promise 对象

multiSet(keyValuePairs<Array>, [callback<Function(error, keys)>]) 
设置多项,参数 keyValuePairs 是字符串的二维数组。该接口返回一个 Promise 对象

multiRemove(keys<Array>, [callback<Function(error)>]) 
移除 keys(字符串数组)指定的多项。返回一个 Promise 对象

multiMerge(keyValuePairs<Array>, [callback<Function(error)>]) 
合并多项已有的键值对,参数 keyValuePairs 是字符串的二维数组。该接口返回一个 Promise 对象。注意该接口还不完善,未能被所有原生支持。

先来看一个简单的 AsyncStorage 数据设置与获取:

<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)
<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)

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

class AwesomeProject extends Component {
    constructor(props) {
        super(props);
        this.state = {
            time : '123'
        };
    }
    componentDidMount() {
        AsyncStorage.setItem('timeStamp', Date.now() + '', function(err){
            //错误处理
            err && console.log(err)
        }).done(function(){
            Alert.alert(
                '恭喜',
                '数据设置成功',
                [
                    {text: 'OK', onPress: () => {}}
                ]
            )
        })
    }
    _getData() {
        AsyncStorage.getItem('timeStamp', function(err, data){
            if(err) return console.log(err);
            this.setState({
                time : data
            })
        }.bind(this));
    }

    render() {
        return (
            <View style={styles.container}>
                <Text style={styles.text}>
                    {this.state.time || '暂无数据'}
                </Text>

                <View style={styles.btnWrap}>
                    <Text style={styles.btn} onPress={this._getData.bind(this)}>点我获取</Text>
                </View>
            </View>
        );
    }
}

View Code

<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)

再来一个 multiSet 和 multiGet 的示例:

<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)
<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)

class AwesomeProject extends Component {
    constructor(props) {
        super(props);
        this.state = {
            a : ''
        };
    }
    componentDidMount() {
        var me = this;
        AsyncStorage.multiSet([['a','1'], ['b','2']], function(err){
            if(err) return console.log(err);
            AsyncStorage.multiGet(['a', 'b'], function(err, keyValuePairs) {
                keyValuePairs.forEach(function (keyValuePair) {
                    if (keyValuePair[0] === 'a') {
                        me.setState({
                            a: keyValuePair[1]
                        })
                    }
                });
            })
        })
    }
    _mergeData() {
        var me = this;
        AsyncStorage.multiSet([['a','5'], ['c','2']], function(err){
            if(err) return console.log(err);
            AsyncStorage.getItem('a', function(err, value) {
                me.setState({
                    a: value
                })
            })
        })
    }

    render() {
        return (
            <View style={styles.container}>
                <Text style={styles.text}>
                    {this.state.a || '加载中'}
                </Text>

                <View style={styles.btnWrap}>
                    <Text style={styles.btn} onPress={this._mergeData.bind(this)}>点我合并</Text>
                </View>

                <View style={styles.btnWrap}>
                    <Text style={styles.btn} onPress={AsyncStorage.getItem.bind(this, ['0',{}])}>点我reload</Text>
                </View>
            </View>
        );
    }
}

View Code

注意 multiMerge 接口还不能被所有原生环境支持,调用的时候很可能会直接报错。事实上可以直接用 multiSet 替代。

<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)

BackAndroid – 返回处理

可以通过该接口来处理应用返回事件。

通过 BackAndroid.addEventListener 和 BackAndroid.removeEventListener 事件,可以监听/移除用户点击安卓设备系统返回键的事件。

通过 BackAndroid.exitApp() 方法可以直接退出当前应用:

class AwesomeProject extends Component {
    constructor(props) {
        super(props);
        this.state = {
            a : ''
        };
    }
    componentDidMount() {
        BackAndroid.addEventListener('hardwareBackPress', this._handleBackPressed.bind(this));
    }
    componentWillUnmount() {
        BackAndroid.removeEventListener('change', this._handleBackPressed.bind(this));
    }
    _handleBackPressed() {
        this.setState({
            a : 'backPressed'
        })
    }
    _exitApp() {
        BackAndroid.exitApp()
    }

    render() {
        return (
            <View style={styles.container}>
                <Text style={styles.text}>
                    {this.state.a || '加载中'}
                </Text>

                <View style={styles.btnWrap}>
                    <Text style={styles.btn} onPress={this._exitApp.bind(this)}>退出应用</Text>
                </View>
            </View>
        );
    }
}

效果1——点击系统返回键:

<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)

效果2——调用 exitApp 方法:

<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)

<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)

CameraRoll – 相册接口

与相册交互的接口,然而安卓这块没IOS的支持好用(无法保存非本地图片)。

1. 通过 CameraRoll.saveImageWithTag(uri) 可以保存某张本地图片到相册,其中 uri 必须为本地地址(例如 ‘file:///sdcard/img.png’)

该接口返回一个 Promise 对象(成功时的回调参数为图片存储后的图片ID):

    _handleSavePic() {
        var me = this;
        CameraRoll.saveImageWithTag('file:///sdcard/img.png').done(function(uri){
            me.setState({
                a : uri
            })
        }, function(err){
            Alert.alert(
                '保存失败',
                JSON.stringify(err),
                [
                    {text: 'OK'}
                ]
            )
        })
    }

2. 通过 CameraRoll.getPhotos(params<Object>) 可以从相册里去获取图片,其中 params 参数格式为:

{
  first : 3,  //获取图片的个数
  groupTypes : React.propTypes.oneOf([  //分组类型
      'Album',
      'All',
      'Event',
      'Faces',
      'Library',
      'PhotoStream',
      'savePhotos'
  ]),
  assetType : React.propTypes.oneOf([  //资源类型
      'Photos',
      'All',
      'Videos'
  ])
}

该接口返回一个 Promise 对象,成功的回调参数数据格式为:

{
  edges: [{
      node: {
          timestamp: 1405312098,
          group_name: 'CameraRoll',
          type: 'ALAssetTypePhoto',
          image: {
              isStored: true,
              height: 669,
              uri: 'asset-library: //asset/assert.JPG?id=C9DB366F-350876C78006&ext=JPG',
              width: 1008
          }
    },
    {node: ....}
  }],
  page_info: {
      has_next_page: true,
      start_cursor: 'asset-library: //asset/assert.JPG?id=C9DB366F-350876C78006&ext=JPG',
      end_cursor: 'asset-library...'
  }
}
//参考至“ReactNative入门与实战”一书162页

来个简单示例:

    _handleGetImages() {
        var me = this;
        var params = {
            first : 3,
            groupTypes : 'Album',
            assetType : 'Photos'
        };
        CameraRoll.getPhotos(params).done(function(data){
            var edges = data.edges,
                photos = [];
            edges.forEach(function(edge){
                photos.push(edge.node.image.uri)
            });
            me.setState({
                photos: photos
            })
        }, function(err){
            Alert.alert(
                '打开相册失败',
                JSON.stringify(err),
                [
                    {text: 'OK'}
                ]
            )
        })
    }

<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)

Clipboard – 剪切板

该模块接口具有获取/设置剪切板内容的能力。

通过 Clipboard.getString() 可以获得设备剪切板内容,通过 Clipboard.setString(content<String>) 可以设置剪切板内容:

class AwesomeProject extends Component {
    constructor(props) {
        super(props);
    }
    _onPress(){
        Clipboard.setString('你好啊')
    }

    render() {
        return (
            <View style={styles.container}>
                <TouchableOpacity>
                    <View style={[styles.button,{backgroundColor:'#CCC'}]}>
                        <TextInput />
                    </View>
                </TouchableOpacity>

                <TouchableOpacity onPress={this._onPress}>
                    <View style={styles.button}>
                        <Text style={styles.buttonText}>修改剪切板内容为“你好啊”</Text>
                    </View>
                </TouchableOpacity>
            </View>
        );
    }
}

<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)

<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)

DatePickerAndroid – 日期选择器

通过 DatePickerAndroid.open(options<Object>) 方法可以打开一个标准的Android时间选择器的对话框,并返回一个Promise对象。

其中 options 参数参考如下:

date (Date对象或毫秒时间戳) - 默认显示的日期
minDate (Date对象或毫秒时间戳) - 可选的最小日期
maxDate (Date对象或毫秒时间戳) - 可选的最大日期

Promise的回调参数为: 

action - 对应动作,若为取消对话框,该值为 DatePickerAndroid.dismissedAction
year - 选中的年份,若为取消对话框,该值为undefined
month (0-11) - 选中的月份,若为取消对话框,该值为undefined
day - 选中的天值,若为取消对话框,该值为undefined

因此我们可以通过判断 Promise 回调中的 action 是否等价于 DatePickerAndroid.dismissedAction,来得知用户是否做了取消对话框的行为:

<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)
<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)

class AwesomeProject extends Component {
    constructor(props) {
        super(props);
    }
    _onPress(){
        DatePickerAndroid.open({
            date: new Date(),
            minDate: new Date('1900/01/01'),
            maxDate: new Date('2100/12/12')
        }).done(function(params){
            var content = '';
            if(params.action !== DatePickerAndroid.dismissedAction){
                content = '你选中了' + params.year + '年' + (params.month+1) + '月' + params.day + '日'
            } else {
                content = '你退出了时间选择对话框'
            }

            Alert.alert(
                '时间选择结果',
                content,
                [
                    {text: 'OK', onPress: () => console.log('OK Pressed')}
                ]
            )
        })
    }

    render() {
        return (
            <View style={styles.container}>
                <TouchableOpacity onPress={this._onPress}>
                    <View style={styles.button}>
                        <Text style={styles.buttonText}>打开日期选择器</Text>
                    </View>
                </TouchableOpacity>

                <TouchableOpacity>
                    <View style={styles.button}>
                        <Text style={styles.buttonText}>somebtn</Text>
                    </View>
                </TouchableOpacity>
            </View>
        );
    }
}

View Code

<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)

<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)

Dimensions – 获取应用窗口尺寸

可通过 Dimensions.get(‘window’) 来获取当前窗口尺寸,得到一个含有 width 和 height 属性的对象。

常用于设置图片宽高(例如设置图片宽度为屏幕宽度):

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

class AwesomeProject extends Component {
    constructor(props) {
        super(props);
        this.state = {
            width : '',
            height : ''
        };
    }
    componentDidMount() {
        var win_info = Dimensions.get('window');
        this.setState({
            width: win_info.width,
            height: win_info.height
        })
    }
    render() {
        return (
            <View style={styles.container}>
                <Text style={styles.text}>
                    屏幕宽度:{this.state.width || '加载中'}
                </Text>
                <Text style={styles.text}>
                    屏幕高度:{this.state.height || '加载中'}
                </Text>
            </View>
        );
    }
}

启动后显示效果如下:

<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)

<span role="heading" aria-level="2">ReactNative入门(安卓)——API(上)

InteractionManager – 交互管理器

在web页面,我们常规会使用 setImmediate/setTimeout/requestAnimationFrame 来定义动画下一帧的执行时间点,在 RN 的动画交互中,我们通过使用 InteractionManager.runAfterInteractions() 来做对应处理是最佳的选择。

例如我们希望安卓切换场景的时候,能在场景切换动画结束了才开始执行某些操作,可以这么写:

componentDidMount: function(){
    InteractionManager.runAfterInteractions(() => {
        //TODO: some events
    });
}

另外我们可以通过 createInteractionHandle() 接口创建一个交互句柄,通知系统当前有个动画交互开始了。

动画结束时再通过 clearInteractionHandle(handle) 来通知系统该动画交互已结束。

示例:

var handle = InteractionManager.createInteractionHandle();
// 开始执行某些动画交互... (`runAfterInteractions` 任务会被压入队列中等候动画结束)
// 动画交互执行完毕的时候执行clearInteractionHandle通知系统交互结束:
InteractionManager.clearInteractionHandle(handle);
// 触发runAfterInteractions

另外 InteractionManager 还有一个静态方法 setDeadline(deadline<Number>),用于(使用setTimeout来)挂起所有尚未执行的任务。

donate

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/155746.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 初识kafka

    初识kafka

    2021年11月27日
    57
  • 【数据增强】Cutout「建议收藏」

    【数据增强】Cutout「建议收藏」论文:ImprovedRegularizationofConvolutionalNeuralNetworkswithCutout.Github:https://github.com/uoguelph-mlrg/Cutout.Cutout的出发点和随机擦除一样,也是模拟遮挡,目的是提高泛化能力,实现上比RandomErasing简单,随机选择一个固定大小的正方形区域,然后采用全0填充就OK了,当然为了避免填充0值对训练的影响,应该要对数据进行中心归一化操作,norm到0。(如果你还不了

    2022年9月25日
    0
  • pytorch中tensor转numpy

    pytorch中tensor转numpycputensor转numpy:#假定a为tensora.numpy()gputensor转numpy:gpu下的tensor不能直接转numpy,需要先转到cputensor后再转为numpya.cpu().numpy()注:若tensor带有梯度,以上述方式转换时会报错:RuntimeError:Can’tcallnumpy()onTensorthatrequiresgrad.Usetensor.detach().numpy()instead.

    2022年10月19日
    0
  • Unity Odin从入门到精通(三):静态检查器详解

    Unity Odin从入门到精通(三):静态检查器详解前言:开发者可以使用静态检查器来选择项目工程、Unity引擎、.Net框架中所有的类型,并查看其所有的静态成员。打开静态检查器:在Unity的菜单栏中选择【Tools->OdinInspector->StaticInspector】菜单项来打开静态检查器。如下图所示:查看静态检查器的源码:首先在Rider当中切换到Assemblies视图。接着在该视图的列表当中选择Sirenix.OdinInspector.Editor程序集。然后从该程序集的列表当中选择Sirenix.Odi

    2022年7月21日
    11
  • web服务基础及web服务器搭建过程「建议收藏」

    web服务基础及web服务器搭建过程「建议收藏」当我们打开一个浏览器输入一个网站时,它会先找缓存再找hosts文件,如果缓存和hosts文件有相对应的地址的时候,就会直接拿到IP地址,(在互联网上计算机与计算机通信用的是IP,但IP地址太难记住为了方便我们人浏览网站就采用了字符串注入了域名的方式所以我们在打开网站输入地址的时候它首先就会做一个域名的解析工作)DNS架构:从后往前看…

    2022年5月8日
    54
  • 根据经纬度计算两点之间的距离的公式是_知道两点经纬度求距离

    根据经纬度计算两点之间的距离的公式是_知道两点经纬度求距离//距离单位米publicstaticdoublealgorithm(doublelongitude1,doublelatitude1,doublelongitude2,doublelatitude2){doubleLat1=rad(latitude1);//纬度doubleLat2=rad(latitude2);doublea=Lat1-Lat2;//…

    2022年9月16日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号