【问题标题】:How to slide card when click on button in React Native?在 React Native 中单击按钮时如何滑动卡片?
【发布时间】:2021-01-18 10:41:21
【问题描述】:

我正在创建一个反应原生应用程序,我需要通过单击按钮创建一个卡片滑块。单击按钮时需要滑动到卡片图像,并且当滑动卡片时需要更改按钮颜色以正确的颜色。以下屏幕显示了我需要的内容,

我可以设计如下画面,现在我需要知道如何在点击按钮时进行滑动操作,以及如何在滑动卡片时更改按钮颜色。 这就是我所做的,

我的代码示例

import React, {Component} from 'react';
import {
  View,
  Text,
  TouchableOpacity,
  TextInput,
  Platform,
  StyleSheet,
  StatusBar,
  Alert,
  Image,
  ScrollView,
  Animated,
  Dimensions,
  Modal,
} from 'react-native';
import * as Animatable from 'react-native-animatable';


const {width, height} = Dimensions.get('window');
const CARD_HEIGHT = 260;
const CARD_WIDTH = width * 0.8;
const SPACING_FOR_CARD_INSET = width * 0.1 - 10;

class TestSlider extends Component {

      return (
        <View style={styles.container}>
          <StatusBar backgroundColor="#750056" barStyle="light-content" />
          <View style={styles.header}>
            <Text style={styles.text_header}>Select Your Travel method !</Text>
          </View>
          <Animatable.View animation="fadeInUpBig" style={[styles.footer]}>
            <View style={styles.CardDetail}>
        
                <TouchableOpacity style={styles.CardDetail1} onPress={() => {this.scroll.scrollTo({ x: 0 }); this.SetColor();}}>
                <View style={styles.detailContent}>
                  <Text style={styles.title}>Car</Text>
                </View>
                </TouchableOpacity>
                  
              <TouchableOpacity style={styles.CardDetail1} onPress={() => this.scroll.scrollTo({ x: CARD_WIDTH }) }>
                <View style={styles.detailContent}>
                  <Text style={styles.title}>Bus</Text>
                </View>
                </TouchableOpacity>
              <TouchableOpacity style={styles.CardDetail1} onPress={() => this.scroll.scrollTo({ x: CARD_WIDTH *2 })}>
                <View style={styles.detailContent}>
                  <Text style={styles.title}>Train</Text>
                </View>
                </TouchableOpacity>
            </View>

            <Animated.ScrollView
              ref={(node) => this.scroll = node}
              horizontal
              scrollEventThrottle={1}
              showsHorizontalScrollIndicator={false}
              style={styles.scrollView}
              pagingEnabled
              snapToInterval={CARD_WIDTH + 20}
              snapToAlignment="center">
              <View style={styles.card}>
                <Image
                  source={require('../assets/car.png')}
                  style={styles.cardImage}
                  resizeMode="contain"
                />
                <View style={styles.button}>
                  <TouchableOpacity
                    onPress={() => {
                      this.setModalVisible(true);
                    }}
                    style={[
                      styles.selectNow,
                      {
                        borderColor: '#009387',
                        borderWidth: 1,
                      },
                    ]}>
                    <Text
                      style={[
                        styles.textSelect,
                        {
                          color: '#009387',
                        },
                      ]}>
                      Select Now
                    </Text>
                  </TouchableOpacity>
                </View>
              </View>
              <View style={styles.card}>
                <Image
                  source={require('../assets/bus.jpg')}
                  style={styles.cardImage}
                  resizeMode="stretch"
                />
                <View style={styles.button}>
                  <TouchableOpacity
                    onPress={() => {}}
                    style={[
                      styles.selectNow,
                      {
                        borderColor: '#009387',
                        borderWidth: 1,
                      },
                    ]}>
                    <Text
                      style={[
                        styles.textSelect,
                        {
                          color: '#009387',
                        },
                      ]}>
                      Select Now
                    </Text>
                  </TouchableOpacity>
                </View>
              </View>
              <View style={styles.card}>
                <Image
                  source={require('../assets/train.png')}
                  style={styles.cardImage}
                  resizeMode="stretch"
                />
                <View style={styles.button}>
                  <TouchableOpacity
                    onPress={() => {}}
                    style={[
                      styles.selectNow,
                      {
                        borderColor: '#009387',
                        borderWidth: 1,
                      },
                    ]}>
                    <Text
                      style={[
                        styles.textSelect,
                        {
                          color: '#009387',
                        },
                      ]}>
                      Select Now
                    </Text>
                  </TouchableOpacity>
                </View>
              </View>
            </Animated.ScrollView>
          </Animatable.View>
        </View>
      );
    }
  
}

export default TestSlider;

const styles = StyleSheet.create({
  container1: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  container: {
    flex: 1,
    backgroundColor: '#750056',
  },
  cardContainer: {
    backgroundColor: '#fff',
    marginTop: 60,
  },
  header: {
    flex: 1,
    justifyContent: 'flex-end',
    paddingHorizontal: 20,
    paddingBottom: 30,
  },
  text_header: {
    color: '#fff',
    fontWeight: 'bold',
    fontSize: 28,
  },
  footer: {
    flex: 1,
    backgroundColor: '#fff',
    borderTopLeftRadius: 30,
    borderTopRightRadius: 30,
    paddingHorizontal: 20,
    paddingVertical: 30,
  },
  scrollView: {
    // position: "absolute",
    top: 60,
    // bottom: 0,
    left: 0,
    right: 0,
    paddingVertical: 10,
  },
  card: {
    // padding: 10,
    elevation: 3,
    backgroundColor: '#FFF',
    borderTopLeftRadius: 10,
    borderBottomRightRadius: 10,
    marginHorizontal: 10,
    shadowColor: '#000',
    shadowRadius: 15,
    shadowOpacity: 0.3,
    shadowOffset: {x: 2, y: -2},
    height: CARD_HEIGHT,
    width: CARD_WIDTH,
    overflow: 'hidden',
  },
  cardImage: {
    flex: 3,
    width: '100%',
    height: '100%',
    alignSelf: 'center',
  },
  button: {
    alignItems: 'center',
    marginTop: 5,
    marginBottom: 5,
  },
  selectNow: {
    width: '80%',
    padding: 5,
    justifyContent: 'center',
    alignItems: 'center',
    borderRadius: 3,
  },
  textSelect: {
    fontSize: 16,
    fontWeight: 'bold',
  },
  CardDetail: {
    alignSelf: 'center',
    marginTop: 20,
    alignItems: 'center',
    flexDirection: 'row',
    position: 'absolute',
    // backgroundColor: "#009387",
  },
  CardDetail1: {
    // alignSelf: 'center',
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#009387',
    borderRadius: 20,
    marginHorizontal: 5,
    width: '30%',
  },
  detailContent: {
    margin: 10,
    alignItems: 'center',
  },
  title:{
    fontSize:14,
    color: "#fff"
  },
});

这是我的设计界面

在我的代码滑动中工作正常。现在我需要在单击它并滚动到右侧卡片时更改按钮颜色。滑动卡片时,它应该改变右边的按钮颜色。请帮我解决这个问题。

【问题讨论】:

    标签: react-native react-native-android react-native-scrollview


    【解决方案1】:

    这是我的示例:

    import React, { Component, useRef, useState } from 'react';
    import {
      View,
      Text,
      TouchableOpacity,
      TextInput,
      Platform,
      StyleSheet,
      StatusBar,
      Alert,
      Image,
      ScrollView,
      Animated,
      Dimensions,
      Modal,
    
    } from 'react-native';
    import * as Animatable from 'react-native-animatable';
    
    const { width, height } = Dimensions.get('window');
    const CARD_HEIGHT = 260;
    const CARD_WIDTH = width * 0.8;
    const SPACING_FOR_CARD_INSET = width * 0.1 - 10;
    
    const App: () => React$Node = () => {
      const refScrollview = useRef(ScrollView)
      let y = 0;
      let animated = true;
      const [isCar, setIsCar] = useState(true);
      const [isBus, setIsBus] = useState(false);
      const [isTrain, setIsTrain] = useState(false);
    
      const handleScroll = (event: Object) => {
        if (event.nativeEvent.contentOffset.x < 350) {
          setIsCar(true);
          setIsBus(false);
          setIsTrain(false);
        } else if (event.nativeEvent.contentOffset.x >= 350 && event.nativeEvent.contentOffset.x < 600) {
          setIsCar(false);
          setIsBus(true);
          setIsTrain(false);
        } else if (event.nativeEvent.contentOffset.x >= 600) {
          setIsCar(false);
          setIsBus(false);
          setIsTrain(true);
        }
      }
    
      return (
        <View style={styles.container}>
          <StatusBar backgroundColor="#750056" barStyle="light-content" />
          <View style={styles.header}>
            <Text style={styles.text_header}>Select Your Travel method !</Text>
          </View>
          <Animatable.View animation="fadeInUpBig" style={[styles.footer]}>
            <View style={styles.CardDetail}>
    
              <TouchableOpacity style={[styles.CardDetail1, { backgroundColor: isCar ? '#750056' : '#009387' }]} onPress={() => {
                refScrollview.current.scrollTo({ x: 0, y, animated });
                setIsCar(true);
                setIsBus(false);
                setIsTrain(false);
              }}>
                <View style={styles.detailContent}>
                  <Text style={styles.title}>Car</Text>
                </View>
              </TouchableOpacity>
    
              <TouchableOpacity style={[styles.CardDetail1, { backgroundColor: isBus ? '#750056' : '#009387' }]} onPress={() => {
                refScrollview.current.scrollTo({ x: 350, y, animated }); setIsCar(false);
                setIsBus(true);
                setIsTrain(false);
              }}>
                <View style={styles.detailContent}>
                  <Text style={styles.title}>Bus</Text>
                </View>
              </TouchableOpacity>
              <TouchableOpacity style={[styles.CardDetail1, { backgroundColor: isTrain ? '#750056' : '#009387' }]} onPress={() => {
                refScrollview.current.scrollTo({ x: 600, y, animated });
                setIsCar(false);
                setIsBus(false);
                setIsTrain(true);
              }}>
                <View style={styles.detailContent}>
                  <Text style={styles.title}>Train</Text>
                </View>
              </TouchableOpacity>
            </View>
    
            <Animated.ScrollView
              ref={refScrollview}
              horizontal
              scrollEventThrottle={1}
              showsHorizontalScrollIndicator={false}
              style={styles.scrollView}
              pagingEnabled
              snapToInterval={CARD_WIDTH + 20}
              snapToAlignment="center"
              onScroll={handleScroll}>
              <View style={styles.card}>
                <Image
                  source={require('./assets/bus.jpg')}
                  style={styles.cardImage}
                  resizeMode="contain"
                />
                <View style={styles.button}>
                  <TouchableOpacity
                    onPress={() => {
                      this.setModalVisible(true);
                    }}
                    style={[
                      styles.selectNow,
                      {
                        borderColor: '#009387',
                        borderWidth: 1,
                      },
                    ]}>
                    <Text
                      style={[
                        styles.textSelect,
                        {
                          color: '#009387',
                        },
                      ]}>
                      Select Now
                        </Text>
                  </TouchableOpacity>
                </View>
              </View>
              <View style={styles.card}>
                <Image
                  source={require('./assets/bus.jpg')}
                  style={styles.cardImage}
                  resizeMode="stretch"
                />
                <View style={styles.button}>
                  <TouchableOpacity
                    onPress={() => { }}
                    style={[
                      styles.selectNow,
                      {
                        borderColor: '#009387',
                        borderWidth: 1,
                      },
                    ]}>
                    <Text
                      style={[
                        styles.textSelect,
                        {
                          color: '#009387',
                        },
                      ]}>
                      Select Now
                        </Text>
                  </TouchableOpacity>
                </View>
              </View>
              <View style={styles.card}>
                <Image
                  source={require('./assets/bus.jpg')}
                  style={styles.cardImage}
                  resizeMode="stretch"
                />
                <View style={styles.button}>
                  <TouchableOpacity
                    onPress={() => { }}
                    style={[
                      styles.selectNow,
                      {
                        borderColor: '#009387',
                        borderWidth: 1,
                      },
                    ]}>
                    <Text
                      style={[
                        styles.textSelect,
                        {
                          color: '#009387',
                        },
                      ]}>
                      Select Now
                        </Text>
                  </TouchableOpacity>
                </View>
              </View>
            </Animated.ScrollView>
          </Animatable.View>
        </View>
      );
    };
    
    const styles = StyleSheet.create({
      container1: {
        flex: 1,
        backgroundColor: '#fff',
        alignItems: 'center',
        justifyContent: 'center',
      },
      container: {
        flex: 1,
        backgroundColor: '#750056',
      },
      cardContainer: {
        backgroundColor: '#fff',
        marginTop: 60,
      },
      header: {
        flex: 1,
        justifyContent: 'flex-end',
        paddingHorizontal: 20,
        paddingBottom: 30,
      },
      text_header: {
        color: '#fff',
        fontWeight: 'bold',
        fontSize: 28,
      },
      footer: {
        flex: 1,
        backgroundColor: '#fff',
        borderTopLeftRadius: 30,
        borderTopRightRadius: 30,
        paddingHorizontal: 20,
        paddingVertical: 30,
      },
      scrollView: {
        // position: "absolute",
        top: 60,
        // bottom: 0,
        left: 0,
        right: 0,
        paddingVertical: 10,
      },
      card: {
        // padding: 10,
        elevation: 3,
        backgroundColor: '#FFF',
        borderTopLeftRadius: 10,
        borderBottomRightRadius: 10,
        marginHorizontal: 10,
        shadowColor: '#000',
        shadowRadius: 15,
        shadowOpacity: 0.3,
        shadowOffset: { x: 2, y: -2 },
        height: CARD_HEIGHT,
        width: CARD_WIDTH,
        overflow: 'hidden',
      },
      cardImage: {
        flex: 3,
        width: '100%',
        height: '100%',
        alignSelf: 'center',
      },
      button: {
        alignItems: 'center',
        marginTop: 5,
        marginBottom: 5,
      },
      selectNow: {
        width: '80%',
        padding: 5,
        justifyContent: 'center',
        alignItems: 'center',
        borderRadius: 3,
      },
      textSelect: {
        fontSize: 16,
        fontWeight: 'bold',
      },
      CardDetail: {
        alignSelf: 'center',
        marginTop: 20,
        alignItems: 'center',
        flexDirection: 'row',
        position: 'absolute',
        // backgroundColor: "#009387",
      },
      CardDetail1: {
        // alignSelf: 'center',
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#009387',
        borderRadius: 20,
        marginHorizontal: 5,
        width: '30%',
      },
      detailContent: {
        margin: 10,
        alignItems: 'center',
      },
      title: {
        fontSize: 14,
        color: "#fff"
      },
    });
    
    export default App;
    
    

    【讨论】:

    • 这工作正常。非常感谢您的帮助。
    • 你有什么教程可以让我学习成为 React Native 的高手吗?请帮我学习 React Native。
    【解决方案2】:

    让我们参考react-native-swiper,希望这会有所帮助。 details here

    【讨论】:

    • 感谢您的帮助。我没有使用 react-native-swiper,我只是用 ScrollView 制作了一个滑块。有没有办法用我的代码做这些事情?
    • 我使用功能组件,我创建const refScrollview = useRef(ScrollView) 然后我在Animated.ScrollView 中定义ref={refScrollview} 并按下按钮让添加功能:onPress={() =&gt; {refScrollview.current.scrollTo({ x, y, animated })}},您可以将 x 更改为水平滚动,动画 =真和 y = 0
    • 我用 this.scroll.scrollTo({ x: CARD_WIDTH }) }> 这个代码行导航到卡片和它工作正常。我还需要更改按钮颜色。
    • 让我们将onScroll={handleScroll} 与handerScroll 一起使用:const handleScroll = (event: Object) =&gt; { console.log('x',event.nativeEvent.contentOffset.x); } 检查event.nativeEvent.contentOffset.x 来配置按钮的颜色
    • 在这里我编辑了我的代码示例。现在,当单击按钮时,它会导航到正确的卡片。现在我需要在单击按钮并滚动卡片时更改颜色。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-31
    • 1970-01-01
    • 2021-11-13
    • 1970-01-01
    • 1970-01-01
    • 2018-08-25
    相关资源
    最近更新 更多