Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Created this Flatlist-slider using React Hooks and is working #27

Open
wavydeer opened this issue Feb 11, 2023 · 0 comments
Open

Created this Flatlist-slider using React Hooks and is working #27

wavydeer opened this issue Feb 11, 2023 · 0 comments

Comments

@wavydeer
Copy link


import {

 UIManager,

 Platform,

 Dimensions,

 View,

 FlatList,

 ImageBackground,

 Pressable,

} from  "react-native";

import { Title } from  "react-native-paper";

import  styles  from  "./styles";

import { LinearGradient } from  "expo-linear-gradient";

import { LOG } from  "../../logging/config";

var  logger = LOG.extend("OBJECT");

const  ImageSlider = ({ sliderData, imageKey, titleKey, colorKey }) => {

 const [index, setIndex] = useState(0);

 const [data, setData] = useState(sliderData);

 const [activeImage, setActiveImage] = useState(0);

 const  slider = useRef();

 const  timer = 4000; // Set scroll time

 const  itemHeight = 165;

 const  itemWidth = Dimensions.get("window").width;

 const  separatorWidth = 0;

 const  totalItemWidth = itemWidth + separatorWidth;

 var  currentIndexCallback = null;

 var  sliderTimer = null;

 if (Platform.OS === "android") {

 UIManager.setLayoutAnimationEnabledExperimental(true);

  }

 useEffect(() => {

 setData(sliderData);

 if (sliderData.toString() !== data.toString()) {

 setData(sliderData);

 logger.info("useEffect|data length=", data.length);

    }

 startAutoPlay();

 return () => {

 stopAutoPlay();

    };

  }, [index, data, activeImage]);

 const  onViewableItemsChanged = useCallback((viewableItems, changed) => {

 logger.info("onViewableItemsChanged|Entry");

 logger.info("onViewableItemsChanged|viewableItems=" + viewableItems);

 if (viewableItems) {

 let  currentIndex = viewableItems["changed"][0].index;

 logger.info("onViewableItemsChanged|currentIndex=" + currentIndex);

 logger.info("onViewableItemsChanged|temp=" + data.length);

 if (currentIndex === sliderData.length - 1) {

 logger.info("onViewableItemsChanged|End of loop");

 setIndex(0);

 setActiveImage(currentIndex);

} else {

 setActiveImage(currentIndex);

      }

 if (currentIndexCallback) {

 currentIndexCallback(currentIndex);

      }

    }

 logger.info("onViewableItemsChanged|Exit");

  }, []);

 const  viewabilityConfig = {

 viewAreaCoveragePercentThreshold:  50,

  };

 const  viewabilityConfigCallbackPairs = useRef([

{ viewabilityConfig, onViewableItemsChanged },

  ]);

 const  changeSliderListIndex = () => {

 logger.info("changeSliderListIndex|Entry");

 //LayoutAnimation.configureNext(LayoutAnimation.Presets.easeIn); //Not working

 logger.info("changeSliderListIndex|index=" + index);

 if (slider != null) {

 setIndex(index + 1);

 slider.current.scrollToIndex({

 index:  index,

 animated:  true,

      });

 logger.info("changeSliderListIndex|Slider Scrolled");

    }

 logger.info("changeSliderListIndex|Exit");

  };

 const  startAutoPlay = () => {

 logger.info("startAutoPlay|Entry");

 sliderTimer = setInterval(() =>  changeSliderListIndex(), timer);

 logger.info("startAutoPlay|Exit");

  };

 const  stopAutoPlay = () => {

 logger.info("stopAutoPlay|Entry");

 if (sliderTimer) {

 logger.info("stopAutoPlay|sliderTimer=True");

 clearInterval(sliderTimer);

 sliderTimer = null;

    }

 logger.info("stopAutoPlay|Exit");

  };

 return (

 <View

 style={{

 width:  itemWidth,

 height:  165,

 zIndex: -1,

 resizeMode:  "cover",

      }}

 >

 <FlatList

 ref={slider}

 horizontal

 pagingEnabled={true}

 snapToInterval={totalItemWidth}

 decelerationRate="fast"

 bounces={false}

 contentContainerStyle={styles.contentContainerStyle}

 data={data}

 showsHorizontalScrollIndicator={false}

 renderItem={({ item, i }) => (

 <ChildItem

 width={itemWidth}

 item={item}

 colorKey={colorKey}

 titleKey={titleKey}

 imageKey={imageKey}

 onPress={() =>  logger.info(item + "pressed")}

 index={index % sliderData.length}

 active={i === index}

 local={false}

 height={itemHeight}

 />

        )}

 ItemSeparatorComponent={() => (

 <View  style={{ width:  separatorWidth }}  />

        )}

 keyExtractor={(item, index) =>  item.toString() + index}

 viewabilityConfigCallbackPairs={viewabilityConfigCallbackPairs.current}

 viewabilityConfig={viewabilityConfig}

 getItemLayout={(data, index) => ({

 length:  totalItemWidth,

 offset:  totalItemWidth * index,

 index,

        })}

 windowSize={1}

 initialNumToRender={1}

 maxToRenderPerBatch={1}

 removeClippedSubviews={true}

 />

 <View  style={styles.circlesContainer}>

 {data.map((i, k) => (

 <View

 key={k}

 style={k == activeImage ? styles.circleActive : styles.circle}

 />

        ))}

 </View>

 </View>

  );

};

const  ChildItem = ({

 item,

 width,

 onPress,

 index,

 colorKey,

 titleKey,

 imageKey,

 local,

 height,

}) => {

 return (

 <Pressable  onPress={() =>  onPress(alert(`${item[titleKey]}`))}>

 <ImageBackground

 style={{

 width:  width,

 height:  height,

 resizeMode:  "cover",

        }}

 source={local ? item[imageKey] : { uri:  item[imageKey] }}

 >

 <LinearGradient

 key={index}

 locations={[0.3, 1]}

 colors={[

 "transparent",

 item[colorKey] == null ? "black" : item[colorKey],

          ]}

 style={styles.linearGradient}

 >

 <View  style={styles.imageTitleContainer}>

 <Title  numberOfLines={1}  style={styles.imageTitle}>

 {item[titleKey]}

 </Title>

 </View>

 </LinearGradient>

 </ImageBackground>

 </Pressable>

  );

};

export  default  ImageSlider;
import { Dimensions, StyleSheet } from "react-native";
import { LIGHTGREY } from "../../../assets/colors/colors";
import {
  MARGINHEIGHTFIVE,
  MARGINHEIGHTTEN,
  MARGINWIDTHTEN,
} from "../../../constants/constants";
const windowWidth = Dimensions.get("window").width;
const windowHeight = Dimensions.get("window").height;

const styles = StyleSheet.create({
  contentContainerStyle: {},
  linearGradient: {
    flex: 1,
  },
  imageTitleContainer: {
    width: windowWidth * (95 / 100),
    paddingRight: 10,
    marginTop: "auto",
    marginBottom: MARGINHEIGHTTEN + MARGINHEIGHTFIVE,
  },
  imageTitle: {
    fontFamily: "Lato-Bold",
    fontSize: 20,
    color: "#ffffff",
    left: MARGINWIDTHTEN,
    textShadowColor: "rgba(0, 0, 0, 0.75)",
    textShadowOffset: { width: -1, height: 1 },
    textShadowRadius: 3,
  },
  circlesContainer: {
    flexDirection: "row",
    position: "absolute",
    bottom: 0,
    alignSelf: "center",
    marginVertical: windowHeight * (0.334 / 100),
  },
  circle: {
    backgroundColor: LIGHTGREY,
    opacity: 0.5,
    height: 5,
    width: 5,
    borderRadius: 50,
    marginHorizontal: windowWidth * (0.924 / 100),
  },
  circleActive: {
    backgroundColor: "#ffffff",
    height: 5,
    width: 5,
    borderRadius: 50,
    marginHorizontal: windowWidth * (0.924 / 100),
  },
});
export default styles;
@wavydeer wavydeer changed the title Created this Flatlist using React Hooks and is working Created this Flatlist-slider using React Hooks and is working Feb 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant