flatlist에서 항목위치를 가운데 고정하고 싶은 경우

박은정·2022년 10월 7일
0

리액트네이티브

목록 보기
13/24

원하는 결과물

데이터 개수가 1,2개일때

데이터 개수가 3개이상일때


방법1 : contentOffset

flatlist에서 스크롤위치를 지정하는 prop contentOffset으로 아래와 같이 사용했다.
horizontal 속성으로 스크롤방향을 가로로 지정한 경우 contentOffset에 x값을 넣어주면 되고
반대로 기본적인 스크롤방향이 세로인 경우 y값을 지정해주면 된다.

한편, contentOffset 속성을 사용하기 위해서는 getItemLayout prop으로 객체를 반환해줘야 한다.

getItemLayout

getItemLayout은 항목의 크기 (너비/높이)를 미리 아는 경우 동적인 사이즈 측정을 건너뛸 수 있는 옵션 최적화입니다. 다음과 같은 고정 크기 항목이 있는 경우 효율적입니다.

 getItemLayout={(data, index) => (
    {length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index}
  )}

getItemLayout을 추가하면 수백 개의 항목 목록에 대한 성능이 크게 향상될 수 있습니다.
ItemSeparatorComponent를 지정하는 경우 ItemSeparatorComponent에 separator의 길이를 포함해야 합니다.

<FlatList 
  horizontal 
  contentOffset={{x:위치시키고 싶은 x위치}} 
  getItemLayout={(data, index) => 
 	({ length: renderItem의 사이즈, offset: renderItem의 사이즈 * index, index })
} />

문제발생

한편, 데이터개수가 1,2개일때는 아래와 같이 위치가 바뀌고 3개가 되면 다시 위처럼 동적으로 위치가 변경되어야 하는데 데이터 개수가 2->3개로 추가될 때 3번째 요소는 없듯이 주황색 요소 끝에까지만 x위치가 이동되었다.

방법2 : onContentSizeChange

위에서 느낀대로 스크롤 길이를 알 수 있는 방법을 찾다가,
스크롤할 수 있는 content의 사이즈가 변경되면 실행되는 함수 prop을 찾아서 아래와 같이 콘솔로그로 확인해보니 undefined가 나왔다가 원래 스크롤 길이로 두번 찍히는 것을 확인했다.

<FlatList 
	horizontal
	contentOffset={{x:offset_x}}
    onContentSizeChange={contentWidth => {
        console.log('사이즈변경');
		console.log(contentWidth);
    }}
/>
사이즈변경
449.5238037109375
undefined
사이즈변경
684.5714111328125
undefined
사이즈변경

결과

그래서 contentWidth값이 존재할때만 offset값을 변경시켜주도록 했다.

const [offset, setOffset] = useState(0);
const [data, setData] = useState([]);

const handleOffset = useCallback(() => {
  if (data.length > 2) setOffset(MARK_OFFSET);
  else setOffset(0);
}, [data]);

<FlatList
  horizontal
  renderItem={renderItem}
  data={data}
  getItemLayout={(data, index) => 
  	({ length: renderItem의 사이즈, offset: renderItem의 사이즈 * index, index })
  }
  contentOffset={{ x: offset }}
  onContentSizeChange={contentWidth => {
      if (contentWidth) handleOffset();
  }}
/>
profile
새로운 것을 도전하고 노력한다

0개의 댓글