본문 바로가기

그 땐 App했지/그 땐 Flutter했지

[TAVE/Study] Do it! Flutter 5장 탭바와 리스트 만들기①

728x90

210927 월

이번에 TSC 본다고 공부가 엄청나게 밀렸다...

알바가기 전에 급하게 달리는 중..ㅎ

 

여러 페이지 만들고 이동하기

 

import 'package:flutter/material.dart';
import 'sub/firstPage.dart';
import 'sub/secondPage.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('TabBar Example'),
        ),
        body: TabBarView(
          children: <Widget>[FirstApp(), SecondApp()],
          controller: controller,
        ),
        bottomNavigationBar: TabBar(tabs: <Tab>[
          Tab(icon: Icon(Icons.looks_one, color: Colors.blue),),
          Tab(icon: Icon(Icons.looks_two, color: Colors.blue),)
        ], controller: controller,
        )
    );
  }

  TabController? controller;

  @override
  void initState() {
    super.initState();
    controller = TabController(length: 2, vsync: this);
  }

  @override
  void dispose() {
    controller!.dispose();
    super.dispose();
  }
}

👉🏻 탭바 위젯을 사용하려면 탭 컨트롤러(TabController)가 필요하다. body에 FirstApp, SecondApp 연결하고 import문으로 파일의 경로를 추가한다.

✍🏻 length는 탭 개수, vsync는 탭이 이동했을 때 호출되는 콜백 함수를 어디서 처리할지 지정한다.

✍🏻 with 키워드는 여러 클래스를 재사용할 수 있는 키워드이다. 

✍🏻 dispose는 위젯의 상태 관리를 완전히 끝내는 함수이다. (State 객체 소멸)

 

 

목록을 보여주는 리스트 뷰

 

flutter:
  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

👉🏻 이미지를 사용할 수 있게 한다. 이 코드를 추가후 Pub get을 클릭한다.

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});
}

animalItem.dart

👉🏻 이 파일을 통해 동물 정보를 객체로 받아 저정한다.

✍🏻 required는 함수를 호출할 때 꼭 전달해야하는 값이다.

import 'package:flutter/material.dart';
import './animalItem.dart';
import 'sub/firstPage.dart';
import 'sub/secondPage.dart';

(...생략...)

class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin
{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('ListView Example'),
        ),
        body: TabBarView(
          children: <Widget>[
            FirstApp(list: animalList),
            SecondApp()
          ],
          controller: controller,
        ),
        bottomNavigationBar: TabBar(tabs: <Tab>[
          Tab(icon: Icon(Icons.looks_one, color: Colors.blue),),
          Tab(icon: Icon(Icons.looks_two, color: Colors.blue),)
        ], controller: controller,
        )
    );
  }
  TabController? controller;
  List<Animal> animalList = new List.empty(growable: true);

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

    animalList.add(Animal(animalName: "벌", kind: "곤충",
      imagePath: "repo/images/bee.png"));
    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"));
  }

  @override
  void dispose() {
    controller!.dispose();
    super.dispose();
  }
}

main.dart

👉🏻 동물 객체를 저장할 animalList를 선언한다. initState에 animalList에 요소들을 추가한다. 

✍🏻 첫 리스트는 빈 값이라 empty이고 growable: true가변적으로 증가할 수 있다는 의미이다.

import 'package:flutter/material.dart';
import '../animalItem.dart';

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

  @override
  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), //아이템 개수만큼만 스크롤 하도록 제한
        ),
      ),
    );
  }
}

firstPage.dart

👉🏻 FirstApp에 animalList를 전달한다. ListView.builder리스트뷰를 위젯으로 만든다.

✍🏻 ListView.builder를 만들기 위해서는 itemBuilder가 필요하다.

728x90