平面表测量项目X位置 [英] Flatlist measure Items X position

查看:0
本文介绍了平面表测量项目X位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的水平列表中有大约10个项目。我如下所示存储了对每个项目的引用。

const Item = ({ title, image, index }) => {
  linkRefs[index] = useRef(null);

  return (
    <Animated.View ref={linkRefs[index]}>
      <Image
        resizeMode="cover"
        style={styles.tinyLogo}
        source={{
          uri: image,
        }}
      />
    </Animated.View>
  );
};

我想获取可见元素的X位置。所以我尝试了下面的代码,它运行良好。

 const Measure = () => {
       Object.keys(itemsY).forEach(function (key) {
        linkRefs[key].current.measure((x, y, width, height, pageX, pageY) => {
          if(typeof pageX != "undefined")
          {
            itemsY[key].setValue(pageX);
            console.log(key+"--"+pageX);
            console.log("width--"+width);
            console.log("---");
          }
        });
      });
    };

问题是,测量仅对完全可见的项目起作用。我甚至希望测量位置,即使它很少可见。我该如何做?

我尝试了itemVisiblePercentThreshold,仍然只对完全可见的项进行度量。

 const viewabilityConfig = useRef({
    itemVisiblePercentThreshold:20
  }).current;     

 <Animated.FlatList
      horizontal
      pagingenabled
      snapToInterval={125}
      snapToAlignment="center"
      decelerationRate="fast"
      showsVerticalScrollIndicator={true}
      showsHorizontalScrollIndicator={false}
      data={DATA}
      renderItem={renderItem}
      keyExtractor={item => item.id}
      initialNumToRender={4}
      horizontal={true}
      viewabilityConfig={viewabilityConfig}
      />

推荐答案

当我使用平面列表时,我决定想知道列表滚动的方向,所以我最终使用onScroll道具来获取该值:

import React , { useState, useRef,useCallback } from 'react';
import { SafeAreaView, Image , View, FlatList, StyleSheet, Text, StatusBar } from 'react-native';
import { Ionicons, MaterialCommunityIcons , FontAwesome5 } from "@expo/vector-icons";
import * as Animatable from 'react-native-animatable';
import FlatListWrapper from "../components/FlatListWrapper";



const FlatListAnimation = () => {
  const DATA = [
    {
      id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
      title: 'First  Item Item Item',
      image : 'https://res.cloudinary.com/Sony-liv/image/fetch/c_fill,e_brightness:10,f_auto,fl_lossy,h_494,q_auto:low,w_344/https://origin-staticv2.sonyliv.com/portrait_thumb/scam_Lang_Protrait_Thumb.jpg'
    },
    {
      id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
      title: 'Second Item',
      image : 'https://res.cloudinary.com/Sony-liv/image/fetch/c_fill,e_brightness:10,f_auto,fl_lossy,h_494,q_auto:low,w_344/https://origin-staticv2.sonyliv.com/portrait_thumb/Ramsingh-CharlieA_07062021_Lang_Protrait_Thumb.jpg'
    },
    {
      id: '58694a0f-3da1-471f-bd96-145571e29d72-3-3',
      title: 'Third Item',
      image : 'https://res.cloudinary.com/Sony-liv/image/fetch/c_fill,e_brightness:10,f_auto,fl_lossy,h_494,q_auto:low,w_344/https://origin-staticv2.sonyliv.com/portrait_thumb/6028647473001.jpg'
  
    },
    {
      id: '58694a0sdsf-3da1-471f-bd96-145571e29d72-4-4',
      title: 'Fourth Item',
      image : 'https://res.cloudinary.com/Sony-liv/image/fetch/c_fill,e_brightness:10,f_auto,fl_lossy,h_494,q_auto:low,w_344/https://origin-staticv2.sonyliv.com/portrait_thumb/6033313370001.jpg'
  
    },
    {
      id: '58694a0f-3ddsda1-471f-bd96-145571e29d72-5-5',
      title: 'Fifth Item',
      image : 'https://res.cloudinary.com/Sony-liv/image/fetch/c_fill,e_brightness:10,f_auto,fl_lossy,h_494,q_auto:low,w_344/https://origin-staticv2.sonyliv.com/portrait_thumb/6033325319001_v2.jpg'
  
    },
    {
      id: 'bd7acbea-c1b1-46c2-aed5-3ad531abb28ba-6-6',
      title: 'Sixth  Item Item Item',
      image : 'https://res.cloudinary.com/Sony-liv/image/fetch/c_fill,e_brightness:10,f_auto,fl_lossy,h_494,q_auto:low,w_344/https://origin-staticv2.sonyliv.com/portrait_thumb/scam_Lang_Protrait_Thumb.jpg'
    },
    {
      id: '3ac68afc-c605-48d3-a4f8-fbd912aa97f63-7-7',
      title: 'Seventh Item',
      image : 'https://res.cloudinary.com/Sony-liv/image/fetch/c_fill,e_brightness:10,f_auto,fl_lossy,h_494,q_auto:low,w_344/https://origin-staticv2.sonyliv.com/portrait_thumb/Ramsingh-CharlieA_07062021_Lang_Protrait_Thumb.jpg'
    },
    {
      id: '58694a0f-3da1-471f-bd96-1455371e29d72-8-8',
      title: 'Eighth Item',
      image : 'https://res.cloudinary.com/Sony-liv/image/fetch/c_fill,e_brightness:10,f_auto,fl_lossy,h_494,q_auto:low,w_344/https://origin-staticv2.sonyliv.com/portrait_thumb/6028647473001.jpg'
  
    },
    {
      id: '58694a0sdsf-3da1-471f-bd96-1445571e29d72-9-9',
      title: 'Ninth Item',
      image : 'https://res.cloudinary.com/Sony-liv/image/fetch/c_fill,e_brightness:10,f_auto,fl_lossy,h_494,q_auto:low,w_344/https://origin-staticv2.sonyliv.com/portrait_thumb/6033313370001.jpg'
  
    },
  ];
  const maxlimit = 20;
    // store the indices of the viewableItmes
  const [ viewableItemsIndices, setViewableItemsIndices ] = useState([]);
  const itemRefs = useRef(
    DATA.map( item=> {})
  );
  
  const isScrollingForward = useRef(true);
  // use last and current scroll position to determine scroll direction
  const lastScrollPosition = useRef(0);
  const handleScroll = ({nativeEvent})=>{
    let currentPosition = nativeEvent.contentOffset.x
    isScrollingForward.current = currentPosition > lastScrollPosition.current
    lastScrollPosition.current = currentPosition
  }
    // Item.js
  const Item = (props) => { 
    let {
      item:{ image , title, isViewable },
      index
    } = props
    return (
      //add animation to Animated.View
      <Animatable.View style={styles.itemContainer} ref={ref=>itemRefs[index]=ref} >
        <Image
          resizeMode="contain"
          style={styles.tinyLogo}
          source={{
            uri: image,
          }}
        />
      </Animatable.View>
    );
  }
  return (
    <SafeAreaView style={styles.container}>
      <FlatListWrapper
        horizontal={true}
        //{/*give each data item an isViewable prop*/}
        data={ DATA }
        renderItem={(item,i)=><Item {...item} />}
        keyExtractor={item => item.id}
        onViewableItemsChanged={({viewableItems, changed})=>{
          let duration = 2000;
          viewableItems.forEach(item=>{
            let itemRef = itemRefs[item.index];
            itemRef?.transitionTo({opacity:1},duration)
            isScrollingForward.current ? 
              itemRef?.bounceInRight() :
              itemRef?.bounceInLeft()
          })
          changed.forEach(item=>{
            let itemRef = itemRefs[item.index];
            if(!item.isViewable){
              itemRef?.transitionTo({opacity:0})
              isScrollingForward.current ? 
              itemRef?.bounceOutLeft() :
              itemRef?.bounceInRight()
            }
          })
        }}
        //{/*config that decides when an item is viewable*/} 
        viewabilityConfig={{itemVisiblePercentThreshold:100}}
        onScroll={handleScroll}
        disableScrollMomentum={true}
      />
     {/* Extra stuff that just tells you what items should be visible*/}
      <Text>Items that should be visible:</Text>
      {viewableItemsIndices.map(i=><Text key={'text-'+i}>  {DATA[i].title}</Text>)}
    </SafeAreaView>
  );
}
  
const styles = StyleSheet.create({
  container: {
    // flex: 1,
    marginTop: StatusBar.currentHeight || 0,
  },
  itemContainer: {
    opacity:0
  },
  title: {
    fontSize: 32,
  },
  tinyLogo: {
    borderRadius : 4,
    width: 150,
    height:150
  },
});

  export default FlatListAnimation; 

这篇关于平面表测量项目X位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆