Menu
CoddyTech

読み込み中のスピナー

CoddyのFlutterジャーニー「データとネットワーク」セクションの一部。レッスン 5/27。

画面が動かないまま2秒間見つめるのは長く感じます。回転する円は、アプリが処理中であることをユーザーに伝えます。Flutterでは、これがCircularProgressIndicatorです。

const CircularProgressIndicator()

動作させるために必要なものはありません。画面に置けば回転します。データを取得している間だけ表示するのが役目です。状態にあるboolで制御できます。

bool loading = false;

// await の前: loading = true
// await の後: loading = false

loading ? const CircularProgressIndicator() : Text(message)

awaitする前にsetStateでloadingをtrueに設定し、答えを表示するsetStateでfalseに戻します。

challenge icon

チャレンジ

簡単

Loading...のテキストをスピナーに置き換えます。

  • 状態にbool loading = false;を追加します
  • fetchの前にtrueに設定し、メッセージが届いたらfalseに戻します
  • loadingがtrueの間、メッセージの代わりにCircularProgressIndicatorを表示します

自分で試してみよう

import 'package:flutter/material.dart';

import 'api.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: MessageScreen(),
    );
  }
}

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

  @override
  State<MessageScreen> createState() => _MessageScreenState();
}

class _MessageScreenState extends State<MessageScreen> {
  String message = 'No message yet';

  Future<void> loadMessage() async {
    setState(() {
      message = 'Loading...';
    });
    final text = await fetch('/message');
    setState(() {
      message = text;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Text(message, style: const TextStyle(fontSize: 24)),
            const SizedBox(height: 24),
            ElevatedButton(onPressed: loadMessage, child: const Text('Load message')),
          ],
        ),
      ),
    );
  }
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

データとネットワークのすべてのレッスン

自分で練習してみよう: Flutterオンラインコンパイラ