🔖

flutter_screenutilライブラリを使用し複数デバイス(解像度)対応

2022/02/11に公開

flutter_screenutilライブラリを使用し、複数デバイスに対応する方法です。
これでデバイスの解像度が変わっても、同じような見た目を維持できます。

手順概要

1.ライブラリを追加する
2.ルートのウィジェットにscreen_utilの設定を行う
3.対象画面のウィジェットにscreen_utilを使えるようにし、wやhでサイズを指定する。

手順詳細

1.ライブラリを追加する

flutter pub add flutter_screenutil

2.ルートのウィジェットにscreen_utilの設定を行う

ScreenUtilInitメソッドを用いて、designSizeでターゲットのデバイスサイズを指定する。
サンプルコード

main.dart

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(
    //Riverpodの設定
    ProviderScope(
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    //複数解像度対応
    return ScreenUtilInit(
        //ターゲットデバイスの設定
        designSize: const Size(375, 812),
	//幅と高さの最小値に応じてテキストサイズを可変させるか
        minTextAdapt: true,
	//split screenに対応するかどうか?
        splitScreenMode: true,
        builder: () => const MaterialApp(
              home: Center(
                child: MessageList(),
              ),
            ));
  }
}

3.対象画面のウィジェットにscreen_utilを使えるようにし、wやhでサイズを指定する。

ScreenUtil.init()でscreen_utilを使えるようにします。
wやhを使うときにこれがないとMediaQueryがないとエラーになります。
ScreenUtil.init()後に
幅基準で可変させたい時はサイズの後に.wを
高さ基準で可変させたい時はサイズの後に.hをします。


EdgeInsets.fromLTRB(21.w, 13.h, 13.w, 0)

サンプルコードの抜粋

message_list_page.dart
// メッセージ一覧のプロバイダー(Riverpod)
final messageListProvider =
    StateNotifierProvider<MessageListNotifier, MessageListState>(
  (ref) => MessageListNotifier(ref.read),
);

//Riverpodを使うのでConsumerWidgetを継承する
class MessageList extends ConsumerWidget {
  const MessageList({Key? key}) : super(key: key);

  //Riverpodで使用するrefを追加する。
  
  Widget build(BuildContext context, WidgetRef ref) {
    final messageListState = ref.watch(messageListProvider);
    final messageListNotifier = ref.watch(messageListProvider.notifier);

    //build後一度だけデータを読み込む
    WidgetsBinding.instance!.addPostFrameCallback((_) {
      if (messageListState.isLoading) {
        messageListNotifier.setInit();
      }
    });

    //複数デバイス対応 
    ScreenUtil.init(
      BoxConstraints(
        maxWidth: MediaQuery.of(context).size.width,
        maxHeight: MediaQuery.of(context).size.heigh,
      ),
      //ターゲットデバイスの解像度を設定
      designSize: Size(375, 812),
      context: context,
      minTextAdapt: true,
      orientation: Orientation.portrait
    );

    if (!messageListState.isLoading) {
      return Scaffold(
          appBar: AppBar(
              backgroundColor: Colors.white,
              title: const Text('メッセージ',
                  textAlign: TextAlign.left,
                  style: TextStyle(
                    color: Colors.black,
                  ))),
          body: ListView.builder(
            itemCount: messageListState.messageList.length,
            itemBuilder: (BuildContext context, int index) {
              return Row(children: <Widget>[
                Container(
		    //w,hをつけて可変設定
                    margin: EdgeInsets.fromLTRB(21.w, 13.h, 13.w, 0),
                    height: 100.h,
                    width: 48.w,
  ・・・・

参考サイト

公式サイト
https://github.com/OpenFlutter/flutter_screenutil

Discussion