2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

React100本ノックをFlutterでやってみた #02 Counter

Last updated at Posted at 2023-12-02

はじめに

前回に引き続,React100本ノックをFlutterで実装していきます。
オリジナルはこちらです。
https://qiita.com/Sicut_study/items/82059f9cbb5b2996e5b3

元記事の方では

React, TypeScriptを使う

というルールがありますが、こちらを無視する形となりますが、ご容赦ください🙇‍♂️

実装

完成品

Simulator Screenshot - iPhone 15 Pro Max - 2023-12-02 at 22.49.13.png

実装

以下のように実装を行いました。
状態管理ではriverpodを利用しています。

ProviderScope追加

riverpodを使うのでProviderScopeで覆う必要がありました。

main.dart
void main() {
  runApp(const ProviderScope(child: MyApp()));
}

counterコンポーネントの作成

providerの作成

flutter_counter.dart
final counterProvider = StateProvider<int>((ref) => 0);

component本体の作成

数値を表示するボックスとそこに表示されるボタンをそれぞれ分けています。
まずはFlutterCounterの部分です。

main.dart
class FlutterCounter extends ConsumerWidget {
  const FlutterCounter({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return Container(
      width: 200,
      height: 300,
      decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(
            16,
          ),
          border: Border.all(
            width: 1,
            color: Colors.grey.shade400,
          ),
          color: Colors.white),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
          Padding(
            padding: const EdgeInsets.symmetric(
              vertical: 32,
            ),
            child: Text(
              'Flutter Counter',
              style: TextStyle(
                fontSize: 16,
                color: Colors.grey.shade700,
              ),
            ),
          ),
          Text(
            ref.watch(counterProvider).toString(),
            style: TextStyle(
              fontSize: 56,
              color: Colors.pink.shade700,
            ),
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              _OperationButton(
                iconData: Icons.add,
                onPressed: () {
                  ref.read(counterProvider.notifier).state += 1;
                },
              ),
              const SizedBox(
                width: 30,
              ),
              _OperationButton(
                iconData: Icons.remove,
                onPressed: () {
                  ref.read(counterProvider.notifier).state -= 1;
                },
                backgroundColor: Colors.white,
                borderColor: Colors.pink,
                opeCodeColor: Colors.pink,
              )
            ],
          ),
        ],
      ),
    );
  }
}

ボタンの部分はこのようにしています。背景色、アイコンの色、枠線の色を指定できます。

flutter_counter.dart
class _OperationButton extends ConsumerWidget {
  const _OperationButton({
    required this.iconData,
    required this.onPressed,
    this.backgroundColor = Colors.pink,
    this.opeCodeColor = Colors.white,
    this.borderColor = Colors.pink,
  });
  final IconData? iconData;
  final void Function()? onPressed;
  final Color backgroundColor;
  final Color opeCodeColor;
  final Color borderColor;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return TextButton(
      style: ElevatedButton.styleFrom(
          shape: const CircleBorder(),
          backgroundColor: backgroundColor,
          side: BorderSide(
            color: borderColor,
          )),
      onPressed: onPressed,
      child: Icon(
        iconData,
        color: opeCodeColor,
        size: 42,
      ),
    );
  }
}

これで実装できました!あとはmain.dartからFlutterCounterを呼び出してあげましょう!

main.dart
class MyApp extends HookWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text(
            'FlutterCounter',
            style: TextStyle(
              color: Colors.pink.shade900,
              fontSize: 24,
            ),
          ),
        ),
        body: ColoredBox(
          color: Colors.pink.shade100,
          child: const Center(
            child: FlutterCounter(),
          ),
        ),
      ),
    );
  }
}

さいごに

flutterで実装できる範囲(でかつ、自分の能力でできる範囲)で、react100本ノックに追従していこうと思うのでよろしくお願いします!

コードや記事の内容について、何かご指摘やアドバイス等ありましたら、コメントや編集リクエスト等で教えて下さい!

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?