흰오목눈이야 개발하자

[Flutter] Carousel Slider의 Indicator 구현하기 본문

Flutter

[Flutter] Carousel Slider의 Indicator 구현하기

흰오목눈이 2024. 5. 12. 15:36

 

슬라이더 이미지 위젯 아래에 위와 같은 Indicator(인디케이터)를 구현하려고 한다

 

# 구현 결과

 Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: imageUrls.asMap().entries.map((entry) {
          return Container(
            width: 8,
            height: 8,
            margin: const EdgeInsets.symmetric(vertical: 2, horizontal: 2),
            decoration: BoxDecoration(
              shape: BoxShape.circle,
              color:
                  Colors.black.withOpacity(currentIndex == entry.key ? 1 : 0.5),
            ),
          );
        }).toList(),

 

해당 이미지의 인덱스와 동일하면 진한 색으로 해당 위치를 알려주고 다른 부분은 투명도를 적용해 연한 색으로 표시해 구별을 줄 거다.

각 동그라미 인덱스들을 만들고 Row로 묶어서 가로로 나열하는 방법으로 구현할 수 있었다.

 

+) currentIndex는 Carousel Slider의 인덱스가 됩니다

아래는 예시입니다

int currentIndex = 0; // build 메소드 밖에 선언

# 코드 분석

imageUrls.asMap().entries.map((entry) {

 

이 코드를 이해하기 위해서는 아래의 지식이 필요하다.

 

1. asMap()이란?

리스트를 사용할 때 각 리스트의 항목에 대한 인덱스를 포함하는 Map을 생성하는 메서드다.

이 Map의 키(key)는 각 요소의 인덱스이고 값(value)은 해당 요소이다.

 

예를 들어, 다음과 같은 리스트가 있다고 가정해 보자.

List<String> urls = [ 'imageUrl1', 'imageUrl2', 'imageUrl3'];

 

List<String> urls

이 리스트를 asMap() 메서드를 사용하여 변환하면 다음과 같다.

Map<int, String> urlsMap = urls.asMap();

 

이제 urlsMap은 다음과 같이 되어 있다

{
    0: 'imageUrl1',
    1: 'imageUrl2',
    2: 'imageUrl3'
}

 

따라서, 'asMap'을 사용하면 리스트의 각 요소에 대한 인덱스와 해당 요소가 포함된 Map을 얻을 수 있다.

이렇게 생성된 Map은 각 요소에 대한 인덱스를 사용하여 해당 요소를 참조할 수 있다

 

2. entries는 무엇인가?

entries 메서드는 Iterable(반복 가능한 개체)을 반환하는 것이다.

Iterable은 Map의 각 항목에 대해 키와 값의 쌍을 포함한다.

 

따라서 entries 메서드를 사용하여 Map을 반복하면 각 항목에 대한 키와 값의 쌍을 얻을 수 있다

예를 들어, 다음과 같은 Map이 있다고 가정해 보자.

Map<int, String> urlsMap = {
    0: 'imageUrl1',
    1: 'imageUrl2',
    2: 'imageUrl3'
};

 

이 Map을 entries 메서드를 사용하여 반복하면 다음과 같다

for (var entry in urlsMap.entries) {
  print('${entry.key}: ${entry.value}');
}

 

위 코드는 다음과 같이 출력된다.

0: imageUrl1
1: imageUrl2
2: imageUrl3

 

따라서 entries 메서드를 사용하면 Map의 각 항목에 대한 키-값 쌍을 반복하고 해당 키와 값을 개별적으로 처리할 수 있다.

3. 마지막으로 map()을 사용한 이유?

각 이미지 URL과 해당 인덱스에 대해 컨테이너를 생성하기 위해서다.  = 원형 인덱스 하나를 생성하기 위해서

이 컨테이너는 원형의 인디케이터 역할을 한다.

 

인덱스(위 코드에서는 entry.key가 해당됨)가 currentIndex와 일치하면 해당 인디케이터의 색상이 완전히 불투명하도록 설정되고, 그렇지 않으면 반투명하도록 설정된다.

<지금까지 이해한 것>
asMap() : 이미지 리스트의 인덱스를 생성하기 위해 사용. 키-값 쌍으로 이루어진 map을 만들어줌
entries: 해당 요소를 쌍으로 가져옴
map(): 각 쌍에 대해 특정한 작업을 수행함

 

 

4. toList()는?

toList() 메서드를 호출하여 결과를 다시 리스트로 변환하여 children 프로퍼티에 전달한다.

이제 각 이미지 URL과 해당 인덱스에 대해 생성된 모든 컨테이너가 행(Row) 위에 배치된다.


다른 의문점

Q. asMap이랑 Map은 무슨 차이?

A. `asMap`과 `Map`은 서로 다른 것이다.

 

1. asMap: asMap은 리스트를 사용할 때 리스트의 각 요소에 대한 인덱스를 포함하는 Map을 생성하는 메서드다.

이 메서드는 Iterable를 Map으로 변환할 때 사용된다. 각 요소의 인덱스가 키(key)이고 요소 자체가 값(value)다.

이렇게 생성된 Map은 각 요소의 인덱스를 사용하여 해당 요소를 참조할 수 있다.

 

2. Map: Map은 키(key)와 값(value)의 쌍으로 이루어진 데이터 구조다. Map은 데이터를 키와 값의 쌍으로 저장하고, 키를 사용하여 값을 조회하거나 변경할 수 있다.

 

예시를 들자면 다음과 같이 설명할 수 있다.

List<String> fruits = ['apple', 'banana', 'orange'];
Map<int, String> fruitMap = fruits.asMap(); // 리스트를 Map으로 변환하여 인덱스와 요소를 매핑

print(fruitMap); // 출력: {0: 'apple', 1: 'banana', 2: 'orange'}
print(fruitMap[0]); // 출력: apple


위 코드에서 asMap 메서드는 리스트의 각 요소와 해당 요소의 인덱스를 매핑한 Map을 생성한다. 이렇게 생성된 Map은 인덱스를 사용하여 리스트의 요소를 참조할 수 있다. 

반면에 Map은 키와 값의 쌍으로 데이터를 저장하는 일반적인 Map 데이터 구조다.


 

전체 흐름 정리

 

 

 

(!) 도식화는 개인적으로 공부하면서 작성한 과정이기에 정확하지 않을 수 있습니다. 댓글로 따뜻한 피드백 부탁드립니다.