Skip to content

Instantly share code, notes, and snippets.

@craiglabenz
Last active August 12, 2024 16:51
Show Gist options
  • Save craiglabenz/b0d016329a88863670d9e9a8f0789245 to your computer and use it in GitHub Desktop.
Save craiglabenz/b0d016329a88863670d9e9a8f0789245 to your computer and use it in GitHub Desktop.

Revisions

  1. craiglabenz revised this gist Aug 12, 2024. 1 changed file with 9 additions and 5 deletions.
    14 changes: 9 additions & 5 deletions mediaquerydata-demo.dart
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,7 @@
    // Copyright 2013 The Flutter Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.

    import 'package:flutter/material.dart';

    void main() {
    @@ -19,7 +23,7 @@ class MyApp extends StatelessWidget {
    home: Theme(
    data: originalTheme.copyWith(
    textTheme: originalTheme.textTheme.copyWith(
    bodyText2: originalTheme.textTheme.bodyText2!.copyWith(
    bodyMedium: originalTheme.textTheme.bodyMedium!.copyWith(
    fontSize: 16,
    ),
    ),
    @@ -95,7 +99,7 @@ class _FullStackState extends State<FullStack> {
    Flexible(
    child: LayoutBuilder(
    builder: (BuildContext context, BoxConstraints constraints) {
    final keyboardTextStyle = Theme.of(context).textTheme.headline2;
    final keyboardTextStyle = Theme.of(context).textTheme.displayMedium;
    late final EdgeInsets viewPadding;
    late final EdgeInsets padding;

    @@ -161,7 +165,7 @@ class _FullStackState extends State<FullStack> {
    children: <Widget>[
    Text(
    'Fake keyboard is ${_fakeKeyboard ? "REVEALED" : "HIDDEN"}',
    style: Theme.of(context).textTheme.headline5,
    style: Theme.of(context).textTheme.headlineSmall,
    ),
    Switch(
    value: _fakeKeyboard,
    @@ -173,7 +177,7 @@ class _FullStackState extends State<FullStack> {
    ),
    Text(
    'SafeArea is ${_safeArea ? "ON" : "OFF"}',
    style: Theme.of(context).textTheme.headline5,
    style: Theme.of(context).textTheme.headlineSmall,
    ),
    Switch(
    value: _safeArea,
    @@ -325,4 +329,4 @@ class MediaQueryRightInfo extends StatelessWidget {
    ],
    );
    }
    }
    }
  2. craiglabenz revised this gist Jan 11, 2022. 1 changed file with 0 additions and 9 deletions.
    9 changes: 0 additions & 9 deletions mediaquerydata-demo.dart
    Original file line number Diff line number Diff line change
    @@ -326,12 +326,3 @@ class MediaQueryRightInfo extends StatelessWidget {
    );
    }
    }

    class RedBlock extends StatelessWidget {
    const RedBlock({Key? key}) : super(key: key);

    @override
    Widget build(BuildContext context) {
    return Container(height: 50, width: 100, color: Colors.red);
    }
    }
  3. craiglabenz revised this gist Jan 11, 2022. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions mediaquerydata-demo.dart
    Original file line number Diff line number Diff line change
    @@ -188,7 +188,7 @@ class _FullStackState extends State<FullStack> {
    ),
    Positioned(
    top: positioning.top,
    left: mq.size.width / 2.1,
    left: mq.size.width / 2.2,
    child: MediaQueryTopInfo(mediaQueryData: mq),
    ),
    Positioned(
    @@ -203,7 +203,7 @@ class _FullStackState extends State<FullStack> {
    ),
    Positioned(
    bottom: positioning.bottom + mq.viewInsets.bottom,
    left: mq.size.width / 2.1,
    left: mq.size.width / 2.2,
    child: MediaQueryBottomInfo(mediaQueryData: mq),
    ),
    _fakeKeyboard
  4. craiglabenz revised this gist Jan 11, 2022. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions mediaquerydata-demo.dart
    Original file line number Diff line number Diff line change
    @@ -111,13 +111,13 @@ class _FullStackState extends State<FullStack> {
    positioning = const EdgeInsets.symmetric(vertical: 20);
    } else if (!_safeArea && _fakeKeyboard) {
    viewPadding = const EdgeInsets.symmetric(vertical: 20);
    padding = const EdgeInsets.fromLTRB(20, 20, 20, 0);
    positioning = const EdgeInsets.symmetric(vertical: 20);
    padding = const EdgeInsets.fromLTRB(0, 20, 0, 0);
    positioning = EdgeInsets.zero;
    } else {
    // Have both
    viewPadding = const EdgeInsets.fromLTRB(0, 0, 0, 20);
    padding = EdgeInsets.zero;
    positioning = const EdgeInsets.symmetric(vertical: 20);
    positioning = const EdgeInsets.only(top: 20);
    }

    final MediaQueryData mq = MediaQuery.of(context).copyWith(
  5. craiglabenz revised this gist Jan 11, 2022. 2 changed files with 337 additions and 304 deletions.
    304 changes: 0 additions & 304 deletions main.dart
    Original file line number Diff line number Diff line change
    @@ -1,304 +0,0 @@
    import 'package:flutter/material.dart';

    void main() {
    runApp(const MyApp());
    }

    class MyApp extends StatelessWidget {
    const MyApp({Key? key}) : super(key: key);

    // This widget is the root of your application.
    @override
    Widget build(BuildContext context) {
    final originalTheme = Theme.of(context);
    return MaterialApp(
    title: 'Flutter Demo',
    theme: ThemeData(
    primarySwatch: Colors.blue,
    ),
    home: Theme(
    data: originalTheme.copyWith(
    textTheme: originalTheme.textTheme.copyWith(
    bodyText2: originalTheme.textTheme.bodyText2!.copyWith(
    fontSize: 16,
    ),
    ),
    ),
    child: const MyHomePage(title: 'Flutter Demo Home Page')),
    );
    }
    }

    class MyHomePage extends StatefulWidget {
    const MyHomePage({Key? key, required this.title}) : super(key: key);

    final String title;

    @override
    State<MyHomePage> createState() => _MyHomePageState();
    }

    class _MyHomePageState extends State<MyHomePage> {
    @override
    Widget build(BuildContext context) {
    return Scaffold(
    resizeToAvoidBottomInset: false,
    body: Stack(
    children: const <Widget>[
    FullStack(),
    ],
    ),
    );
    }
    }

    class FullStack extends StatefulWidget {
    const FullStack({Key? key}) : super(key: key);

    @override
    State<FullStack> createState() => _FullStackState();
    }

    class _FullStackState extends State<FullStack> {
    bool _safeArea = false;
    bool _fakeKeyboard = false;

    final focusNode = FocusNode();

    @override
    void initState() {
    super.initState();
    focusNode.requestFocus();
    }

    @override
    Widget build(BuildContext context) {
    return Column(
    children: <Widget>[
    // Uncomment this if you want to summon the real keyboard on mobile.
    // const SizedBox(height: 100),
    // Padding(
    // padding: const EdgeInsets.symmetric(horizontal: 12),
    // child: Row(
    // children: <Widget>[
    // Expanded(
    // child: TextField(
    // decoration: InputDecoration(
    // filled: true,
    // fillColor: Colors.grey[300],
    // ),
    // ),
    // ),
    // ],
    // ),
    // ),
    Flexible(
    child: LayoutBuilder(
    builder: (BuildContext context, BoxConstraints constraints) {
    final keyboardTextStyle = Theme.of(context).textTheme.headline2;
    late final EdgeInsets viewPadding;
    late final EdgeInsets padding;

    if (!_safeArea && !_fakeKeyboard) {
    viewPadding = const EdgeInsets.symmetric(vertical: 20);
    padding = const EdgeInsets.symmetric(vertical: 20);
    } else if (_safeArea && !_fakeKeyboard) {
    viewPadding = EdgeInsets.zero;
    padding = EdgeInsets.zero;
    } else if (!_safeArea && _fakeKeyboard) {
    viewPadding = const EdgeInsets.symmetric(vertical: 20);
    padding = const EdgeInsets.fromLTRB(20, 20, 20, 0);
    } else {
    // Have both
    viewPadding = const EdgeInsets.fromLTRB(0, 0, 0, 20);
    padding = EdgeInsets.zero;
    }

    final MediaQueryData mq = MediaQuery.of(context).copyWith(
    padding: padding,
    viewPadding: viewPadding,
    viewInsets: EdgeInsets.fromLTRB(
    0,
    0,
    0,
    _fakeKeyboard ? 300 : 0,
    ),
    );
    return MediaQuery(
    data: mq,
    // data: MediaQuery.of(context),
    child: Stack(
    children: <Widget>[
    Positioned(
    bottom: mq.size.height / 2,
    left: mq.size.width / 2.5,
    child: Column(
    children: <Widget>[
    Text(
    'Fake keyboard is ${_fakeKeyboard ? "REVEALED" : "HIDDEN"}',
    style: Theme.of(context).textTheme.headline5,
    ),
    Switch(
    value: _fakeKeyboard,
    onChanged: (value) {
    setState(() {
    _fakeKeyboard = value;
    });
    },
    ),
    Text(
    'SafeArea is ${_safeArea ? "ON" : "OFF"}',
    style: Theme.of(context).textTheme.headline5,
    ),
    Switch(
    value: _safeArea,
    onChanged: (value) {
    setState(() {
    _safeArea = value;
    });
    },
    ),
    ],
    ),
    ),
    Positioned(
    top: mq.padding.top,
    left: MediaQuery.of(context).size.width / 2.1,
    child: const MediaQueryTopInfo(),
    ),
    Positioned(
    top: MediaQuery.of(context).size.height / 2.5 -
    mq.viewInsets.bottom / 2,
    left: mq.padding.left,
    child: const MediaQueryLeftInfo(),
    ),
    Positioned(
    top: MediaQuery.of(context).size.height / 2.5 -
    mq.viewInsets.bottom / 2,
    right: mq.padding.right,
    child: const MediaQueryRightInfo(),
    ),
    Positioned(
    bottom: mq.viewInsets.bottom,
    left: MediaQuery.of(context).size.width / 2.1,
    child: const MediaQueryBottomInfo(),
    ),
    _fakeKeyboard
    ? Positioned(
    bottom: 0,
    width: mq.size.width,
    height: 300,
    child: Container(
    color: Colors.grey[300],
    child: Row(
    mainAxisAlignment:
    MainAxisAlignment.spaceEvenly,
    children: <Widget>[
    Text('K', style: keyboardTextStyle),
    Text('E', style: keyboardTextStyle),
    Text('Y', style: keyboardTextStyle),
    Text('B', style: keyboardTextStyle),
    Text('O', style: keyboardTextStyle),
    Text('A', style: keyboardTextStyle),
    Text('R', style: keyboardTextStyle),
    Text('D', style: keyboardTextStyle),
    ],
    ),
    ),
    )
    : Container()
    ],
    ),
    );
    },
    ),
    )
    ],
    );
    }
    }

    class MediaQueryBottomInfo extends StatelessWidget {
    const MediaQueryBottomInfo({Key? key}) : super(key: key);

    @override
    Widget build(BuildContext context) {
    final viewInsets = MediaQuery.of(context).viewInsets;
    final viewPadding = MediaQuery.of(context).viewPadding;
    final padding = MediaQuery.of(context).padding;
    return Column(
    children: <Widget>[
    const Text('BOTTOM'),
    Text('Padding: ${padding.bottom}'),
    Text('ViewPadding: ${viewPadding.bottom}'),
    Text('ViewInsets: ${viewInsets.bottom}'),
    ],
    );
    }
    }

    class MediaQueryTopInfo extends StatelessWidget {
    const MediaQueryTopInfo({Key? key}) : super(key: key);

    @override
    Widget build(BuildContext context) {
    final viewInsets = MediaQuery.of(context).viewInsets;
    final viewPadding = MediaQuery.of(context).viewPadding;
    final padding = MediaQuery.of(context).padding;
    return Column(
    children: <Widget>[
    const Text('TOP'),
    Text('Padding: ${padding.top}'),
    Text('ViewPadding: ${viewPadding.top}'),
    Text('ViewInsets: ${viewInsets.top}'),
    ],
    );
    }
    }

    class MediaQueryLeftInfo extends StatelessWidget {
    const MediaQueryLeftInfo({Key? key}) : super(key: key);

    @override
    Widget build(BuildContext context) {
    final viewInsets = MediaQuery.of(context).viewInsets;
    final viewPadding = MediaQuery.of(context).viewPadding;
    final padding = MediaQuery.of(context).padding;
    return Column(
    children: <Widget>[
    const Text('LEFT'),
    Text('Padding: ${padding.left}'),
    Text('ViewPadding: ${viewPadding.left}'),
    Text('ViewInsets: ${viewInsets.left}'),
    ],
    );
    }
    }

    class MediaQueryRightInfo extends StatelessWidget {
    const MediaQueryRightInfo({Key? key}) : super(key: key);

    @override
    Widget build(BuildContext context) {
    final viewInsets = MediaQuery.of(context).viewInsets;
    final viewPadding = MediaQuery.of(context).viewPadding;
    final padding = MediaQuery.of(context).padding;
    return Column(
    children: <Widget>[
    const Text('RIGHT'),
    Text('Padding: ${padding.right}'),
    Text('ViewPadding: ${viewPadding.right}'),
    Text('ViewInsets: ${viewInsets.right}'),
    ],
    );
    }
    }

    class RedBlock extends StatelessWidget {
    const RedBlock({Key? key}) : super(key: key);

    @override
    Widget build(BuildContext context) {
    return Container(height: 50, width: 100, color: Colors.red);
    }
    }
    337 changes: 337 additions & 0 deletions mediaquerydata-demo.dart
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,337 @@
    import 'package:flutter/material.dart';

    void main() {
    runApp(const MyApp());
    }

    class MyApp extends StatelessWidget {
    const MyApp({Key? key}) : super(key: key);

    // This widget is the root of your application.
    @override
    Widget build(BuildContext context) {
    final originalTheme = Theme.of(context);
    return MaterialApp(
    title: 'Flutter Demo',
    theme: ThemeData(
    primarySwatch: Colors.blue,
    ),
    home: Theme(
    data: originalTheme.copyWith(
    textTheme: originalTheme.textTheme.copyWith(
    bodyText2: originalTheme.textTheme.bodyText2!.copyWith(
    fontSize: 16,
    ),
    ),
    ),
    child: const MyHomePage(title: 'Flutter Demo Home Page')),
    );
    }
    }

    class MyHomePage extends StatefulWidget {
    const MyHomePage({Key? key, required this.title}) : super(key: key);

    final String title;

    @override
    State<MyHomePage> createState() => _MyHomePageState();
    }

    class _MyHomePageState extends State<MyHomePage> {
    @override
    Widget build(BuildContext context) {
    return Scaffold(
    resizeToAvoidBottomInset: false,
    body: Stack(
    children: const <Widget>[
    FullStack(),
    ],
    ),
    );
    }
    }

    class FullStack extends StatefulWidget {
    const FullStack({Key? key}) : super(key: key);

    @override
    State<FullStack> createState() => _FullStackState();
    }

    class _FullStackState extends State<FullStack> {
    bool _safeArea = true;
    bool _fakeKeyboard = false;

    final focusNode = FocusNode();

    @override
    void initState() {
    super.initState();
    focusNode.requestFocus();
    }

    @override
    Widget build(BuildContext context) {
    return Column(
    children: <Widget>[
    // Uncomment this if you want to summon the real keyboard on mobile.
    // const SizedBox(height: 100),
    // Padding(
    // padding: const EdgeInsets.symmetric(horizontal: 12),
    // child: Row(
    // children: <Widget>[
    // Expanded(
    // child: TextField(
    // decoration: InputDecoration(
    // filled: true,
    // fillColor: Colors.grey[300],
    // ),
    // ),
    // ),
    // ],
    // ),
    // ),
    Flexible(
    child: LayoutBuilder(
    builder: (BuildContext context, BoxConstraints constraints) {
    final keyboardTextStyle = Theme.of(context).textTheme.headline2;
    late final EdgeInsets viewPadding;
    late final EdgeInsets padding;

    late final EdgeInsets positioning;

    if (!_safeArea && !_fakeKeyboard) {
    viewPadding = const EdgeInsets.symmetric(vertical: 20);
    padding = const EdgeInsets.symmetric(vertical: 20);
    positioning = EdgeInsets.zero;
    } else if (_safeArea && !_fakeKeyboard) {
    viewPadding = EdgeInsets.zero;
    padding = EdgeInsets.zero;
    positioning = const EdgeInsets.symmetric(vertical: 20);
    } else if (!_safeArea && _fakeKeyboard) {
    viewPadding = const EdgeInsets.symmetric(vertical: 20);
    padding = const EdgeInsets.fromLTRB(20, 20, 20, 0);
    positioning = const EdgeInsets.symmetric(vertical: 20);
    } else {
    // Have both
    viewPadding = const EdgeInsets.fromLTRB(0, 0, 0, 20);
    padding = EdgeInsets.zero;
    positioning = const EdgeInsets.symmetric(vertical: 20);
    }

    final MediaQueryData mq = MediaQuery.of(context).copyWith(
    padding: padding,
    viewPadding: viewPadding,
    viewInsets: EdgeInsets.fromLTRB(
    0,
    0,
    0,
    _fakeKeyboard ? 300 : 0,
    ),
    );
    return Stack(
    children: <Widget>[
    // Top notch (heh)
    Positioned(
    left: mq.size.width / 4,
    top: 10,
    child: Container(
    height: 5,
    width: mq.size.width / 2,
    color: Colors.grey[800],
    ),
    ),
    // Bottom notch
    !_fakeKeyboard
    ? Positioned(
    left: mq.size.width / 4,
    bottom: 10,
    child: Container(
    height: 5,
    width: mq.size.width / 2,
    color: Colors.grey[800],
    ),
    )
    : Container(),
    Positioned(
    bottom: mq.size.height / 2,
    left: mq.size.width / 2.5,
    child: Column(
    children: <Widget>[
    Text(
    'Fake keyboard is ${_fakeKeyboard ? "REVEALED" : "HIDDEN"}',
    style: Theme.of(context).textTheme.headline5,
    ),
    Switch(
    value: _fakeKeyboard,
    onChanged: (value) {
    setState(() {
    _fakeKeyboard = value;
    });
    },
    ),
    Text(
    'SafeArea is ${_safeArea ? "ON" : "OFF"}',
    style: Theme.of(context).textTheme.headline5,
    ),
    Switch(
    value: _safeArea,
    onChanged: (value) {
    setState(() {
    _safeArea = value;
    });
    },
    ),
    ],
    ),
    ),
    Positioned(
    top: positioning.top,
    left: mq.size.width / 2.1,
    child: MediaQueryTopInfo(mediaQueryData: mq),
    ),
    Positioned(
    top: mq.size.height / 2.5 - mq.viewInsets.bottom / 2,
    left: positioning.left,
    child: MediaQueryLeftInfo(mediaQueryData: mq),
    ),
    Positioned(
    top: mq.size.height / 2.5 - mq.viewInsets.bottom / 2,
    right: positioning.right,
    child: MediaQueryRightInfo(mediaQueryData: mq),
    ),
    Positioned(
    bottom: positioning.bottom + mq.viewInsets.bottom,
    left: mq.size.width / 2.1,
    child: MediaQueryBottomInfo(mediaQueryData: mq),
    ),
    _fakeKeyboard
    ? Positioned(
    bottom: 0,
    width: mq.size.width,
    height: 300,
    child: Container(
    color: Colors.grey[300],
    child: Row(
    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
    children: <Widget>[
    Text('K', style: keyboardTextStyle),
    Text('E', style: keyboardTextStyle),
    Text('Y', style: keyboardTextStyle),
    Text('B', style: keyboardTextStyle),
    Text('O', style: keyboardTextStyle),
    Text('A', style: keyboardTextStyle),
    Text('R', style: keyboardTextStyle),
    Text('D', style: keyboardTextStyle),
    ],
    ),
    ),
    )
    : Container()
    ],
    );
    },
    ),
    )
    ],
    );
    }
    }

    class MediaQueryBottomInfo extends StatelessWidget {
    const MediaQueryBottomInfo({Key? key, required this.mediaQueryData})
    : super(key: key);

    final MediaQueryData mediaQueryData;

    @override
    Widget build(BuildContext context) {
    final viewInsets = mediaQueryData.viewInsets;
    final viewPadding = mediaQueryData.viewPadding;
    final padding = mediaQueryData.padding;
    return Column(
    children: <Widget>[
    const Text('BOTTOM'),
    Text('Padding: ${padding.bottom}'),
    Text('ViewPadding: ${viewPadding.bottom}'),
    Text('ViewInsets: ${viewInsets.bottom}'),
    ],
    );
    }
    }

    class MediaQueryTopInfo extends StatelessWidget {
    const MediaQueryTopInfo({Key? key, required this.mediaQueryData})
    : super(key: key);

    final MediaQueryData mediaQueryData;

    @override
    Widget build(BuildContext context) {
    final viewInsets = mediaQueryData.viewInsets;
    final viewPadding = mediaQueryData.viewPadding;
    final padding = mediaQueryData.padding;
    return Column(
    children: <Widget>[
    const Text('TOP'),
    Text('Padding: ${padding.top}'),
    Text('ViewPadding: ${viewPadding.top}'),
    Text('ViewInsets: ${viewInsets.top}'),
    ],
    );
    }
    }

    class MediaQueryLeftInfo extends StatelessWidget {
    const MediaQueryLeftInfo({Key? key, required this.mediaQueryData})
    : super(key: key);

    final MediaQueryData mediaQueryData;

    @override
    Widget build(BuildContext context) {
    final viewInsets = mediaQueryData.viewInsets;
    final viewPadding = mediaQueryData.viewPadding;
    final padding = mediaQueryData.padding;
    return Column(
    children: <Widget>[
    const Text('LEFT'),
    Text('Padding: ${padding.left}'),
    Text('ViewPadding: ${viewPadding.left}'),
    Text('ViewInsets: ${viewInsets.left}'),
    ],
    );
    }
    }

    class MediaQueryRightInfo extends StatelessWidget {
    const MediaQueryRightInfo({Key? key, required this.mediaQueryData})
    : super(key: key);

    final MediaQueryData mediaQueryData;

    @override
    Widget build(BuildContext context) {
    final viewInsets = mediaQueryData.viewInsets;
    final viewPadding = mediaQueryData.viewPadding;
    final padding = mediaQueryData.padding;
    return Column(
    children: <Widget>[
    const Text('RIGHT'),
    Text('Padding: ${padding.right}'),
    Text('ViewPadding: ${viewPadding.right}'),
    Text('ViewInsets: ${viewInsets.right}'),
    ],
    );
    }
    }

    class RedBlock extends StatelessWidget {
    const RedBlock({Key? key}) : super(key: key);

    @override
    Widget build(BuildContext context) {
    return Container(height: 50, width: 100, color: Colors.red);
    }
    }
  6. craiglabenz created this gist Jan 11, 2022.
    304 changes: 304 additions & 0 deletions main.dart
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,304 @@
    import 'package:flutter/material.dart';

    void main() {
    runApp(const MyApp());
    }

    class MyApp extends StatelessWidget {
    const MyApp({Key? key}) : super(key: key);

    // This widget is the root of your application.
    @override
    Widget build(BuildContext context) {
    final originalTheme = Theme.of(context);
    return MaterialApp(
    title: 'Flutter Demo',
    theme: ThemeData(
    primarySwatch: Colors.blue,
    ),
    home: Theme(
    data: originalTheme.copyWith(
    textTheme: originalTheme.textTheme.copyWith(
    bodyText2: originalTheme.textTheme.bodyText2!.copyWith(
    fontSize: 16,
    ),
    ),
    ),
    child: const MyHomePage(title: 'Flutter Demo Home Page')),
    );
    }
    }

    class MyHomePage extends StatefulWidget {
    const MyHomePage({Key? key, required this.title}) : super(key: key);

    final String title;

    @override
    State<MyHomePage> createState() => _MyHomePageState();
    }

    class _MyHomePageState extends State<MyHomePage> {
    @override
    Widget build(BuildContext context) {
    return Scaffold(
    resizeToAvoidBottomInset: false,
    body: Stack(
    children: const <Widget>[
    FullStack(),
    ],
    ),
    );
    }
    }

    class FullStack extends StatefulWidget {
    const FullStack({Key? key}) : super(key: key);

    @override
    State<FullStack> createState() => _FullStackState();
    }

    class _FullStackState extends State<FullStack> {
    bool _safeArea = false;
    bool _fakeKeyboard = false;

    final focusNode = FocusNode();

    @override
    void initState() {
    super.initState();
    focusNode.requestFocus();
    }

    @override
    Widget build(BuildContext context) {
    return Column(
    children: <Widget>[
    // Uncomment this if you want to summon the real keyboard on mobile.
    // const SizedBox(height: 100),
    // Padding(
    // padding: const EdgeInsets.symmetric(horizontal: 12),
    // child: Row(
    // children: <Widget>[
    // Expanded(
    // child: TextField(
    // decoration: InputDecoration(
    // filled: true,
    // fillColor: Colors.grey[300],
    // ),
    // ),
    // ),
    // ],
    // ),
    // ),
    Flexible(
    child: LayoutBuilder(
    builder: (BuildContext context, BoxConstraints constraints) {
    final keyboardTextStyle = Theme.of(context).textTheme.headline2;
    late final EdgeInsets viewPadding;
    late final EdgeInsets padding;

    if (!_safeArea && !_fakeKeyboard) {
    viewPadding = const EdgeInsets.symmetric(vertical: 20);
    padding = const EdgeInsets.symmetric(vertical: 20);
    } else if (_safeArea && !_fakeKeyboard) {
    viewPadding = EdgeInsets.zero;
    padding = EdgeInsets.zero;
    } else if (!_safeArea && _fakeKeyboard) {
    viewPadding = const EdgeInsets.symmetric(vertical: 20);
    padding = const EdgeInsets.fromLTRB(20, 20, 20, 0);
    } else {
    // Have both
    viewPadding = const EdgeInsets.fromLTRB(0, 0, 0, 20);
    padding = EdgeInsets.zero;
    }

    final MediaQueryData mq = MediaQuery.of(context).copyWith(
    padding: padding,
    viewPadding: viewPadding,
    viewInsets: EdgeInsets.fromLTRB(
    0,
    0,
    0,
    _fakeKeyboard ? 300 : 0,
    ),
    );
    return MediaQuery(
    data: mq,
    // data: MediaQuery.of(context),
    child: Stack(
    children: <Widget>[
    Positioned(
    bottom: mq.size.height / 2,
    left: mq.size.width / 2.5,
    child: Column(
    children: <Widget>[
    Text(
    'Fake keyboard is ${_fakeKeyboard ? "REVEALED" : "HIDDEN"}',
    style: Theme.of(context).textTheme.headline5,
    ),
    Switch(
    value: _fakeKeyboard,
    onChanged: (value) {
    setState(() {
    _fakeKeyboard = value;
    });
    },
    ),
    Text(
    'SafeArea is ${_safeArea ? "ON" : "OFF"}',
    style: Theme.of(context).textTheme.headline5,
    ),
    Switch(
    value: _safeArea,
    onChanged: (value) {
    setState(() {
    _safeArea = value;
    });
    },
    ),
    ],
    ),
    ),
    Positioned(
    top: mq.padding.top,
    left: MediaQuery.of(context).size.width / 2.1,
    child: const MediaQueryTopInfo(),
    ),
    Positioned(
    top: MediaQuery.of(context).size.height / 2.5 -
    mq.viewInsets.bottom / 2,
    left: mq.padding.left,
    child: const MediaQueryLeftInfo(),
    ),
    Positioned(
    top: MediaQuery.of(context).size.height / 2.5 -
    mq.viewInsets.bottom / 2,
    right: mq.padding.right,
    child: const MediaQueryRightInfo(),
    ),
    Positioned(
    bottom: mq.viewInsets.bottom,
    left: MediaQuery.of(context).size.width / 2.1,
    child: const MediaQueryBottomInfo(),
    ),
    _fakeKeyboard
    ? Positioned(
    bottom: 0,
    width: mq.size.width,
    height: 300,
    child: Container(
    color: Colors.grey[300],
    child: Row(
    mainAxisAlignment:
    MainAxisAlignment.spaceEvenly,
    children: <Widget>[
    Text('K', style: keyboardTextStyle),
    Text('E', style: keyboardTextStyle),
    Text('Y', style: keyboardTextStyle),
    Text('B', style: keyboardTextStyle),
    Text('O', style: keyboardTextStyle),
    Text('A', style: keyboardTextStyle),
    Text('R', style: keyboardTextStyle),
    Text('D', style: keyboardTextStyle),
    ],
    ),
    ),
    )
    : Container()
    ],
    ),
    );
    },
    ),
    )
    ],
    );
    }
    }

    class MediaQueryBottomInfo extends StatelessWidget {
    const MediaQueryBottomInfo({Key? key}) : super(key: key);

    @override
    Widget build(BuildContext context) {
    final viewInsets = MediaQuery.of(context).viewInsets;
    final viewPadding = MediaQuery.of(context).viewPadding;
    final padding = MediaQuery.of(context).padding;
    return Column(
    children: <Widget>[
    const Text('BOTTOM'),
    Text('Padding: ${padding.bottom}'),
    Text('ViewPadding: ${viewPadding.bottom}'),
    Text('ViewInsets: ${viewInsets.bottom}'),
    ],
    );
    }
    }

    class MediaQueryTopInfo extends StatelessWidget {
    const MediaQueryTopInfo({Key? key}) : super(key: key);

    @override
    Widget build(BuildContext context) {
    final viewInsets = MediaQuery.of(context).viewInsets;
    final viewPadding = MediaQuery.of(context).viewPadding;
    final padding = MediaQuery.of(context).padding;
    return Column(
    children: <Widget>[
    const Text('TOP'),
    Text('Padding: ${padding.top}'),
    Text('ViewPadding: ${viewPadding.top}'),
    Text('ViewInsets: ${viewInsets.top}'),
    ],
    );
    }
    }

    class MediaQueryLeftInfo extends StatelessWidget {
    const MediaQueryLeftInfo({Key? key}) : super(key: key);

    @override
    Widget build(BuildContext context) {
    final viewInsets = MediaQuery.of(context).viewInsets;
    final viewPadding = MediaQuery.of(context).viewPadding;
    final padding = MediaQuery.of(context).padding;
    return Column(
    children: <Widget>[
    const Text('LEFT'),
    Text('Padding: ${padding.left}'),
    Text('ViewPadding: ${viewPadding.left}'),
    Text('ViewInsets: ${viewInsets.left}'),
    ],
    );
    }
    }

    class MediaQueryRightInfo extends StatelessWidget {
    const MediaQueryRightInfo({Key? key}) : super(key: key);

    @override
    Widget build(BuildContext context) {
    final viewInsets = MediaQuery.of(context).viewInsets;
    final viewPadding = MediaQuery.of(context).viewPadding;
    final padding = MediaQuery.of(context).padding;
    return Column(
    children: <Widget>[
    const Text('RIGHT'),
    Text('Padding: ${padding.right}'),
    Text('ViewPadding: ${viewPadding.right}'),
    Text('ViewInsets: ${viewInsets.right}'),
    ],
    );
    }
    }

    class RedBlock extends StatelessWidget {
    const RedBlock({Key? key}) : super(key: key);

    @override
    Widget build(BuildContext context) {
    return Container(height: 50, width: 100, color: Colors.red);
    }
    }