Flutter - 리스트뷰 만들기

유의선·2024년 3월 4일

리스트뷰를 이용해 동물 목록을 보여주는 앱을 만들어보았다.
탭바 코드에 이어서 작성해보았다.


repo/image 폴더를 만들고 그 안에 사용할 이미지를 추가했다.

그 후 pubspec.yaml 파일에 다음 코드를 추가한다.

flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true
  assets:
    - repo/images/bee.png
    - repo/images/cat.png
    - repo/images/cow.png
    - repo/images/dog.png
    - repo/images/fox.png
    - repo/images/monkey.png
    - repo/images/pig.png
    - repo/images/wolf.png

코드 추가 후 pubspec.yaml 파일에서 Flutter commands줄의 Pub get 버튼을 눌러 이미지를 사용할 수 있게 만든다.


lib 폴더에 animalItem.dart 파일을 추가하고 동물 정보를 담당할 Animal 클래스를 생성한다.

import 'package:flutter/material.dart';

class Animal {
  String? imagePath;
  String? animalName;
  String? kind;
  bool? flyExist = false;

  Animal(
      {required this.animalName,
      required this.kind,
      required this.imagePath,
      this.flyExist});
}

이미지 경로, 이름, 종류, 날 수 있는지를 저장할 변수를 선언했다.

Animal 생성자는 생성할 때 전달받은 동물 정보가 중괄호 안에 있는 각각의 매개변수에 대입된다.
매개변수 앞에 붙은 @required 애너테이션은 함수를 호출할 때 꼭 전달해야 하는 값이라는 뜻이다.


main.dart 파일에 animalItem.dart 파일을 import 하고 동물 정보를 담을 List를 선언한다.

import 'animalItem.dart';

...


class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
  TabController? tabController;
  List<Animal> animalList = new List.empty(growable: true);

List를 선언할 때는 처음에는 빈 값이므로 List.empty()로 선언한다.
growable은 이 리스트가 가변적으로 증가할 수 있다는 것을 의미한다.

그 후 각 동물 정보를 입력해 Animal 객체를 생성하고 animalList에 추가한다.
이 작업은 initState() 함수에 작성한다.

  
  void initState() {
    super.initState();
    tabController = TabController(length: 2, vsync: this);

    animalList.add(Animal(animalName: "벌", kind: "곤충", imagePath: "repo/image/bee.png", flyExist: true));
    animalList.add(Animal(animalName: "고양이", kind: "포유류", imagePath: "repo/images/cat.png"));
    animalList.add(Animal(animalName: "소", kind: "포유류", imagePath: "repo/images/cow.png"));
    animalList.add(Animal(animalName: "개", kind: "포유류", imagePath: "repo/images/dog.png"));
    animalList.add(Animal(animalName: "여우", kind: "포유류", imagePath: "repo/images/fox.png"));
    animalList.add(Animal(animalName: "원숭이", kind: "포유류", imagePath: "repo/images/monkey.png"));
    animalList.add(Animal(animalName: "돼지", kind: "포유류", imagePath: "repo/images/pig.png"));
    animalList.add(Animal(animalName: "늑대", kind: "포유류", imagePath: "repo/images/wolf.png"));
  }

firstPage.dartFisrAppanimalList 데이터를 받아올 수 있도록 만들었다.

import 'package:listview_example/animalItem.dart';

class FirstApp extends StatelessWidget {
  final List<Animal>? list;
  FirstApp({Key? key, this.list}) : super(key: key);
  
  ...

list를 final로 선언하면 오류가 발생한다.
이 오류는 생성자로 list 매개변수를 입력받으면 해결된다.

main.dart파일에서 FisrtApp으로 동물 목록을 전달하도록 만든다.

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Listview Example'),
      ),
      body: TabBarView(
        children: <Widget>[FirstApp(list: animalList), SecondApp()],
        controller: tabController,
      ),

FirstApp에서 전달받은 List를 통해 리스트뷰를 만들어보았다.
리스트뷰는 ListView.builder를 사용해 만들 수 있다.
ListView.builder를 사용하려면 itemBuilder가 필요하다.

  
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: Center(
          child: ListView.builder(itemBuilder: (context, position){
            return Card();
          })
        ),
      ),
    );
  }

itemBuilderBuildContextint를 반환한다.
BuildContext는 위젯 트리에서 위젯의 위치를 알려주고,
int는 아이템의 순번을 의미한다.
위 코드에서는 각각 contextposition에 담았다.

리스트뷰의 아이템은 Card로 만들었다.
Card에 이미지와 텍스트 위젯을 이용해 동물 이름을 출력하도록 만들었다

  
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: Center(
            child: ListView.builder(
                itemBuilder: (context, position) {
                  return Card(
                    child: Row(
                      children: <Widget>[
                        Image.asset(
                          list![position].imagePath!,
                          height: 100,
                          width: 100,
                          fit: BoxFit.contain,
                        ),
                        Text(list![position].animalName!)
                      ],
                    ),
                  );
                },
                itemCount: list!.length)),
      ),
    );
  }

position을 이용해 리스트에서 아이템의 위치를 받아
animalNameimagePath를 받아 동물 정보를 받아왔다.

itemCount: list!.length 로 아이템 개수만큼 스크롤 할 수 있게 제한하였다.


0개의 댓글