[Flutter] ListView.separated로 구분선 표시

5819 단어 MaterialDesignFlutter

목적


  • ListView에서 행 사이에 구분선을 표시합니다.
  • 리스트의 선두와 마지막에도 구분선을 표시한다

  • Android 앱/Material Design에서는 목록 구분선을 표시하지 않는 경우가 많지만, 항목이 많은 목록에서는 구분선을 표시하는 것이 좋습니다.
    htps : // 마테리아 l. 이오 / 코 m 포넨 ts / ぃ sts # 아나토 myVisuals, dividers, and spacing

    경위


  • ListView에 구분선을 표시하고 싶습니다.
  • ListView.separated() 를 사용할 수 있을 것 같다
  • 목록의 시작과 끝에 구분선이 표시되지 않습니다.
  • 구그 코드를 참고로 구현해 보자 ​​
  • 선두와 마지막 구분선이 이중으로 표시되고 있는 것 같다
  • 주제

  • 목록의 시작과 끝에 구분선이 표시되지 않음



    샘플 코드


    Widget separatedList() {
        final itemCount = 6;
        return ListView.separated(
                padding: EdgeInsets.only(top: 20.0),
                itemBuilder: (context, index) => Container(
                            padding: EdgeInsets.all(20.0),
                            alignment: Alignment.centerLeft,
                            child: Text(
                                'row $index',
                                style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold),
                            ),
                        ),
                separatorBuilder: (context, index) {
                    print('separator: $index');
                    return Divider(height: 0.5);
                },
                itemCount: itemCount);
    }
    

    결과





    로그


    I/flutter (13762): separator: 0
    I/flutter (13762): separator: 1
    I/flutter (13762): separator: 2
    I/flutter (13762): separator: 3
    I/flutter (13762): separator: 4
    

    n 행의 표시에 대해서, (n-1) 회 separatorBuilder 가 불리고 있는 것을 알 수 있습니다.
    표시되고 있는 구분선의 개수와 일치하고 있으므로, ListView.separated 로서는 예상대로의 표시인 것을 알 수 있습니다.

    구구한 코드



    실수로 검색하여 다음 사이트(코드)를 찾았습니다.
    - Flutter - How to add first top and last bottom list with divider() on ListView.separated()
    - [Flutter] ListView.separated() 에서 가장 마지막에 Divider() 표시
    itemCount 를 플러스하고 itemBuilderDivider() 를 반환한다는 내용입니다.

    참고로 구현해 보면 그러한 표시가 되었습니다만, 선두와 마지막 구분선에 위화감이 있어 separatorBuilder 의 로그를 주워 보았습니다.

    샘플 코드(수정 1)


    Widget separatedList() {
        final itemCount = 6;
        return ListView.separated(
                padding: EdgeInsets.only(top: 20.0),
                itemBuilder: (context, index) {
                    if (index == 0 || index == itemCount + 1) {
                        return Divider(height: 0.5);
                    }
                    return Container(
                        padding: EdgeInsets.all(20.0),
                        alignment: Alignment.centerLeft,
                        child: Text(
                            'row ${index - 1}',
                            style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold),
                        ),
                    );
                },
                separatorBuilder: (context, index) {
                    print('separator: $index');
                    return Divider(height: 0.5);
                },
                itemCount: itemCount + 2);
    }
    

    결과(수정 1)





    로그(수정 1)


    I/flutter (13762): separator: 0
    I/flutter (13762): separator: 1
    I/flutter (13762): separator: 2
    I/flutter (13762): separator: 3
    I/flutter (13762): separator: 4
    I/flutter (13762): separator: 5
    I/flutter (13762): separator: 6
    

    separatorBuilder 가 7회 불리고 있기 때문에 문제 없음!
    생각하면
    if (index == 0 || index == itemCount + 1) {
        return Divider(height: 0.5);
    }
    

    에 의해 2개의 구분선을 묘화 하고 있을 것이므로, 합계로 9개가 되어 역시 여분에 선을 묘화 하고 있었습니다.
    itemCount 를 + 2 하고 return Divider(height: 0.5) 하고 있는 분도 행으로서 다루어지기 때문에, 이것에 대해서도 한층 더 단락선을 렌더링 하려고 하기 때문이군요.

    대책



    처음과 끝에서 Divider(height: 0.5)를 반환하는 대신 빈 Container()를 반환하도록 변경했습니다.

    샘플 코드(수정 2)


    Widget separatedList() {
        final itemCount = 6;
        return ListView.separated(
                padding: EdgeInsets.only(top: 20.0),
                itemBuilder: (context, index) {
                    if (index == 0 || index == itemCount + 1) {
                        return Container();
                    }
                    return Container(
                        padding: EdgeInsets.all(20.0),
                        alignment: Alignment.centerLeft,
                        child: Text(
                            'row ${index - 1}',
                            style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold),
                        ),
                    );
                },
                separatorBuilder: (context, index) {
                    print('separator: $index');
                    return Divider(height: 0.5);
                },
                itemCount: itemCount + 2);
    }
    

    결과(수정 2)





    기대한 표시가 되었습니다.
    리스트의 선두와 마지막에는 구분선을 표시하지 않는 디자인으로 하는 것이 좋을 것 같네요.

    좋은 웹페이지 즐겨찾기