[Flutter]-ListView

최준영·2021년 1월 7일
1

Flutter

목록 보기
9/10
post-thumbnail
post-custom-banner

ListView

지금까지는 텍스트 이미지 등 단일 정보를 다뤘다면 이제는 다수 항목을 표시할 수 있는 위젯에 대해 다룹니다.

리스트뷰를 다루는 가장 기본적인 패턴은 정적인 데이터와 동적인 데이터로 구분된다.

정적 리스트뷰

리스트뷰에 표시할 데이터가 미리 정해진 경우인 정적 리스트

import 'package:flutter/material.dart';

class ListViewStaticDemo extends StatelessWidget {
  static const List<String> _data=[
    'Mercury',
    'Venus',
    'Earth',
    'Mars',
    'Jupiter',
    'Saturn',
    'Uranus',
    'Neptune'
  ];
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('ListView'),
        centerTitle: true,
      ),
      body: _buildListView(),
    );
  }
  Widget _buildListView(){
    return ListView.builder(
      itemCount: _data.length,
      itemBuilder: (BuildContext _context, int i){
        return ListTile(
          title: Text(_data[i],
            style: TextStyle(fontSize: 23),),
          trailing: Icon(Icons.favorite_border),
        );
      },
    );
  }
}
  • static const List<String> _data
    String형 리스트인 _data에 행성 이름을 넣었습니다.

  • ListView.builder
    ListView.builder는 리스트뷰를 만들 수 있는 가장 표준적인 방법
    빌더는 디자인 패턴의 일종으로 복잡한 기능을 갖는 객체의 생성 과정과 표현 방법을 분리하여 동일 한 생성 절차에서 서로 다른 표현 결과를 만드는 방법을 제공

  • itemCount: _data.length,
    리스트에 표시할 항목의 개수 지정
    생략시 무한 데이터를 갖는 리스트뷰로 가정

  • itemBuilder: (BuildContext _context, int i)
    각 행의 항목을 만드는 방법을 지정
    ListTile에서 title과 아이콘인 trailing을 사용

동적 리스트뷰

데이터의 개수가 사전에 정해지지 않는 동적 데이터 로딩 예제입니다.

휴대폰에 있는 주소록 목록을 표시하는 예제입니다.
주소록 데이터베이스를 접근할 수 있는 contacts_service 패키지를 활용

pubspec.yaml로 가서

다음으로 AndroidManifest.xml로 이동하여 권한을 추가합니다

<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>```

```dart
import 'package:contacts_service/contacts_service.dart';
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';

class ListViewStaticDemo extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('ListView'),
        centerTitle: true,
      ),
      body: ContactListPage()
    );
  }
}
class ContactListPage extends StatefulWidget {
  @override
  _ContactListPageState createState() => _ContactListPageState();
}

class _ContactListPageState extends State<ContactListPage> {
  Iterable<Contact> _contacts;


  @override
  void initState() {
    super.initState();
    _checkPermissions();
  }
  _checkPermissions()async{
    await PermissionHandler().requestPermissions([PermissionGroup.contacts]);
    refreshContacts();
  }
  refreshContacts()async{
    Iterable<Contact> contacts=
        await ContactsService.getContacts(withThumbnails: false);
    setState(() {
      _contacts=contacts;
    });
  }

  @override
  Widget build(BuildContext context) {
    return _contacts !=null
        ? ListView.builder(itemCount: _contacts.length,itemBuilder: _buildRow)
        : Center(child: CircularProgressIndicator());
  }
  Widget _buildRow(BuildContext context,int i){
    Contact c=_contacts.elementAt(i);
    return ListTile(
      leading: (c.avatar !=null && c.avatar.length>0)
          ? CircleAvatar(backgroundImage: MemoryImage(c.avatar))
          : CircleAvatar(child: Text(c.initials()),),
      title: Text(c.displayName ?? " "),
    );
  }
}
  • _checkPermissions()
    먼저 권한을 확인하는 _checkPermissions메서드를 호출합니다
    이 메서드는 사용자의 선택을 기다려야 하므로 async 키워드가 필요합니다
    권한을 획득하면 refreshContacts() async 메서드 호출

  • refreshContacts() async
    refreshContacts() 메서드는 비동기로 contacts_service 패키지에 있는 ContactService.getContacts() 메서드를 호출합니다.
    withThumbnails 속성을 false로 하면 썸네일을 로딩하지 않기 때문에 속도가 빠릅니다
    로딩이 완료되면 setState() 메서드를 호출하여 _contacts변수를 갱신합니다

  • _buildRow
    ListTile 위젯을 사용하여 리스트의 각 행을 표시합니다
    leading 속성에 사진을 표시하거나 없으면 이니셜을 표시합니다.

  • 결과

profile
Flutter 공부합니다
post-custom-banner

1개의 댓글

comment-user-thumbnail
2023년 10월 20일

들고.

답글 달기