🐷

[Flutter]Indicatorについての個人的まとめ

2022/07/06に公開

FlutterのIndicatorとは

Indicator(プログレスバー)とは?:「Loading.../通信中...的な表示のこと」

FlutterのIndicatorの中には主に

  1. CircularProgressIndicator()→円型のインジケータ 公式

  1. LinearProgressIndicator()→直線型のインジケータ 公式

がある


また、特定の値を取得するかしないかの違いとして

  1. Determinate("(値が)確定した")

  1. Indeterminate("(値が)不確定な")

の2種類の分類が上記のCircular/Linearインジケータの中に存在している。以下公式

  • Determinateインジケーターには、各時点で特定の値があり、値は0.0から1.0まで単調に増加する必要があります。この時点で、インジケーターは完了します。確定的な進行状況インジケーターを作成するには、0.0から1.0までのnull以外の値を使用します。
  • Indeterminateインジケーターは、各時点で特定の値を持っておらず、代わりに、進行状況がどれだけ残っているかを示すことなく、進行状況を示します。不確定な進行状況インジケーターを作成するには、null値を使用します。

つまり、

  • Circular/Linearインジケータ(クラス)

の中に

  • Determinate/Indeterminate(value.による引数を持たせるかどうか)

の分類がある。

ってこと

使い所

  • 時間のかかる処理などを行うとき、ユーザーに処理の完了を待たせることになるその時に表示する
    ユーザーにも何らかの処理が確実に行われていることが分かりUXの向上につながる

使い方

サンプルコード:

1. LinearProgressIndicator()

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

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  static const String _title = 'Flutter Code Sample';

  
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: _title,
      home: MyStatefulWidget(),
    );
  }
}

class MyStatefulWidget extends StatefulWidget {
  //通信状態によってインジケータの描画が変わるのでStatefull!
  const MyStatefulWidget({Key? key}) : super(key: key);

  
  State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}

/// AnimationControllers can be created with `vsync: this` because of TickerProviderStateMixin.
class _MyStatefulWidgetState extends State<MyStatefulWidget>
    with TickerProviderStateMixin {
  late AnimationController controller;

  
  void initState() {// 親クラスのvoid initState() メソッドをオーバーライド
  // initState() に `controller` オブジェクトを設置
    controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 5),
    )..addListener(() {
        setState(() {});
      });
    controller.repeat(reverse: true);
    super.initState();
  }

  
  void dispose() {// 親クラスのvoid void dispose()メソッドをオーバーライド
    controller.dispose();
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.all(20.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[
            const Text(
              'Linear progress indicator with a fixed color',
              style: TextStyle(fontSize: 20),
            ),
            LinearProgressIndicator(
              value: controller.value, //null以外で何らかの値
              semanticsLabel: 'Linear progress indicator', //インジケータのラベル名 
            ),
          ],
        ),
      ),
    );
  }
}

Point (重要なのはコード下半分)

  • LinearProgressIndicator()でインジケータ表示
  • value: controller.value, で値を渡せる(今回はDeterminateな例)

2. CircularProgressIndicator()

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

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  static const String _title = 'Flutter Code Sample';

  
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: _title,
      home: MyStatefulWidget(),
    );
  }
}

class MyStatefulWidget extends StatefulWidget {
  const MyStatefulWidget({Key? key}) : super(key: key);

  
  State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}

/// AnimationControllers can be created with `vsync: this` because of TickerProviderStateMixin.
class _MyStatefulWidgetState extends State<MyStatefulWidget>
    with TickerProviderStateMixin {
  late AnimationController controller;

  
  void initState() {
    controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 5),
    )..addListener(() {
        setState(() {});
      });
    controller.repeat(reverse: true);
    super.initState();
  }

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

  
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.all(20.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[
            Text(
              'Linear progress indicator with a fixed color',
              style: Theme.of(context).textTheme.headline6,
            ),
            CircularProgressIndicator(
              value: controller.value,
              semanticsLabel: 'Linear progress indicator',
            ),
          ],
        ),
      ),
    );
  }
}

Point (重要なのはコード下半分)

  • CircularProgressIndicator()でインジケータ表示
  • value: controller.value, で値を渡せる(今回はDeterminateな例)

[Other Point]

プログレスインジケータは value プロパティを持っていて、これに 0.0 から 1.0 までの値をセットすることによって、進捗割合を明確に表示できます。

一方、Indeterminate の方は、進行状況が不明瞭の場合に使います。作業量が明確にわからず、動いていることは動いているんだけど、今どの程度か示せないような場合に使います。

Indeterminateの場合は、単にウィジェットを表示すれば、グルグルといい塩梅に回ったりしてくれるだけです。

value をセットすることもなく、ただ置けばいいだけなので簡単ですね。

  • RefreshIndicator について

RefreshIndicatortという「スワイプして更新」イディオムをサポートするウィジェット。
らしいがこれはまた次回復習しようと思う

以上です。間違えが見つかり次第、或いは知識がアップデートされ次第改訂していきます。🙏

GitHubで編集を提案

Discussion