宝宝秀项目学习(四)

// 1、Modal组件的使用
// 2、TextInput组件的使用
// 3、用户登录界面的设计
// 3.1 定时器的使用
// 3.2  小技巧--根据不同的state显示不同的view
// 3.3  子组件给父组件的回调函数
// 3.4  异步存储获取本地资源
//
//
// 一、
// 1、Modal组件:Modal组件可以用来覆盖包含React Native根视图的原生视图(如UIViewController,Activity)。
// 2、TextInput组件:TextInput是一个允许用户在应用中通过键盘输入文本的基本组件。本组件的属性提供了多种特性的配置,譬如自动完成、自动大小写、占位文字,以及多种不同的键盘类型(如纯数字键盘)等等。

<Modal
    animationType={}  //可选属性有'none', 'slide', 'fade
    transparent={}       //是否透明,设置是否为透明的,true或者是false
    visible={}               //设置此modal是否为可见的true或者是false,一般由状态管理器来设置
    onRequestClose={() => { } }   //销毁modal界面时调用,一般就是设置visible的属性为false就行了
    onShow={}                           //模态在显示的时候调用此函数
>
    {/*这里面就是覆盖在上面的内容*/}
    <View style={styles.modalContant}>
        <Icon
            name="ios-close-outline"
            style={styles.backfromModal}
            size={45}
            onPress={this._backfromModal}
        />

        <View style={this.commentBox}>
            <View style={styles.commentNeirong}>
                <TextInput
                    placeholder={'快来评论吧'} //如果没有任何文字输入,会显示此字符串,即提示信息
                    style={styles.pinlun}
                    onFocus={this._focus}    //当文本框获得焦点时调用此方法
                    onBlur={this._blur}      //当文本框失去焦点时调用此方法
                    defaultValue={this.state.content}  //默认值,即可编辑的一开始就在输入框中
                    onChangeText={(text)=>{
                        this.setState({
                            content:text
                        })
                        //使用onChangeText写入state,然后从this.state中取出值。这是唯一的从输入框中取出输入值方法,text就是输入的内容
                    }}
                />
            </View>
        </View>
        <Button
            onPress={this._submit}
            style={styles.submit}
        >
            提交评论
        </Button>
    </View>
</Modal>
// TextInput在安卓上默认有一个底边框,同时会有一些padding。如果要想使其看起来和iOS上尽量一致,则需要设置padding: 0,同时设置underlineColorAndroid="transparent"来去掉底边框。
// 二、用户登录界面
export default class Loginin extends Component {
    constructor(props) {
        super(props)
        this.state={
            phoneNumber:'',               //电话号码
            codeAlreadysSend:false,     //标记是否点击了获取验证码,即是否成功的发送了请求验证码的请求
            verifyCode:'',                //验证码
            seconds:60                      //倒计时
        }
    }
    render() {
        return (
            <View style={styles.container}>
                <View style = {styles.signupBox}>
                    <Text style = {styles.textTitle}> 快速登录</Text>
                    <View style={{height:45}}>
                        <TextInput
                            placeholder={'输入手机号'}
                            autoCapitalize={'none'} //控制TextInput是否要自动将特定字符切换为大写
                            autoCorrect={false}     //如果为false,会关闭拼写自动修正。默认值是true。
                            keyboardType={'phone-pad'}  //决定弹出的何种软键盘的
                            style={styles.inputArea}
                            underlineColorAndroid='transparent' //
                            onChangeText={(text)=>{
                                this.setState({
                                    phoneNumber:text
                                })
                            }}
                        />
                    </View>
                    {this.state.codeAlreadysSend ?    //判断是否已经成功发送了请求验证码的请求
                        <View style={styles.verifyCodeBox}>
                            <TextInput
                                placeholder={'输入验证码'}
                                autoCapitalize={'none'}
                                autoCorrect={false}
                                keyboardType={'phone-pad'}
                                style={styles.inputArea}
                                underlineColorAndroid='transparent'
                                onChangeText={(text)=>{
                                    this.setState({
                                        verifyCode:text
                                    })
                                }}
                            />
                            {this.state.seconds === 0 ?    //判断倒计时是否结束
                                <View style = {styles.countDown}>
                                    <Text style = {styles.countdownText} onPress={this._getVerifyCode}>重新获取</Text>
                                    {/*如果倒计时结束,那么重新获取验证码*/}
                                </View>
                                :
                                <View style = {styles.countDown}>
                                    <Text style = {styles.countdownText}>剩余{this.state.seconds}秒</Text>
                                </View>
                            }
                        </View>
                        : null
                    }
                    {this.state.codeAlreadysSend ?      //根据不同的状态显示不同的View,用三元运算符
                        <View style={styles.sendBtn}>
                            <Text style={styles.btnText} onPress={this._login}>登录</Text>
                        </View>
                        :
                        <View style={styles.sendBtn}>
                            <Text style={styles.btnText} onPress={this._getVerifyCode}>获取验证码</Text>
                        </View>
                    }
                </View>
            </View>
        );
    }
    //点击登录按钮
    _login = ()=> {
        //去服务器验证手机号码与验证码是否匹配
        //正则匹配
        let phoneNumber = this.state.phoneNumber
        let verifyCode = this.state.verifyCode
        if(!phoneNumber || !verifyCode){
            alert('手机号码或验证码不能为空')
            return       //return后将不在执行下面的代码
        }
        let body = {
            phoneNumber:phoneNumber,
            code:verifyCode
        };
        let url = config.apis.base + config.apis.verify
        request.post(url,body)
            .then(
                (data)=>{
                    if(data && data.success){
                        this.props.afterLogin(data.data);  //向父组件回调数据(login是要放在App.js中的,要放到tab的前面)
                    }else{
                        alert('获取验证码失败,请检查您的手机号是否正确')
                    }
                }
            )
            .catch((err)=>{
                alert('错误'+err)
            })
    }
    //点击获取验证码
    _getVerifyCode = ()=> {
        //去服务器获取验证码
        //正则匹配
        let phoneNumber = this.state.phoneNumber
        if(!phoneNumber){
            alert('手机号码不能为空')
            return
        }
        let body = {
            phoneNumber:phoneNumber
        };
        let url = config.apis.base + config.apis.signup
        request.post(url,body)
            .then(
                (data)=>{
                    if(data && data.success){
                        {this._showVerifyCode()}  //请求成功显示输入验证码的输入框和倒计时(都是由状态机控制着)
                    }else{
                        alert('获取验证码失败,请检查您的手机号是否正确')
                    }
                }
            )
            .catch((err)=>{
                alert('错误'+err)
            })
    }
    //显示验证码的输入框和倒计时
    _showVerifyCode=()=>{
        this.setState({
            codeAlreadysSend:true,
            seconds:5
        })
        //开始倒计时,this._setInterval的目的是将setInterval绑定到this,每一秒钟状态机中的seconds要减去一
        this._interval = setInterval(()=>{
            if(this.state.seconds === 0){
                clearInterval(this._interval)
                return
            }
            this.setState({
                seconds:this.state.seconds - 1
            })},1000);
    }
    /**
     * 生命周期方法,组件将被卸载之前
     */
    componentWillUnmount(){
        this._interval && clearInterval(this._interval)   //用计时器必须在组件将被卸载前清除计时操作,不然容易出问题
    }
}


// react-native官网说:我们发现很多React Native应用发生致命错误(闪退)是与计时器有关。具体来说,是在某个组件被卸载(unmount)之后,计时器却仍然在运行。要解决这个问题,只需铭记在unmount组件时清除(clearTimeout/clearInterval)所有用到的定时器即可:
export default class Hello extends Component {
    componentDidMount() {
        this.timer = setTimeout(
            () => { console.log('把一个定时器的引用挂在this上'); },
            500
        );
    }
    componentWillUnmount() {
        // 请注意Un"m"ount的m是小写

        // 如果存在this.timer,则使用clearTimeout清空。
        // 如果你使用多个timer,那么用多个变量,或者用个数组来保存引用,然后逐个clear
        this.timer && clearTimeout(this.timer);
    }
};

// 在App.js中,已进入render函数,首先判断本地存储中是否有用户信息
if(!this.state.logined){   //这里每执行一次render函数都会重新判断一次logined。
    return(
        <Login afterLogin={this._afterLogin}/>     //用户登录页面,放在tab组件的外面
    )
}
// 用户第一次打开App的时候,登录成功后会将用户信息持久化到本地

//用户登录成功的回调函数(这里是子组件登陆成功,给父组件的回调)
_afterLogin = (user) => {
    //    user是一个用户信息对象
    let user2 =JSON.stringify(user);
    AsyncStorage.setItem('user',user2)      //异步存储用户信息到本地
        .then(     //then()函数是上一步成功后执行
            ()=>{
                this.setState({
                    logined:true,   //注意:state每改变一次,就重新渲染一次(即重新执行一次render函数),
                    user:user2                                            // 所以登陆成功后的页面跳转是不需要Navigator的。
                })
            }
        )
        .catch((err)=>{
            alert('存储发生错误'+err)
        })



    //异步获取用户登录状态和信息
    _asyncGetAppStatus = ()=> {
        AsyncStorage.getItem('user')
            .then(
                (data)=>{
                    let user;
                    let newState = {};   //定义一个空对象
                    if(data){
                        user = JSON.parse(data);  //JSON.parse()方法用来解析json字符串成JavaScript对象
                    }
                    if(user && user.accesssToken){
                        newState.logined = true;
                        newState.user = user;
                        //就相当于 newState = {logined:true,user:user}
                    }else{
                        newState.loaded = false;
                    }
                    this.setState(newState);
                }
            )
            .catch((err) =>{
                alert('AsyncStorage err'+err)
            })
    }   }

基于数据挖掘的音乐推荐系统设计与实现 需要一个代码说明,不需要论文 采用python语言,django框架,mysql数据库开发 编程环境:pycharm,mysql8.0 系统分为前台+后台模式开发 网站前台: 用户注册, 登录 搜索音乐,音乐欣赏(可以在线进行播放) 用户登陆时选择相关感兴趣的音乐风格 音乐收藏 音乐推荐算法:(重点) 本课题需要大量用户行为(如播放记录、收藏列表)、音乐特征(如音频特征、歌曲元数据)等数据 (1)根据用户之间相似性或关联性,给一个用户推荐与其相似或有关联的其他用户所感兴趣的音乐; (2)根据音乐之间的相似性或关联性,给一个用户推荐与其感兴趣的音乐相似或有关联的其他音乐。 基于用户的推荐和基于物品的推荐 其中基于用户的推荐是基于用户的相似度找出相似相似用户,然后向目标用户推荐其相似用户喜欢的东西(和你类似的人也喜欢**东西); 而基于物品的推荐是基于物品的相似度找出相似的物品做推荐(喜欢该音乐的人还喜欢了**音乐); 管理员 管理员信息管理 注册用户管理,审核 音乐爬虫(爬虫方式爬取网站音乐数据) 音乐信息管理(上传歌曲MP3,以便前台播放) 音乐收藏管理 用户 用户资料修改 我的音乐收藏 完整前后端源码,部署后可正常运行! 环境说明 开发语言:python后端 python版本:3.7 数据库:mysql 5.7+ 数据库工具:Navicat11+ 开发软件:pycharm
MPU6050是一款广泛应用在无人机、机器人和运动设备中的六轴姿态传感器,它集成了三轴陀螺仪和三轴加速度计。这款传感器能够实时监测并提供设备的角速度和线性加速度数据,对于理解物体的动态运动状态至关重要。在Arduino平台上,通过特定的库文件可以方便地与MPU6050进行通信,获取并解析传感器数据。 `MPU6050.cpp`和`MPU6050.h`是Arduino库的关键组成部分。`MPU6050.h`是头文件,包含了定义传感器接口和函数声明。它定义了类`MPU6050`,该类包含了初始化传感器、读取数据等方法。例如,`begin()`函数用于设置传感器的工作模式和I2C地址,`getAcceleration()`和`getGyroscope()`则分别用于获取加速度和角速度数据。 在Arduino项目中,首先需要包含`MPU6050.h`头文件,然后创建`MPU6050`对象,并调用`begin()`函数初始化传感器。之后,可以通过循环调用`getAcceleration()`和`getGyroscope()`来不断更新传感器读数。为了处理这些原始数据,通常还需要进行校准和滤波,以消除噪声和漂移。 I2C通信协议是MPU6050与Arduino交互的基础,它是一种低引脚数的串行通信协议,允许多个设备共享一对数据线。Arduino板上的Wire库提供了I2C通信的底层支持,使得用户无需深入了解通信细节,就能方便地与MPU6050交互。 MPU6050传感器的数据包括加速度(X、Y、Z轴)和角速度(同样为X、Y、Z轴)。加速度数据可以用来计算物体的静态位置和动态运动,而角速度数据则能反映物体转动的速度。结合这两个数据,可以进一步计算出物体的姿态(如角度和角速度变化)。 在嵌入式开发领域,特别是使用STM32微控制器时,也可以找到类似的库来驱动MPU6050。STM32通常具有更强大的处理能力和更多的GPIO口,可以实现更复杂的控制算法。然而,基本的传感器操作流程和数据处理原理与Arduino平台相似。 在实际应用中,除了基本的传感器读取,还可能涉及到温度补偿、低功耗模式设置、DMP(数字运动处理器)功能的利用等高级特性。DMP可以帮助处理传感器数据,实现更高级的运动估计,减轻主控制器的计算负担。 MPU6050是一个强大的六轴传感器,广泛应用于各种需要实时运动追踪的项目中。通过 Arduino 或 STM32 的库文件,开发者可以轻松地与传感器交互,获取并处理数据,实现各种创新应用。博客和其他开源资源是学习和解决问题的重要途径,通过这些资源,开发者可以获得关于MPU6050的详细信息和实践指南
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值