본문 바로가기
Programming/Flutter

[flutter] layoutbuilder

by NAMP 2023. 3. 6.

Template 를 사용하여 화면을 구성한다.

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

    @override
    Widget build(BuildContext context) {
      return DefaultTemplate(
        contents: RootContents(),
      );
    }
  }

LayoutBuilder 를 사용하여 화면 크기에 따라 반응하도록 한다.

  @override
    Widget build(BuildContext context) {
      return LayoutBuilder(
        builder: (BuildContext context, BoxConstraints constraints) {
          ScreenLayoutController.to.setScreenSize(constraints);
          var screenType = ScreenLayoutController.to.screenType.value;
          switch (screenType) {
            case ScreenSizeType.mobile: return _layout(hasDrawer: true);
            case ScreenSizeType.tablet:
            case ScreenSizeType.desktop:
            default: return _layout();
          }
        },
      );
    }

GetX 컨트롤러 ScreenLayoutController 를 사용하여 크기를 결정한다.

  enum ScreenSizeType { mobile, tablet, desktop }

  class ScreenLayoutController extends GetxController {
    static ScreenLayoutController get to => Get.find();
    var screenType = ScreenSizeType.desktop.obs;
    var isShowDrawer = false.obs;
    var boxConstraints = const BoxConstraints().obs;

    void setScreenSize(BoxConstraints constraints) {
      boxConstraints.value = constraints;
      if (constraints.maxWidth <= 600) {
        screenType.value = ScreenSizeType.mobile;
        isShowDrawer.value = true;
      } else if (constraints.maxWidth < 800) {
        screenType.value = ScreenSizeType.tablet;
        isShowDrawer.value = false;
      } else {
        screenType.value = ScreenSizeType.desktop;
        isShowDrawer.value = false;
      }
    }
  }

layout 에서 Scaffold 를 반환한다.

  Widget _layout({bool hasDrawer = false}) {
    return Scaffold(
      key: _key,
      drawer: hasDrawer
          ? Container(
              width: Get.size.width * 0.7,
              color: Colors.white,
              child: Container(
                  margin: const EdgeInsets.only(top: 50, left: 20),
                  child: const RightMenu()),
            )
          : null,
      body: _body(),
    );
  }

body 함수에서 ConstrainedBox 를 사용하여 최대 넓이를 지정한다.

  Widget _body() {
    return Container(
      alignment: Alignment.topCenter,
      child: ConstrainedBox(
        constraints: const BoxConstraints(maxWidth: 1000),
        child: Column(children: [
          Stack(
            children: [
              InkWell(
                onTap: () {
                  _key.currentState?.openDrawer();
                },
                child: const SizedBox(
                  width: 80,
                  height: 80,
                  child: Icon(Icons.menu),
                ),
              ),
              NavigationMenu(ScreenLayoutController.to.screenType.value),
            ],
          ),
          Expanded(child: contents),
          const Placeholder(
            fallbackHeight: 100,
            color: Colors.grey,
          )
        ]),
      ),
    );
  }

참고

https://github.com/sudar-life/flutter_web_sample

 

댓글