PR

[Flutter]Flutter Widget of the Week「#82 AboutDialog」、「#83 async」、「#84 url_launcher」

Flutter

はじめに

前回はFlutter Widget of the Weekの「#79 AnimatedWidget」、「#80 Padding」、「#81 CheckboxListTile」を紹介しました。

今回はその続きで「#82 AboutDialog」、「#83 async」、「#84 url_launcher」の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.2

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

#82 AboutDialog

AboutDialogとは

規約、バージョン、ライセンス、その他注意事項を簡単に実装できるウィジェットです。

サンプルコード

import 'package:flutter/material.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('AboutDialog'),
        centerTitle: true,
      ),
      body: SafeArea(
        child: Center(
          child: ElevatedButton(
            onPressed: () {
              showAboutDialog(
                context: context,
                applicationName: 'Flutter Widget of the Week',
                applicationVersion: '1.0.0',
                applicationIcon: const FlutterLogo(
                  size: 32,
                ),
                applicationLegalese: '適当な文章',
              );
            },
            child: const Text('AboutDialog'),
          ),
        ),
      ),
    );
  }
}

結果

動画

公式リファレンス

AboutDialog class - material library - Dart API
API docs for the AboutDialog class from the material library, for the Dart programming language.

#83 async

asyncとは

便利な機能がある非同期パッケージです。

複数のstreamを1つにマージさせたり、キャッシュさせたり、streamをfutureに変換できたり様々な機能があります。

サンプルコード

import 'dart:async';

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

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

  @override
  State<SamplePage083> createState() => _SamplePage083State();
}

class _SamplePage083State extends State<SamplePage083> {
  final stream1Controller = StreamController<int>();
  final stream2Controller = StreamController<int>();
  final stream3Controller = StreamController<int>();

  late final Stream<int> totalStream;

  final countCache = AsyncCache<int>(
    const Duration(seconds: 15),
  );

  @override
  void initState() {
    super.initState();
    totalStream = StreamGroup.merge(
      [
        stream1Controller.stream,
        stream2Controller.stream,
      ],
    );
    totalStream.listen((event) {
      debugPrint('totalStream : $event');
    });
  }

  @override
  void dispose() {
    stream1Controller.close();
    stream2Controller.close();
    stream3Controller.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('async'),
        centerTitle: true,
      ),
      body: SafeArea(
        child: ListView(
          children: [
            ListTile(
              title: const Text('StreamGroup : stream1Controller'),
              onTap: () async {
                stream1Controller.sink.add(1);
              },
            ),
            ListTile(
              title: const Text('StreamGroup : stream2Controller'),
              onTap: () async {
                stream2Controller.sink.add(2);
              },
            ),
            ListTile(
              title: const Text('AsyncCache'),
              onTap: () async {
                debugPrint('AsyncCache ${DateTime.now().toLocal()}');
                final count = await countCache.fetch(() async {
                  await Future<void>.delayed(const Duration(seconds: 5));
                  return 10;
                });
                debugPrint(
                  'count: ${count.toString()}  ${DateTime.now().toLocal()}',
                );
              },
            ),
            ListTile(
              title: const Text('StreamQueue'),
              onTap: () async {
                final stream1 = Stream.fromFuture(getData(2));
                final stream2 = Stream.fromFuture(getData(4));
                final stream3 = Stream.fromFuture(getData(6));
                final streams = StreamGroup.merge([
                  stream1,
                  stream2,
                  stream3,
                ]);
                final data = StreamQueue(streams);
                final first = await data.next;
                debugPrint(first);
                final second = await data.next;
                debugPrint(second);
                final third = await data.next;
                debugPrint(third);
              },
            ),
          ],
        ),
      ),
    );
  }

  Future<String> getData(int duration) async {
    await Future<void>.delayed(Duration(seconds: duration)); //Mock delay
    return 'This a test data for duration $duration';
  }
}

結果

flutter: totalStream : 1
flutter: totalStream : 2
flutter: AsyncCache 2022-09-23 21:41:30.902709
flutter: This a test data for duration 2
flutter: count: 10  2022-09-23 21:41:35.910736
flutter: This a test data for duration 4
flutter: This a test data for duration 6

動画

公式リファレンス

async | Dart Package
Utility functions and classes related to the 'dart:async' library.

#84 url_launcher

url_launcherとは

ウェブページやメール送信画面、電話番号等の外部URLへ画面遷移する機能をもったパッケージです。

サンプルコード

import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher_string.dart';

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

  String get url => 'https://flutter.dev/';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('url_launcher'),
        centerTitle: true,
      ),
      body: SafeArea(
        child: ListView(
          children: [
            ListTile(
              title: const Text('アプリ内ブラウザで開く'),
              onTap: () async {
                if (!await canLaunchUrlString(url)) {
                  return;
                }
                await launchUrlString(
                  url,
                  mode: LaunchMode.inAppWebView,
                );
              },
            ),
            ListTile(
              title: const Text('外部ブラウザで開く'),
              onTap: () async {
                if (!await canLaunchUrlString(url)) {
                  return;
                }
                await launchUrlString(
                  url,
                  mode: LaunchMode.externalApplication,
                );
              },
            ),
            ListTile(
              title: const Text('不正なURLブラウザは開かない'),
              onTap: () async {
                const dummyUrl = 'dummy';
                if (!await canLaunchUrlString(dummyUrl)) {
                  debugPrint('不正なURL');
                  return;
                }
                await launchUrlString(dummyUrl);
              },
            ),
          ],
        ),
      ),
    );
  }
}

結果

動画

公式リファレンス

url_launcher | Flutter package
Flutter plugin for launching a URL. Supports web, phone, SMS, and email schemes.

さいごに

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

おすすめ参考書

リンク

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

コメント

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