PR

[Flutter]Flutter Widget of the Week「#103 sensors_plus」、「#104 collection」、「#105 HeroMode」

Flutter

はじめに

前回はFlutter Widget of the Weekの「#100 FlutterLogo」、「#101 animated_text_kit」、「#102 MouseRegion」を紹介しました。

今回はその続きで「#103 sensors_plus」、「#104 collection」、「#105 HeroMode」の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.8

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

#103 sensors_plus

sensors_plusとは

スマホに搭載されている加速度センサーの値を簡単に取得できるパッケージです。

サンプルコード

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

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

  @override
  State<SamplePage103> createState() => _SamplePage103State();
}

class _SamplePage103State extends State<SamplePage103> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('sensors_plus'),
        centerTitle: true,
      ),
      body: SafeArea(
        child: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              StreamBuilder(
                stream: accelerometerEvents,
                builder: (context, snapshot) {
                  if (snapshot.connectionState == ConnectionState.waiting) {
                    return const CircularProgressIndicator();
                  }
                  if (snapshot.hasError) {
                    return const Icon(
                      Icons.error,
                      color: Colors.red,
                    );
                  }
                  final event = snapshot.data!;
                  return Column(
                    children: [
                      const Text('accelerometerEvents'),
                      Text('x:${event.x}'),
                      Text('y:${event.y}'),
                      Text('z:${event.z}'),
                    ],
                  );
                },
              ),
              const SizedBox(height: 20),
              StreamBuilder(
                stream: userAccelerometerEvents,
                builder: (context, snapshot) {
                  if (snapshot.connectionState == ConnectionState.waiting) {
                    return const CircularProgressIndicator();
                  }
                  if (snapshot.hasError) {
                    return const Icon(
                      Icons.error,
                      color: Colors.red,
                    );
                  }
                  final event = snapshot.data!;
                  return Column(
                    children: [
                      const Text('userAccelerometerEvents'),
                      Text('x:${event.x}'),
                      Text('y:${event.y}'),
                      Text('z:${event.z}'),
                    ],
                  );
                },
              ),
              const SizedBox(height: 20),
              StreamBuilder(
                stream: gyroscopeEvents,
                builder: (context, snapshot) {
                  if (snapshot.connectionState == ConnectionState.waiting) {
                    return const CircularProgressIndicator();
                  }
                  if (snapshot.hasError) {
                    return const Icon(
                      Icons.error,
                      color: Colors.red,
                    );
                  }
                  final event = snapshot.data!;
                  return Column(
                    children: [
                      const Text('gyroscopeEvents'),
                      Text('x:${event.x}'),
                      Text('y:${event.y}'),
                      Text('z:${event.z}'),
                    ],
                  );
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}

結果

動画

公式リファレンス

sensors_plus | Flutter package
Flutter plugin for accessing accelerometer, gyroscope, and magnetometer sensors.

#104 collection

collectionとは

リストやマップ、セットなどの便利な拡張関数のパッケージです。

サンプルコード

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

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

  @override
  State<SamplePage104> createState() => _SamplePage104State();
}

class _SamplePage104State extends State<SamplePage104> {
  final a = <String>['Nilay', 'Brett', 'Shams', 'Kathy'];
  final b = <String>['Nilay', 'Andrew', 'Fitz', 'Filip'];
  final c = [
    {'apple', 'red'},
    {'banana', 'yellow'}
  ];
  final d = [
    {'apple', 'red'},
    {'banana', 'black'}
  ];

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

    final queue = PriorityQueue<_Sample104Person>(
      (a, b) => a.kindness.compareTo(b.kindness),
    )
      ..add(_Sample104Person(kindness: 2))
      ..add(_Sample104Person(kindness: 3));
    final mom = queue.removeFirst();
    debugPrint('mom : ${mom.kindness}');

    final team = _Sample104Team(<_Sample104Person>{
      _Sample104Person(kindness: 1),
    });

    // UnsupportedError.
    // team.people.add(
    //   _Sample104Person(kindness: 2),
    // );
    debugPrint('team : ${team.length}');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('collection'),
        centerTitle: true,
      ),
      body: SafeArea(
        child: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Text('a : ${a.toString()}'),
              Text('b : ${b.toString()}'),
              Text(
                'ListEquality().equals(a, b):'
                '${const ListEquality<String>().equals(a, b)}',
              ),
              const SizedBox(height: 20),
              Text('c : ${c.toString()}'),
              Text('d : ${d.toString()}'),
              Text(
                'DeepCollectionEquality().equals(c, d):'
                '${const DeepCollectionEquality().equals(c, d)}',
              ),
              const SizedBox(height: 20),
              Text('sum : ${[1, 2, 3, 4].sum}'),
              Text('average  :${[1, 2, 3, 4].average}'),
            ],
          ),
        ),
      ),
    );
  }
}

class _Sample104Person {
  _Sample104Person({
    required this.kindness,
  });

  final int kindness;
}

class _Sample104Team {
  _Sample104Team(
    this._people,
  );

  final Set<_Sample104Person> _people;

  UnmodifiableSetView<_Sample104Person> get people =>
      UnmodifiableSetView(_people);

  int get length => _people.length;
}

結果

flutter: mom : 2
flutter: team : 1

動画

公式リファレンス

collection | Dart package
Collections and utilities functions and classes related to collections.

#105 HeroMode

HeroModeとは

Heroを使ったトランジションを簡単に有効/無効にできるウィジェットです。

サンプルコード

import 'package:flutter/material.dart';

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

  @override
  State<SamplePage105> createState() => _SamplePage105State();
}

class _SamplePage105State extends State<SamplePage105> {
  bool enabled = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('HeroMode'),
        centerTitle: true,
      ),
      body: SafeArea(
        child: Center(
          child: GestureDetector(
            child: HeroMode(
              enabled: enabled,
              child: Hero(
                tag: 'sample105',
                child: Image.asset(
                  'assets/genba_neko.png',
                  width: 128,
                  height: 128,
                ),
              ),
            ),
            onTap: () {
              Navigator.of(context).push<void>(
                MaterialPageRoute(
                  builder: (context) {
                    return const _SamplePage105Sub();
                  },
                ),
              );
            },
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            enabled = !enabled;
          });
        },
        child: enabled
            ? const Icon(Icons.check_box)
            : const Icon(Icons.check_box_outline_blank),
      ),
    );
  }
}

class _SamplePage105Sub extends StatelessWidget {
  const _SamplePage105Sub();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('HeroMode Sub'),
        centerTitle: true,
      ),
      body: SafeArea(
        child: Center(
          child: Hero(
            tag: 'sample105',
            child: Image.asset(
              'assets/genba_neko.png',
            ),
          ),
        ),
      ),
    );
  }
}

結果

HeroMode ONの場合は画像が拡大しながら遷移

HeroMode OFFの場合は普通の画面遷移します。

動画

公式リファレンス

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

さいごに

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

そして追いつく前に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をコピーしました