🍆

Flutter MediaQuery

2024/10/05に公開

👤対象者

  • MediaQueryについて知りたい
  • なんとなく使ってる
  • 実は使いすぎないほうがいいらしい

記事の内容

Flutter公式の動画を皆がらMediaQueryについて学んでいきましょう。
https://www.youtube.com/watch?v=xVk1kPvkgAY

MediaQueryを使用してデバイスを使用するようにアプリを調整して構築しています。がアプリのパフォーマンスを犠牲にしていませんか?

MediaQueryオブジェクトには、現在のウィンドウサイズ、アクセシビリティ ナビゲーションが有効化どうか現在のフォント倍率など、アプリが実行されているメディアに関数有用な情報が含まれています。

MediaQueryはデータすべてのそのstaticメソッドを使用してアクセスできます。このメソッドはビルドコンテキストを取得しMediaQueryプロパティが変更されるたびに再構築をトリガーします。ウィジェットのbuildメソッド内でMediaQuery.of(context)を呼び出すと、データが変更されるたびにウィジェットが再構築され、ウィジェットが最新の値を持つことが保証されます。

かなりきれいですが、これには小さな問題があります。MediaQueryプロパティのいずれかが変更されると、ウィジェットが再構築されます。MediaQueryには20近くの異なるプロパティがあります。再構築の可能性はたくさんあります。

こちらの公式で確認できます

たとえば、モバイルデバィスで仮想キーボードを開いたり閉じたりすると、MediaQueryのビューインセットプロパティが変更されます。ウィジェットがview insetsプロパティを気にしない場合でも、MediaQuery.ofを呼び出すと、キーボードアニメーションの再生中にすべてのフレームを再構築する必要があります。両方の長所を生かし、必要なデータが変更された場合にのみ再構築するには、MediaQuery.properyOfを使用します。MediaQueryのサイズプロパティを取得するにはMediaQuery.sizeOfを呼び出しアクセシビリティナビゲーションが有効化どうかを確認するにはMediaQuery.acces sibleNavigationOfを呼び出します。興味のあるプロパティ名を取得し、MediaQuery.properyOfを呼び出します。

これで関連するMediaQueryプロパティデータが変更された場合にのみウィジェットが再構築されるようになります。ウィジェットは不必要な再構築によってパフォーマンスを犠牲にすることなく、最新のMediaQueryデータを取得します。

example

import 'package:flutter/material.dart';

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

  
  Widget build(BuildContext context) {
    // サイズに関する最適化された使用
    final size = MediaQuery.sizeOf(context);
    final isLargeScreen = size.width > 600;

    // アクセシビリティに関する最適化された使用
    final isAccessibleNavigation = MediaQuery.accessibleNavigationOf(context);

    // キーボードに関する最適化された使用
    final bottomInset = MediaQuery.viewInsetsOf(context).bottom;
    final isKeyboardVisible = bottomInset > 0;

    // アニメーションに関する最適化された使用
    final disableAnimations = MediaQuery.disableAnimationsOf(context);

    return Scaffold(
      appBar: AppBar(
        title: const Text('最適化されたMediaQuery使用例'),
      ),
      body: Column(
        children: [
          Text(
            isLargeScreen ? '大画面デバイス' : '小画面デバイス',
            style: Theme.of(context).textTheme.titleLarge, // headline6 から titleLarge に変更
          ),
          Text(
            'アクセシブルナビゲーション: ${isAccessibleNavigation ? '有効' : '無効'}',
          ),
          Text(
            'キーボード: ${isKeyboardVisible ? '表示中' : '非表示'}',
          ),
          if (!disableAnimations)
            AnimatedContainer(
              duration: const Duration(seconds: 1),
              height: isKeyboardVisible ? 100 : 200,
              color: Colors.blue,
              child: const Center(child: Text('アニメーション対応コンテナ')),
            )
          else
            Container(
              height: 150,
              color: Colors.blue,
              child: const Center(child: Text('静的コンテナ')),
            ),
        ],
      ),
    );
  }
}

感想

使い方の参考例が紹介されたサイトのリンクを記載しておきます。過去に書いたことがある記事もリンク貼って起きます。参考までに
https://flutter.salon/widget/mediaquery/
https://zenn.dev/joo_hashi/articles/57865195ab4e42

Discussion