[Flutter]Flutter Widget of the Week「#121 StatefulBuilder」、「#122 RepaintBoundary」、「#123 google_fonts」

Flutter

はじめに

前回はFlutter Widget of the Weekの「#118 badges」、「#119 DropdownButton」、「#120 ScaffoldMessengerを紹介しました。

今回はその続きで「#121 StatefulBuilder」、「#122 RepaintBoundary」、「#123 google_fonts」の3つです。

前回の記事はこちら

またGitHubにも公開しています。

GitHub - nobushiueshi/flutter_widget_of_the_week
Contribute to nobushiueshi/flutter_widget_of_the_week development by creating an account on GitHub.

Flutter Widget of the Week

環境

  • Flutter 3.3.10

記事にした時点でのバージョンです。GitHubに公開しているのは常に最新の安定版(stable)を使う予定です。

#121 StatefulBuilder

StatefulBuilderとは

ウィジェットの一部分だけ状態を持たせたい場合や巨大なウィジェットツリーを効率的にビルドさせたいときに使うのがこのStatefulBuilderです。

サンプルコード

import 'package:flutter/material.dart';

class SamplePage121 extends StatefulWidget {
  const SamplePage121({
    super.key,
  });

  @override
  State<SamplePage121> createState() => _SamplePage121State();
}

class _SamplePage121State extends State<SamplePage121> {
  bool _value = false;

  @override
  Widget build(BuildContext context) {
    debugPrint('SamplePage121#build');
    return Scaffold(
      appBar: AppBar(
        title: const Text('StatefulBuilder'),
        centerTitle: true,
      ),
      body: SafeArea(
        child: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              StatefulBuilder(
                builder: (context, setState) => CheckboxListTile(
                  title: const Text('ページ全体がリビルドされない'),
                  value: _value,
                  onChanged: (newValue) {
                    // debugPrintされない.
                    // つまりページ全体がリビルドされない.
                    setState(() => _value = newValue ?? false);
                  },
                ),
              ),
            ],
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // debugPrintされる.
          // ページ全体がリビルドされている。
          setState(() {
            _value = !_value;
          });
        },
        child: const Icon(Icons.check_box),
      ),
    );
  }
}

結果

真ん中のチェックリストを押下してもbuildのログが表示されませんが、フローティングアクションボタンの場合は表示されます。

動画

公式リファレンス

StatefulBuilder class - widgets library - Dart API
API docs for the StatefulBuilder class from the widgets library, for the Dart programming language.

#122 RepaintBoundary

RepaintBoundaryとは

このRepaintBoundaryはどのウィジェットのレンダリングが更新されているかを色で教えてくれるデバッグ機能です。

色が頻繁に変わらなければレンダリングが重い等あった場合にこのRepaintBoundaryを使って調べましょう。

サンプルコード

import 'dart:math';

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

class SamplePage122 extends StatefulWidget {
  const SamplePage122({
    super.key,
  });

  @override
  State<SamplePage122> createState() => _SamplePage122State();
}

class _SamplePage122State extends State<SamplePage122> {
  @override
  void initState() {
    super.initState();
    debugRepaintRainbowEnabled = true;
  }

  @override
  void dispose() {
    debugRepaintRainbowEnabled = false;
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('RepaintBoundary'),
        centerTitle: true,
      ),
      body: SafeArea(
        child: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: const [
              RepaintBoundary(
                child: SamplePage122Rotate(),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class SamplePage122Rotate extends StatefulWidget {
  const SamplePage122Rotate({
    super.key,
  });

  @override
  State<SamplePage122Rotate> createState() => _SamplePage122RotateState();
}

class _SamplePage122RotateState extends State<SamplePage122Rotate>
    with SingleTickerProviderStateMixin {
  late final AnimationController controller;
  late final Animation<double> animation;

  @override
  void initState() {
    super.initState();

    controller = AnimationController(
      duration: const Duration(seconds: 2),
      vsync: this,
    )..repeat();
    animation = Tween<double>(
      begin: 0,
      end: 2 * pi,
    ).animate(controller);
  }

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

  @override
  Widget build(BuildContext context) {
    return Center(
      child: AnimatedBuilder(
        animation: animation,
        child: const FlutterLogo(
          size: 100,
        ),
        builder: (context, child) {
          return Transform.rotate(
            angle: animation.value,
            child: child,
          );
        },
      ),
    );
  }
}

結果

動画

公式リファレンス

RepaintBoundary class - widgets library - Dart API
API docs for the RepaintBoundary class from the widgets library, for the Dart programming language.

#123 google_fonts

google_fontsとは

その名の通り、Google Fontsが簡単に導入できるパッケージです。

ただし、残念ながら日本語のフォントには対応してないようです。

サンプルコード

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

class SamplePage123 extends StatelessWidget {
  const SamplePage123({
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('google_fonts'),
        centerTitle: true,
      ),
      body: SafeArea(
        child: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Text(
                'Dash is awesome!',
                style: GoogleFonts.lobster(),
              ),
              const SizedBox(height: 20),
              Text(
                'Dash is awesome!',
                style: GoogleFonts.lobster(
                  fontSize: 20,
                ),
              ),
              const SizedBox(height: 20),
              Text(
                'Dash is awesome!',
                style: GoogleFonts.notoSansJavanese(),
              ),
              const SizedBox(height: 20),
              Text(
                'Dash is awesome!',
                style: GoogleFonts.abel(),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

結果

動画

公式リファレンス

google_fonts | Flutter Package
A package to include fonts from fonts.google.com in your Flutter app.

さいごに

このシリーズ、終りが見えない。。。

そして追いつく前にYouTubeのFlutter Widget of the Weekが終わってしまい、悲しみ。。。と思ったら再開された?

おすすめ参考書

リンク

GitHub - nobushiueshi/flutter_widget_of_the_week
Contribute to nobushiueshi/flutter_widget_of_the_week development by creating an account on GitHub.

コメント

タイトルとURLをコピーしました