React Native点击按钮时如何滑动卡片?

How to slide card when click on button in React Native?

我正在创建一个 React 本机应用程序,我需要通过单击按钮创建一个卡片滑块。单击按钮时需要滑动到卡片图像,滑动卡片时需要更改按钮颜色才能正确。下面的屏幕显示了我所需要的,

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

我的代码示例

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"
  },
});

这是我的设计UI

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

让我们参考一下 react-native-swiper,希望对您有所帮助。 details here

这是我的样本:

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;