🍜
Flutter MediaQuery.removePaddingによってviewPaddingが0になる
Overlay
Widgetを使ってWidgetツリーを飛び越えて表示した時に、viewPadding
の値が想定と違い混乱することがありました。これはMediaQuery.removePadding
が適用されたWidgetツリーの内側と外側で、viewPadding
の値が異なることが原因でした。
この記事では、MediaQuery.removePadding
の使い方と、viewPaddingの値が変わる理由を解説します。
MediaQuery.removePadding
MediaQuery.removePadding
メソッドは、指定したパディングを0に置き換えたMediaQueryData
を作成します。
これは、AppBar
やSafeArea
といったWidgetの内部で使われています。
AppBar
は、removeBottom: true
によって、画面下のパディングが0に指定されています。
SafeArea
は、パラメータで指定した位置のパディングが0に指定されていますね。
SafeArea
のパディングを削除するパラメータはデフォルトでtrueです。
例えば、以下のコードだと画面の左・右・上のパディングが0になります。
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return SafeArea(top: false, child: Text('テスト'));
}
}
MediaQuery.viewPaddingの値が変わる
removePaddingによってviewPaddingの値が変わることを見てみましょう。
以下はAppBar
とMediaQuery.removePadding
を順番に適用したコードです。
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: _ViewPaddingWidget()));
}
class _ViewPaddingWidget extends StatelessWidget {
Widget build(BuildContext contextX) {
return Scaffold(
// removeTop: true,
appBar: AppBar(title: Text('AppBar')),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// EdgeInsets.fromLTRB(left, top, right, bottom)
Text('contextX: ${MediaQuery.viewPaddingOf(contextX)}'),
Builder(
builder:
(contextY) => Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('contextY: ${MediaQuery.viewPaddingOf(contextY)}'),
MediaQuery.removePadding(
context: contextY,
removeBottom: true,
child: Builder(
builder:
(contextZ) => Text(
'contextZ: ${MediaQuery.viewPaddingOf(contextZ)}',
),
),
),
],
),
),
],
),
);
}
}
このコードを実行すると、contextX、contextY、contextZの順にパディングが無くなっていることが確認できます。
以下はiPhone Xsで実行した結果です。上下にviewPadding
が設定された後、上パディングがなくなり、下パディングがなくなっています。
まとめ
-
MediaQuery.removePadding
によって、MediaQuery.viewPadding
の値が変わる -
MediaQuery.removePadding
は、AppBar
やSafeArea
の内部で使われている -
MediaQuery.removePadding
は、指定したパディングを0に置き換えたMediaQueryData
を作成する
参考文献
Discussion