0

I'm creating a react native app and I need to create a card slider with a button click. When click on the button need to slide to the card image and also when slide the card need to change the button color in order to the correct one. The below screens shows what I need,

Screen1

Screen2

I am able to design the following screen and now I need to know how to do sliding things when clicking on the button and how to change button color when sliding the card. This is what I did,

My code samples

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

This is my design UI

Screen3

In my code sliding things working fine. Now I need to change the button color when clicking on it and scroll into the right card. And when sliding the card it should change the right button color. Please help me to solve this problem.

Sidath
  • 379
  • 1
  • 9
  • 25

2 Answers2

2

let's refer react-native-swiper, hope this helps. details here

Jals
  • 280
  • 1
  • 15
  • Thank you for your help. I'm not using react-native-swiper, I just make a slider with ScrollView. Are there any way to do these things with my code? – Sidath Jan 18 '21 at 10:53
  • 2
    i use function component, i create ```const refScrollview = useRef(ScrollView)``` then i define ```ref={refScrollview}``` in ```Animated.ScrollView``` and on button press let add function : ```onPress={() => {refScrollview.current.scrollTo({ x, y, animated })}}```, you can change x to horizontal scroll, animated = true and y = 0 – Jals Jan 18 '21 at 11:17
  • I used this.scroll.scrollTo({ x: CARD_WIDTH }) }> this code line to navigate to the card and it is working fine. I need to change the button color also. – Sidath Jan 18 '21 at 11:22
  • 1
    let's use ```onScroll={handleScroll}``` with handerScroll : ```const handleScroll = (event: Object) => { console.log('x',event.nativeEvent.contentOffset.x); }``` check ```event.nativeEvent.contentOffset.x``` to config color of button – Jals Jan 18 '21 at 11:30
  • Here I edited my code samples. Now it navigates to the right card when clicking on the button. Now I need to change the color when clicking on the button and scrolling the cards. – Sidath Jan 18 '21 at 11:36
  • Thank you so much. It is working fine. can I have your email to contact you if have any question with react native? – Sidath Jan 18 '21 at 11:49
2

here is my sample :

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;

Jals
  • 280
  • 1
  • 15