首页 > 解决方案 > React Native onFocus 和 onBlur TouchableOpacity

问题描述

我正在使用 react natives Touchable Opacity 为我悬停的框设置动画/效果。我正在为安卓电视开发一个应用程序。我想制作类似于默认的 android 电视主屏幕的悬停效果(导航时,聚焦时,卡片会放大,而模糊时卡片会变小)。我也在使用 map 来迭代许多项目。这是我到目前为止所得到的。


import React, { Component } from 'react';
import { StyleSheet, View, TouchableOpacity } from 'react-native';

export default class TV extends Component {

    constructor(props) {
        super(props);
        this.state = {
            bgColor: 'gray',
            entries: [
                {
                    "albumId": 1,
                    "id": 1,
                    "title": "accusamus beatae ad facilis cum similique qui sunt",
                    "url": "https://via.placeholder.com/600/92c952",
                    "thumbnailUrl": "https://via.placeholder.com/150/92c952"
                },
                {
                    "albumId": 1,
                    "id": 2,
                    "title": "reprehenderit est deserunt velit ipsam",
                    "url": "https://via.placeholder.com/600/771796",
                    "thumbnailUrl": "https://via.placeholder.com/150/771796"
                }]
        }
    }


        render () {
        return (
            <View style={styles.thumbnailContainer}>
                {
                    this.state.entries.map((e, index) => {
                        return(

                                <TouchableOpacity onPress={()=>null} onFocus={()=>this.setState({bgColor: 'red'})} onBlur={()=>this.setState({bgColor: 'gray'})}>
                                    <View style={styles.thumbnailWrapper}></View>
                                </TouchableOpacity>

                            )
                    })
                }
            </View>
        );
    }
}

const styles = StyleSheet.create({
    thumbnailContainer: {
      flex: 1,
      flexDirection:'row',
      flexWrap:'wrap'
    },
    thumbnailWrapper: {
        backgroundColor: 'gray',
        width: 50,
        height: 50
    }
})

我目前仅使用背景颜色进行测试。不知道如何让样式背景颜色发生变化。undefined is not an object (evaluating this.state)如果我这样做,它会给我一个backgroundColor: this.state.bgColor

那么我如何才能为“卡片”设置动画,或者在这种情况下,在聚焦和模糊时只是简单的视图。

编辑:

解决了这个问题。希望有人觉得这很有用。我不确定这是否是正确的方法。但我刚刚创建了一个存储当前悬停索引的状态。如果映射索引的当前索引相同,则背景颜色应为红色。这是完整的代码:


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

export default class TV extends Component {

    constructor(props) {
        super(props);
        this.state = {
            bgColor: 'red',
            index: 0,
            entries: [
                {
                    "albumId": 1,
                    "id": 1,
                    "title": "accusamus beatae ad facilis cum similique qui sunt",
                    "url": "https://via.placeholder.com/600/92c952",
                    "thumbnailUrl": "https://via.placeholder.com/150/92c952"
                },
                {
                    "albumId": 1,
                    "id": 2,
                    "title": "reprehenderit est deserunt velit ipsam",
                    "url": "https://via.placeholder.com/600/771796",
                    "thumbnailUrl": "https://via.placeholder.com/150/771796"
                }]
        }
    }

    render() {
        return (
            <View style={styles.thumbnailContainer}>
                {
                    this.state.entries.map((e, index) => {
                        return (
                            <TouchableOpacity
                                key={e.id}
                                onFocus={() => this.setState({ bgColor: 'red', index: index })}
                                onBlur={() => this.setState({ bgColor: 'gray' })}
                            >
                                <Text style={[styles.thumbnailWrapper, this.state.index == index ? { backgroundColor: this.state.bgColor } : { backgroundColor: 'gray' }]}>{e.title}</Text>
                            </TouchableOpacity>

                        )
                    })
                }
            </View>
        );
    }
}

const styles = StyleSheet.create({
    thumbnailContainer: {
        flex: 1,
        alignContent: 'center',
        justifyContent: 'center'
    },
    thumbnailWrapper: {
        width: 350,
        height: 50
    }
})


标签: androidreact-native

解决方案


您正在尝试将状态传递给主类之外的背景颜色,请注意 const styles = StyleSheet.create()export default class TV extends Component{}状态之外只能在类内部传递

尝试这个:

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

export default class TV extends Component {

  constructor(props) {
    super(props);
    this.state = {
      bgColor: 'gray',
      entries: [
        {
          "albumId": 1,
          "id": 1,
          "title": "accusamus beatae ad facilis cum similique qui sunt",
          "url": "https://via.placeholder.com/600/92c952",
          "thumbnailUrl": "https://via.placeholder.com/150/92c952"
        },
        {
          "albumId": 1,
          "id": 2,
          "title": "reprehenderit est deserunt velit ipsam",
          "url": "https://via.placeholder.com/600/771796",
          "thumbnailUrl": "https://via.placeholder.com/150/771796"
        }]
    }
  }

  render() {
    return (
      <View style={[styles.thumbnailContainer, { backgroundColor: this.state.bgColor }]}>
        {
          this.state.entries.map((e, index) => {
            return (
              <TouchableOpacity
                key={e.id}
                onFocus={() => this.setState({ bgColor: 'red' })}
                onBlur={() => this.setState({ bgColor: 'gray' })}
              >
                <Text style={styles.thumbnailWrapper}>{e.title}</Text>
              </TouchableOpacity>

            )
          })
        }
      </View>
    );
  }
}

const styles = StyleSheet.create({
  thumbnailContainer: {
    flex: 1,
    alignContent: 'center',
    justifyContent: 'center'
  },
  thumbnailWrapper: {
    width: 350,
    height: 50
  }
})

这应该可以解决您未定义的错误


推荐阅读