react native触摸遥控器解决方案

完整代码(不可完全复制,仅供参考逻辑

/**
 * Created by apple on 2016/11/7.
 */
import React,{ Component } from 'react';
import {
    View,
    Navigator,
    StyleSheet,
    Image,
    TouchableOpacity,
    Alert,
    Text,
    TouchableHighlight,
    PanResponder,
    Animated,
    Easing
} from 'react-native';
import Language from '../../common/language';
import Nav from '../../common/MineNav';
import Util from '../../common/common';
import Gsoap from '../../common/gsoap';
import * as TYPES from '../../common/types';

var TouchRemote = React.createClass({
    debugMsg: true,
    _panResponder: null,
    movePos: [],
    bounceValue: new Animated.Value(0),
    getDefaultProps: function () {
        return ({
            controlType: "keyBoardType",
            connectSTBToken: {}
        });
    },
    getInitialState: function () {
        return {
            powerState: false,
            homeState: false,
            keyBoard: false,//up down left right ok
            menuState: false,
            backState: false,
            volumeUpState: false,
            volumeDownState: false
        };
    },
    componentWillMount: function () {
        this.console("componentWillMount===controlType:" + this.props.controlType + ";connectSTBToken:" + JSON.stringify(this.props.connectSTBToken));
        this._panResponder = PanResponder.create({
            // 要求成为响应者:
            onStartShouldSetPanResponder: (evt, gestureState) => true,
            onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
            onMoveShouldSetPanResponder: (evt, gestureState) => true,
            onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,

            onPanResponderGrant: (evt, gestureState) => {
                // 开始手势操作。给用户一些视觉反馈,让他们知道发生了什么事情!
                // gestureState.{x,y}0 现在会被设置为0
                this.movePos = [];
                this.console("touch start===X:" + gestureState.x0 + "===Y:" + gestureState.y0);
                this.movePos.push(Math.floor(gestureState.x0), Math.floor(gestureState.y0));
            },
            onPanResponderMove: (evt, gestureState) => {
                // 最近一次的移动距离为gestureState.move{X,Y}
                // 从成为响应者开始时的累计手势移动距离为gestureState.d{x,y}
            },
            onPanResponderTerminationRequest: (evt, gestureState) => true,
            onPanResponderRelease: (evt, gestureState) => {
                // 用户放开了所有的触摸点,且此时视图已经成为了响应者。
                // 一般来说这意味着一个手势操作已经成功完成。
                this.console("touch end===moveX:" + gestureState.moveX + "===moveY:" + gestureState.moveY);
                this.movePos.push(Math.floor(gestureState.moveX), Math.floor(gestureState.moveY));
                this.moveActionEnd(this.movePos);
            },
            onPanResponderTerminate: (evt, gestureState) => {
                // 另一个组件已经成为了新的响应者,所以当前手势将被取消。
                this.console("what???");
            },
            onShouldBlockNativeResponder: (evt, gestureState) => {
                // 返回一个布尔值,决定当前组件是否应该阻止原生组件成为JS响应者
                // 默认返回true。目前暂时只支持android。
                return true;
            }
        });
    },
    actAnimationStart: function () {
        this.console("actAnimationStart");
        // 可选的基本动画类型: spring, decay, timing
        this.bounceValue.setValue(0);
        Animated.timing(
            /**
             * 将`bounceValue`值动画化的意思是,在以Animated为前缀名的组件中,比如此例中的Animated.Image,
             * 将`bounceValue`值所赋予的样式就是会跟随`bounceValue`值的变化而改变样式的,
             * `bounceValue`值的改变在Animated.timing()函数中改变,此例中`bounceValue`值将从0变化至1,变化的时间为200ms
             * 也就是说,以Animated为前缀名的组件Image(Animated.Image),将在200ms的时间内,透明度从0变化至1
             * */
            this.bounceValue,// 将`bounceValue`值动画化
            {
                toValue: 1,// 将其值以动画的形式改到一个较小值
                duration: 180,
                easing: Easing.ease
            }
        ).start(() => {
                this.actAnimationEnd()
            });
    },
    actAnimationEnd: function () {
        this.console("actAnimationEnd");
        // 可选的基本动画类型: spring, decay, timing
        this.bounceValue.setValue(1);
        Animated.timing(
            this.bounceValue,// 将`bounceValue`值动画化
            {
                toValue: 0,// 将其值以动画的形式改到一个较小值
                duration: 300,
                easing: Easing.ease
            }
        ).start();
    },
    moveActionEnd: function (movePos) {
        this.console("movePos" + JSON.stringify(movePos));
        let [sX, sY, eX, eY] = movePos;
        let x = eX - sX, y = eY - sY, direction;
        let z = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
        if ((eX == 0 && eY == 0) || z < 20) {//移动距离小于20像素视为点击
            direction = -1;
        } else {
            direction = Math.round(( ( ( Math.atan2(y, x) * ( 180 / Math.PI ) ) + 180 ) / 90) + 3) % 4;
        }
        this.console("角度:" + direction);// 点击(-1) 上(0) 右(1) 下(2) 左(3)
        switch (direction) {
            case -1:
                this.keyPressIn(6);
                break;
            case 0:
                this.keyPressIn(2);
                break;
            case 1:
                this.keyPressIn(5);
                break;
            case 2:
                this.keyPressIn(3);
                break;
            case 3:
                this.keyPressIn(4);
                break;
            default :
                break;
        }
    },
    keyPressIn: function (keyCode) {
        let _keyString = '';
        switch (keyCode) {
            case 0://POWER
                this.setState({powerState: true});
                _keyString = 'POWER';
                break;
            case 1://HOME
                this.setState({homeState: true});
                _keyString = 'HOME';
                break;
            case 2://UP
                this.setState({keyBoard: 'up'});
                this.actAnimationStart();
                _keyString = 'UP';
                break;
            case 3://DOWN
                this.setState({keyBoard: 'down'});
                this.actAnimationStart();
                _keyString = 'DOWN';
                break;
            case 4://LEFT
                this.setState({keyBoard: 'left'});
                this.actAnimationStart();
                _keyString = 'LEFT';
                break;
            case 5://RIGHT
                this.setState({keyBoard: 'right'});
                this.actAnimationStart();
                _keyString = 'RIGHT';
                break;
            case 6://CENTER
                this.setState({keyBoard: 'center'});
                this.actAnimationStart();
                _keyString = 'CENTER';
                break;
            case 7://RED
                break;
            case 8://MENU
                this.setState({menuState: true});
                _keyString = 'MENU';
                break;
            case 9://BACK
                this.setState({backState: true});
                _keyString = 'BACK';
                break;
            case 10://VOLUME_UP
                this.setState({volumeUpState: true});
                _keyString = 'VOLUME_UP';
                break;
            case 11://VOLUME_DOWN
                this.setState({volumeDownState: true});
                _keyString = 'VOLUME_DOWN';
                break;
            default:
                break;
        }
        this.console("userID:" + this.props.connectSTBToken.userId + ";stbToken:" + this.props.connectSTBToken.userToken + ";keyCode:" + keyCode+ ";keyString:" + _keyString);
        if (this.props.connectSTBToken.userId && this.props.connectSTBToken.userToken) {
            let {userId, userToken} = this.props.connectSTBToken;
            let that = this;
            Gsoap.sendRemoteControlKeyOnSTBDevice(userId, userToken, _keyString, (statusCode, statusMessage) => {
                that.console("keyPressIn===statusCode:" + statusCode + ";statusMessage:" + statusMessage);
                switch (statusCode) {
                    case 2000:
                        //success
                        break;
                    default:
                        break;
                }
            });
        }
    },
    keyBoardImg: function () {
        let keyBoardImg = ' ';
        switch (this.state.keyBoard) {
            case 'up':
                keyBoardImg = TYPES.REMOTE_TOUCH_UP;
                break;
            case 'down':
                keyBoardImg = TYPES.REMOTE_TOUCH_DOWN;
                break;
            case 'left':
                keyBoardImg = TYPES.REMOTE_TOUCH_LEFT;
                break;
            case 'right':
                keyBoardImg = TYPES.REMOTE_TOUCH_RIGHT;
                break;
            case 'center':
                keyBoardImg = TYPES.REMOTE_TOUCH_OK;
                break;
        }
        return keyBoardImg;
    },
    render: function () {
        let keyBoardImg = this.keyBoardImg();
        return (
            <View style={styles.wrap}>
                {/*顶上停止按键以及主页按键*/}
                <View style={styles.topContainer}>
                    {/*STOP*/}
                    <TouchableOpacity activeOpacity={1}
                                      onPressIn={()=>{this.keyPressIn(0)}}
                                      onPressOut={()=>{this.setState({powerState:false})}}>
                        <Image style={styles.StopHomeIcon}
                               source={{uri: this.state.powerState ? TYPES.REMOTE_STOP_FOCUS : TYPES.REMOTE_STOP}}></Image>
                    </TouchableOpacity>
                    {/*HOME*/}
                    <TouchableOpacity activeOpacity={1}
                                      onPressIn={()=>{this.keyPressIn(1)}}
                                      onPressOut={()=>{this.setState({homeState:false})}}>
                        <Image style={styles.StopHomeIcon}
                               source={{uri: this.state.homeState ? TYPES.REMOTE_HOME_FOCUS : TYPES.REMOTE_HOME}}/>
                    </TouchableOpacity>
                </View>
                {/*中间上下左右键盘,申请权限等功能键*/}
                <View style={[styles.touchContainer, {backgroundColor: '#e2eaea'}]}
                    {...this._panResponder.panHandlers}>
                    <Animated.Image
                        style={[styles.middleContainer_BG, {opacity: this.bounceValue}]}
                        source={{uri: keyBoardImg}}/>
                </View>
                {/*底下音量加减,返回菜单等功能按键*/}
                <View style={styles.bottomContainer}>
                    <View style={styles.bottomToolWrap}>
                        <TouchableOpacity style={[styles.bottomIconStyle, {marginVertical: 5}]}
                                          activeOpacity={1}
                                          onPressIn={()=>{this.keyPressIn(9)}}
                                          onPressOut={()=>{this.setState({backState:false})}}>
                            <Image style={styles.bottomIconStyle}
                                   source={{uri: this.state.backState ? TYPES.REMOTE_BACK_FOCUS : TYPES.REMOTE_BACK}}/>
                        </TouchableOpacity>
                        <TouchableOpacity style={[styles.bottomIconStyle, {marginVertical: 5}]}
                                          activeOpacity={1}
                                          onPressIn={()=>{this.keyPressIn(10)}}
                                          onPressOut={()=>{this.setState({volumeUpState:false})}}>
                            <Image style={styles.bottomIconStyle}
                                   source={{uri: this.state.volumeUpState ? TYPES.REMOTE_VOLUMEA_FOCUS : TYPES.REMOTE_VOLUMEA}}/>
                        </TouchableOpacity>
                        <TouchableOpacity style={[styles.bottomIconStyle, {marginVertical: 5}]}
                                          activeOpacity={1}
                                          onPressIn={()=>{this.keyPressIn(8)}}
                                          onPressOut={()=>{this.setState({menuState:false})}}>
                            <Image style={styles.bottomIconStyle}
                                   source={{uri: this.state.menuState ? TYPES.REMOTE_MENU_FOCUS : TYPES.REMOTE_MENU}}/>
                        </TouchableOpacity>
                    </View>
                    <TouchableOpacity style={[styles.bottomIconStyle, {marginVertical: 5}]}
                                      activeOpacity={1}
                                      onPressIn={()=>{this.keyPressIn(11)}}
                                      onPressOut={()=>{this.setState({volumeDownState:false})}}>
                        <Image style={styles.bottomIconStyle}
                               source={{uri: this.state.volumeDownState ? TYPES.REMOTE_VOLUMEP_FOCUS : TYPES.REMOTE_VOLUMEP}}/>
                    </TouchableOpacity>
                </View>
            </View>
        );
    },
    console: function (msg) {
        this.debugMsg ? console.log("+++xq debug+++touchRemote===" + msg + "===") : null;
    }
});

const styles = StyleSheet.create({
    wrap: {
        flex: 1,
        flexDirection: 'column',
        justifyContent: 'flex-start',
        alignItems: 'center',
        paddingHorizontal: Util.screenWidth / 10,
        paddingVertical: Util.screenHeight / 25,
        backgroundColor: "#eaeff0"
    },
    topContainer: {
        flexDirection: 'row',
        justifyContent: 'space-between',
        width: Util.screenWidth / 10 * 8,
        paddingHorizontal: 15
    },
    StopHomeIcon: {
        //13 : 7
        width: Util.screenWidth / 7 * 1.6,
        height: Util.screenWidth / 13 * 1.6
    },

    touchContainer: {
        width: Util.screenWidth,
        height: Util.screenWidth / 8 * 5 + Util.screenWidth / 11 * 1.2,
        paddingHorizontal: 15,
        marginTop: 15,
        marginBottom: 15,
        alignItems: 'center',
        justifyContent: 'center'
    },

    middleContainer: {
        flexDirection: 'row',
        justifyContent: 'center',
        width: Util.screenWidth / 10 * 8,
        paddingHorizontal: 15,
        marginVertical: 10
    },
    middleContainer_BG: {
        width: Util.screenWidth / 8 * 5,
        height: Util.screenWidth / 8 * 5,
        flexDirection: 'column',
        justifyContent: 'flex-start',
        alignItems: 'center'
    },
    upIcon: {
        flex: 1,
        width: Util.screenWidth / 8 * 5 / 4 * 1.5
    },
    middleToolWrap: {
        flex: 1,
        flexDirection: 'row'
    },
    middleTool: {
        flex: 1
    },
    dowIcon: {
        flex: 1,
        width: Util.screenWidth / 8 * 5 / 4 * 1.5
    },

    bottomContainer: {
        width: Util.screenWidth / 8 * 5,
        height: Util.screenWidth / 8 * 3.5,
        flexDirection: 'column',
        justifyContent: 'flex-start',
        alignItems: 'center'
    },
    bottomIconStyle: {
        //11 : 7
        width: Util.screenWidth / 7 * 1.2,
        height: Util.screenWidth / 11 * 1.2
    },
    bottomToolWrap: {
        width: Util.screenWidth / 8 * 5,
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'space-between'
    }
});

module.exports = TouchRemote;


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值