🔖
flutter_screenutilライブラリを使用し複数デバイス(解像度)対応
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,
・・・・
参考サイト
公式サイト
Discussion