当前位置:首页 > 芯闻号 > 充电吧
[导读]关于如何集成TabBar,请看上一节《【搭建react-native项目框架】3.集成第三方路由和tab页》本节只讲解如何自定义TabBar的中间按钮,以及播放时旋转动画的实现。关于动画与播放器的集成

关于如何集成TabBar,请看上一节《【搭建react-native项目框架】3.集成第三方路由和tab页》

本节只讲解如何自定义TabBar的中间按钮,以及播放时旋转动画的实现。

关于动画与播放器的集成可以参考https://github.com/pheromone/react-native-videoDemo,但这个项目目前安卓存在bug,所以我只借鉴了动画部分。

还是先来看效果图


其实思路很简单,首先要使TabBar把中间按钮的位置空出来,然后摆上一个悬浮的按钮,就能实现中间按钮了。1.设置CustomTabBar的placeMiddle属性为true,这个属性表示是否把中间按钮的位置留出来。
                    

2.悬浮效果可以用绝对定位来实现,见下图


在components下新建一个playButton.js文件。先写一个外层View,绝对定位到页面底部中间位置;再做个带边框的圆形View;然后用长方形View将圆形View下半部的边框覆盖;最后写个旋转图和按钮。

                
                    
                    
                     this.play()} underlayColor="transparent" style={[styles.playInner]}>
                        
                            
                            
                        
                    
                

const styles = StyleSheet.create({
    playBox: {
        width: Common.autoScaleSize(128),
        height: Common.autoScaleSize(136),
        position: 'absolute',
        bottom: 0,
        left: Common.autoScaleSize(311),
        flexDirection: 'column',
        justifyContent: 'flex-start',
        alignItems: 'center',
    },
    playBoxCircle: {
        backgroundColor: '#ffffff',
        width: Common.autoScaleSize(128),
        height: Common.autoScaleSize(128),
        borderRadius: Common.autoScaleSize(128),
        position: 'absolute',
        bottom: Common.autoScaleSize(8),
        borderWidth: Common.autoScaleSize(1),
        borderColor: '#cdcdcd',
    },
    playBoxBackground: {
        backgroundColor: '#ffffff',
        width: Common.autoScaleSize(125),
        height: Common.autoScaleSize(72),
        position: 'absolute',
        bottom: 0,
        left: Common.autoScaleSize(1),
    },
    playInner: {
        width: Common.autoScaleSize(101),
        height: Common.autoScaleSize(101),
        borderRadius: Common.autoScaleSize(101),
        position: 'absolute',
        bottom: Common.autoScaleSize(20),
        flexDirection: 'column',
        justifyContent: 'center',
        alignItems: 'center',
    },
    playInnerBox: {
        backgroundColor: '#cdcdcd',
        width: Common.autoScaleSize(101),
        height: Common.autoScaleSize(101),
        borderRadius: Common.autoScaleSize(101),
        flexDirection: 'column',
        justifyContent: 'center',
        alignItems: 'center',
    },
    playBackImage: {
        width: Common.autoScaleSize(101),
        height: Common.autoScaleSize(101),
        borderRadius: Common.autoScaleSize(101),
        position: 'absolute',
    },
});
3.实现旋转动画。

先构造初始旋转角度、播放状态和旋转动画

        this.state = {
            playImage: require('./resources/images/play.png'),
            rotateValue: new Animated.Value(0), //旋转角度的初始值
        };
        this.isPlaying = false;
        this.playerAnimated = Animated.timing(this.state.rotateValue, {
            toValue: 1, //角度从0变1
            duration: 15000, //从0到1的时间
            easing: Easing.inOut(Easing.linear), //线性变化,匀速旋转
        });

根据播放状态切换播放按钮的图标,并开始/暂停播放

    play() {
        this.isPlaying = !this.isPlaying;
        if (this.isPlaying === true) {
            this.setState({
                playImage: require('./resources/images/pause.png'),
            });
            this.startPlay();
        } else {
            this.setState({
                playImage: require('./resources/images/play.png'),
            });
            this.stopPlay();
        }
    }

开始播放

    startPlay() {
        this.playerAnimated.start(() => {
            this.playerAnimated = Animated.timing(this.state.rotateValue, {
                toValue: 1, //角度从0变1
                duration: 15000, //从0到1的时间
                easing: Easing.inOut(Easing.linear), //线性变化,匀速旋转
            });
            this.rotating();
        });
    }

暂停播放

    stopPlay() {
        this.state.rotateValue.stopAnimation((oneTimeRotate) => {
            //计算角度比例
            this.playerAnimated = Animated.timing(this.state.rotateValue, {
                toValue: 1,
                duration: (1-oneTimeRotate) * 15000,
                easing: Easing.inOut(Easing.linear),
            });
        });
    }

开始旋转动画

    rotating() {
        if (this.isPlaying) {
            this.state.rotateValue.setValue(0);
            this.playerAnimated.start(() => {
                this.rotating()
            })
        }
    };
4.在App.js文件中引入playButton.js
import PlayButton from "./components/playButton";

在最外层View组件底部渲染PlayButton

            
                //Router......
                
            


最后上完整的playButton.js代码
import React, { Component } from 'react';
import {
    Animated,
    Easing,
    StyleSheet,
    View,
    TouchableOpacity,
    Image,
} from "react-native";
//自定义组件
import Common from "./common";
//页面
import PlayScreen from '../views/play'; //播放页

export default class PlayButton extends Component {
    constructor(props) {
        super(props);
        //使用Animated.Value设定初始化值(角度)
        this.state = {
            playImage: require('../resources/images/play.png'),
            rotateValue: new Animated.Value(0), //旋转角度的初始值
        };
        this.isPlaying = false;
        this.playerAnimated = Animated.timing(this.state.rotateValue, {
            toValue: 1, //角度从0变1
            duration: 15000, //从0到1的时间
            easing: Easing.inOut(Easing.linear), //线性变化,匀速旋转
        });
    }

    play() {
        this.isPlaying = !this.isPlaying;
        if (this.isPlaying === true) {
            this.setState({
                playImage: require('../resources/images/pause.png'),
            });
            this.startPlay();
        } else {
            this.setState({
                playImage: require('../resources/images/play.png'),
            });
            this.stopPlay();
        }
    }

    rotating() {
        if (this.isPlaying) {
            this.state.rotateValue.setValue(0);
            this.playerAnimated.start(() => {
                this.rotating()
            })
        }
    };

    startPlay() {
        this.playerAnimated.start(() => {
            this.playerAnimated = Animated.timing(this.state.rotateValue, {
                toValue: 1, //角度从0变1
                duration: 15000, //从0到1的时间
                easing: Easing.inOut(Easing.linear), //线性变化,匀速旋转
            });
            this.rotating();
        });
    }

    stopPlay() {
        this.state.rotateValue.stopAnimation((oneTimeRotate) => {
            //计算角度比例
            this.playerAnimated = Animated.timing(this.state.rotateValue, {
                toValue: 1,
                duration: (1-oneTimeRotate) * 15000,
                easing: Easing.inOut(Easing.linear),
            });
        });
    }

    render() {
        return (
            
                
                
                 this.play()} underlayColor="transparent" style={[styles.playInner]}>
                    
                        
                        
                    
                
            
        );
    }
}

const styles = StyleSheet.create({
    playBox: {
        width: Common.autoScaleSize(128),
        height: Common.autoScaleSize(136),
        position: 'absolute',
        bottom: 0,
        left: Common.autoScaleSize(311),
        flexDirection: 'column',
        justifyContent: 'flex-start',
        alignItems: 'center',
    },
    playBoxCircle: {
        backgroundColor: '#ffffff',
        width: Common.autoScaleSize(128),
        height: Common.autoScaleSize(128),
        borderRadius: Common.autoScaleSize(128),
        position: 'absolute',
        bottom: Common.autoScaleSize(8),
        borderWidth: Common.autoScaleSize(1),
        borderColor: '#cdcdcd',
    },
    playBoxBackground: {
        backgroundColor: '#ffffff',
        width: Common.autoScaleSize(128),
        height: Common.autoScaleSize(101),
        position: 'absolute',
        bottom: 0,
    },
    playInner: {
        width: Common.autoScaleSize(101),
        height: Common.autoScaleSize(101),
        borderRadius: Common.autoScaleSize(101),
        position: 'absolute',
        bottom: Common.autoScaleSize(20),
        flexDirection: 'column',
        justifyContent: 'center',
        alignItems: 'center',
    },
    playInnerBox: {
        backgroundColor: '#cdcdcd',
        width: Common.autoScaleSize(101),
        height: Common.autoScaleSize(101),
        borderRadius: Common.autoScaleSize(101),
        flexDirection: 'column',
        justifyContent: 'center',
        alignItems: 'center',
    },
    playBackImage: {
        width: Common.autoScaleSize(101),
        height: Common.autoScaleSize(101),
        borderRadius: Common.autoScaleSize(101),
        position: 'absolute',
    },
});

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

前端传递:表名 user,字段 username 字符串、age 数字、is_ikun 布尔,并且把这些值封装为了一个对象

关键字: 框架 前端

摘要:J2EE是目前企业开发的主流Java开发应用平台,文章主要介绍了轻量级J2EE中流行的Struts2、Spring和Hibernate三种框架。具体阐述了SSH框架的基本特征、优点以及SSH的无缝集成,并结合病房信...

关键字: 轻量级J2EE SSH 框架 无缝集成 病房信息管理系统

在软件研发这个领域,程序员的终极目标都是想成为一名合格的架构师。

关键字: 架构 框架 软件研发

  近日召开的ARM TechCon大会着眼于小型物联网设备的安全性问题发布了一系列重要新闻,不过除此之外亦有大量其它有趣的技术成果在这里得到展示。从系统芯片设计到用于位置服务的软件代理,可谓一

关键字: react thunderboard 传感器 开发套件 芯科科技

在芯片性能提升有限的今天,分布式训练成为了应对超大规模数据集和模型的主要方法。本文将向你介绍流行深度学习框架 PyTorch 最新版本( v1.5)的分布式数据并行包的设计、实现和评估。 论文地

关键字: pytorch 机器学习 框架

近日,中国国防科技大学、美国加州大学洛杉矶分校和哈佛医学院的研究人员研发了一个深度强化学习框架FINDER。相比于现有的解决方案,FINDER能够更快速、更高效地找到复杂网络中一组最关键的节点,

关键字: AI 开发 框架

众所周知,清华-伯克利深圳学院更是成立了“RISC-V 国际开源实验室”,直接将图灵奖得主、最早提出“精简指令集”(RISC)体系的大卫·帕特森(David Patterson)引入,抓住了开源和源创的源头,有可能在芯片...

关键字: 开源 框架

全球“数字硅幕”正在落下?数字经济时代,数据不仅是重要的资源和生产要素,更成为国家基础性战略资产。

关键字: 数字 框架 硅幕

近日,美国同英国签署历史性网络公司数据互通协议,赋予两国政府“长臂管辖权”。数字经济时代,数据不仅是重要的资源和生产要素,更成为国家基础性战略资产。

关键字: 数字 框架 硅幕

现在最热门的前端框架,毫无疑问是React。 上周,基于 React 的React Native发布,结果一天之内,就获得了 5000 颗星,受瞩目程度可见一斑。 React 起源于 Face

关键字: react 前端框架
关闭
关闭