【Flutter】심플한 header와 footer를 작성한다

16864 단어 DartVSCodeFlutter
Provider 패턴으로 Model을 만들고 header와 footer가 있는 앱을 만듭니다.
완성형은 다음과 같은 형태



(gif이므로 흐릿하지만, 실제로는 고화질입니다)

footer( BottomNavigationBar )를 누른 위치에 따라 header의 문자와 body에 표시되는 것을 바꾸고 있습니다.

파일 구조



이번에는 모델을 사용합니다.
lib
├── header.dart
├── main.dart
├── models
│   └── bottom_navigation_model.dart
└── routes
    ├── home.dart
    ├── profile.dart
    └── settings.dart

lib/main.dart



참고 기사 무엇인가를 읽고 있으면 BottomNavigationBarItemlabel 의 부분을 title 로 해 Text() 로 묘화 하고 있는 기사가 많습니다만, 그것은 v1.19.0 에서는는 추천되고 있지 않는 것 같습니다.

@Deprecated('Use "label"instead, as it allows for an improved text-scaling experience. ' 'This feature was deprecated after v1.19.0.'), final

참고 : BottomNavigationBarItem class - widgets library - Dart API


lib/main.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'models/bottom_navigation_model.dart';
import 'routes/profile.dart';
import 'routes/home.dart';
import 'routes/settings.dart';

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

class MyApp extends StatelessWidget {
  final List _pageList = [
    Profile(),
    Home(),
    Settings(),
  ];
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutterの練習', //アプリの名前
      theme: ThemeData(
        primaryColor: Colors.green,
      ),
      home: ChangeNotifierProvider<BottomNavigationModel>(
        create: (_) => BottomNavigationModel(),
        child:
            Consumer<BottomNavigationModel>(builder: (context, model, child) {
          return Scaffold(
            // appBar: Header(), //各ファイルでHeader()を実行するのでいらない
            body: _pageList[model.currentIndex], //中身を描画
            //footer部分
            bottomNavigationBar: BottomNavigationBar(
              type: BottomNavigationBarType.fixed,
              items: [
                BottomNavigationBarItem(
                  icon: Icon(Icons.person),
                  label: 'プロフィール',
                ),
                BottomNavigationBarItem(
                  icon: Icon(Icons.home),
                  label: 'ホーム',
                ),
                BottomNavigationBarItem(
                  icon: Icon(Icons.settings),
                  label: '設定',
                ),
              ],
              currentIndex: model.currentIndex,
              onTap: (index) {
                model.currentIndex = index;
              },
              selectedItemColor: Colors.pinkAccent, //選んだ物の色
              unselectedItemColor: Colors.black45, //選んでない物の色
            ),
          );
        }),
      ),
    );
  }
}

lib/header.dart


Icons.add 를 기술하고 있습니다만, 특별히 의미는 없습니다.

lib/header.dart
import 'package:flutter/material.dart';

class Header extends StatelessWidget with PreferredSizeWidget {
  final String headerTitle;
  Header({this.headerTitle}); //ヘッダータイトルを変更できるようにする
  @override
  Size get preferredSize => Size.fromHeight(kToolbarHeight);

  @override
  Widget build(BuildContext context) {
    return AppBar(
      title: Text(headerTitle),
      actions: [
        Padding(
          padding: const EdgeInsets.all(8.0),
          child: IconButton(
            icon: Icon(Icons.add),
            onPressed: () {
              //押したときの処理
            },
          ),
        )
      ],
    );
  }
}

lib/models/bottom_navigation_model.dart



lib/models/bottom_navigation_model.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class BottomNavigationModel extends ChangeNotifier {
  int _currentIndex = 1; //最初に表示される画面

  // getterとsetterを指定しています
  // setのときにnotifyListeners()を呼ぶことアイコンタップと同時に画面を更新しています。
  get currentIndex => _currentIndex;

  set currentIndex(int index) {
    _currentIndex = index;
    notifyListeners(); // View側に変更を通知
  }
}


lib/routes/profile.dart



lib/routes/profile.dart
import 'package:flutter/material.dart';
import '../header.dart';

class Profile extends StatelessWidget {
  final String screenName = 'プロフィール'; //headerに表示される名前
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: Header(headerTitle: screenName),
      body: Center(
        child: Text(screenName),
      ),
    );
  }
}

lib/routes/home.dart



lib/routes/home.dart
import 'package:flutter/material.dart';
import '../header.dart';

class Home extends StatelessWidget {
  final String screenName = 'ホーム'; //headerに表示される名前
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: Header(headerTitle: screenName),
      body: Center(
        child: Text(screenName),
      ),
    );
  }
}

lib/routes/settings.dart



lib/routes/settings.dart
import 'package:flutter/material.dart';
import '../header.dart';

class Settings extends StatelessWidget {
  final String screenName = '設定'; //headerに表示される名前
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: Header(headerTitle: screenName),
      body: Center(
        child: Text(screenName),
      ),
    );
  }
}

참고



Flutter : 간단하고 StatelessBottomNavigationBar를 만들어 본 이야기
Flutter에서 Twitter 클라이언트 작성 ② 바닥글 추가

좋은 웹페이지 즐겨찾기