React Native Flip Card 不支持翻转

Posted

技术标签:

【中文标题】React Native Flip Card 不支持翻转【英文标题】:React Native Flip Card not Working on flip 【发布时间】:2021-10-31 03:35:12 【问题描述】:

我正在尝试制作翻转纸牌游戏。我使用 GestureFlipView 进行翻转卡片动画。我想在 3X3 网格中显示这些翻转卡,为此我使用了 react native。但是问题是卡片没有被翻转,并且它也表现出模糊的行为。只有最后一张卡工作正常,其他卡的行为不可预测。

Github 仓库:https://github.com/akhilomar/React-Native-Number-Game

卡屏:https://i.stack.imgur.com/Cliww.png

卡片组件

import View, Text, SafeAreaView, TouchableOpacity from 'react-native';
import GestureFlipView from 'react-native-gesture-flip-card';

const Cards = (props) => 

    const [flipType, setFlip] = useState('left');

    useEffect(() => 

    )


    const renderFront = () => 
        return(
            <TouchableOpacity onPress = () => 
                this.flipView.flipRight() 
                setFlip('right');
                console.log("Pressed" + `$props.val`)
        
         >
            <View style = backgroundColor:'red', width: 100, height: 100, alignItems: 'center', justifyContent: 'center'>
                <Text style = color: "white", fontSize: 20>Swipe Me</Text>
                

            </View>
            </TouchableOpacity>
        );
    ;

    const renderBack = () => 
        return(
        <View style = backgroundColor:'blue', width: 100, height: 100, alignItems: 'center', justifyContent: 'center'>
            <Text style = color: "white", fontSize: 30>props.val</Text>
            /* <TouchableOpacity onPress = () => 
                (flipType === 'left') ? this.flipView.flipRight() : this.flipView.flipLeft();
                setFlip((flipType === 'left') ? 'right' : 'left');
        
          style = padding: 10, backgroundColor: 'purple', width: 100, height: 40, alignItems: 'center', justifyContent: 'center'>
                <Text style = color: 'white'>Reverse</Text>
            </TouchableOpacity> */

        </View>
        );
    ;
    //ref = (ref) => this.flipView = ref

    return(
        <SafeAreaView style = flex: 1, alignItems: 'center', justifyContent: 'center'>
            <GestureFlipView ref = (ref) => this.flipView = ref  width=300 height = 500>
                renderFront()
                renderBack()
            </GestureFlipView>
        </SafeAreaView>
    );


export default Cards;```

**Card List Component**

```import React from 'react';
import SafeAreaView, View, FlatList, Dimensions, StyleSheet  from 'react-native';
import Cards from './Cards';

const CardScreen = () => 

    // const data = ['1','2','3','4','5','6','7','8','9'];

    const DATA = [
      
        id: '1',
        title: '1',
      ,
      
        id: '2',
        title: '2',
      ,
      
        id: '3',
        title: '3',
      ,
      
        id: '4',
        title: '4',
      ,
      
        id: '5',
        title: '5',
      ,
      
        id: '6',
        title: '6',
      ,
      
        id: '7',
        title: '7',
      ,
      
        id: '8',
        title: '8',
      ,
      
        id: '9',
        title: '9',
      
      
    ];

      const Shuffle = (arr1) => 
        var ctr = arr1.length, temp, index;
        while (ctr > 0) 
            index = Math.floor(Math.random() * ctr);
            ctr--;
            temp = arr1[ctr];
            arr1[ctr] = arr1[index];
            arr1[index] = temp;
        
        return arr1;
      

      const numColumns = 3;
      const size = Dimensions.get('window').width/numColumns;
      const styles = StyleSheet.create(
        itemContainer: 
          width: size,
          height: size,
        ,
        item: 
          flex: 1,
          margin: 3,
          backgroundColor: 'lightblue',
        
      );
    
    return(
      <>
        <FlatList
            data=DATA
            renderItem=( item ) => (
                <View style=styles.itemContainer>
                    <Cards val = item.value/>
                </View>
            )
            keyExtractor=item => item.id
            numColumns=numColumns />

          /* 
            data.map((index, item) => 
              return(
              
              <View style=styles.itemContainer>
                    <Cards val = item/>
              </View>
              );
            )
           */
      </>
    );


export default CardScreen;```

【问题讨论】:

【参考方案1】:

您需要正确使用ref。你可以阅读它here

const Cards = (props) => 
  //first define ref
  const flipViewRef = React.useRef();


  //in onPress use it like this
  <TouchableOpacity onPress = () => 
        flipViewRef.current.flipRight() 
        ...     
  >

  //in GestureFlipView assign it like this
  <GestureFlipView ref=flipViewRef />
  




【讨论】:

【参考方案2】:

您遇到问题的主要原因是您在功能组件中使用了this 引用。正如here 所解释的,this 的值将取决于函数的调用方式,甚至可能是undefined。使用this 的更可靠方法来自class context。对于 React,这意味着使用类组件,而不是功能组件,这就是这里使用的。你可以阅读函数和类组件here。

需要考虑的其他一点是FlatList 是否适合此处。通常,此组件用于improve performance 以呈现大型列表。我建议不要使用FlatList,而是使用更简单的东西,例如一组View 组件来抽牌。这是基于您的代码的完整示例:

import React,  useState  from 'react';
import  View, Dimensions, StyleSheet, Text, TouchableOpacity  from 'react-native';
import GestureFlipView from 'react-native-gesture-flip-card';

const Card = (props: any) => 

  const [flipType, setFlip] = useState('left');

  let flipView: any;
  const onFrontPress = () => 
    flipView.flipRight()
    setFlip('right');
  
  const cardDimensions =  width: 0.9 * props.size, height: 0.9 * props.size ;

  const renderFront = () => 
    return (
      <TouchableOpacity onPress=onFrontPress style=[styles.front, cardDimensions]>
        <Text style=styles.frontText>Swipe Me</Text>
      </TouchableOpacity>
    );
  ;

  const renderBack = () => 
    return (
      <View style=[styles.back, cardDimensions]>
        <Text style=styles.backText>props.val</Text>
      </View>
    );
  ;

  return (
    <GestureFlipView ref=(ref) => flipView = ref width=props.size     height=props.size>
      renderFront()
      renderBack()
    </GestureFlipView>
  );


const CardRow = () => 
  const size = Dimensions.get('window').width / 3;
  return (
    <View style=styles.rowContainer>
      <Card size=size />
      <Card size=size / width: 0.9 * props.size, height: 0.9 * props.size >
      <Card size=size />
    </View>
  );


const CardScreen = () => 
  return (
    <View style=styles.container>
      <CardRow />
      <CardRow />
      <CardRow />
    </View>
  );


const styles = StyleSheet.create(
  container: 
    flexDirection: 'column',
    flex: 1,
  ,
  rowContainer: 
    flexDirection: 'row',
    justifyContent: 'space-evenly',
  ,
  back: 
    backgroundColor: 'blue',
    alignItems: 'center',
    justifyContent: 'center'
  ,
  backText: 
    color: "white",
    fontSize: 30
  ,
  front: 
    backgroundColor: 'green',
    alignItems: 'center',
    justifyContent: 'center',
  ,
  frontText: 
    color: "white",
    fontSize: 20
  

);

export default CardScreen;

【讨论】:

以上是关于React Native Flip Card 不支持翻转的主要内容,如果未能解决你的问题,请参考以下文章

[OpenJudge 3061]Flip The Card

React Native:图像 URI 不适用于发布 apk

Flip-Card CSS/HTML:翻转时卡片背面不显示

带有默认样式表的动态内联样式 React Native

无法在 React Native Paper 中更改卡片标题文本的颜色

我如何在 React-Native 中使用 agora 视频通话共享手机屏幕