웹 개발/Flutter

[Flutter] 플러터 웹 사이트 반응형으로 생성하기

ohbox 2021. 1. 23. 22:30
반응형

 

기존에 만들었던 웹사이트는 반응형 웹을 위한 설정이 적용되어있지 않기 때문에 

웹 화면을 조절했을 때 아래와 같이 overflow가 발생하거나 웹사이트의 UI가 유지되지 않는다. 

 

 

 

 

 


1) responsive builder

반응형 웹 사이트를 구축하기 위해 responsive builder 패키지를 사용한다.

responsive_builder: ^0.1.2

 

 

웹을 실행하는데 사용되는 디바이스에 맞는 페이지를 설정하면 디바이스에 맞는 반응형 웹을 생성해준다. 

디바이스 크기를 일일히 설정해줘야할 필요를 줄여주는 패키지라고 생각한다.

watch, mobile, tablet, desktop
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: ScreenTypeLayout(
          mobile: HomeScreenMobile(),
          tablet: HomeScreenDesktop(),
        ),);
  }
}

 

모바일 디바이스 사이즈에 맞는 페이지를 새롭게 추가해줬다. 

 

 

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: CenteredView(
        child: Column(
          children: <Widget>[
            NavigationBar(),
            Divider(
              thickness: 1,
              height: 1,
              color: Colors.black26,
            ),
            Expanded(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  HomeBody(),
                  SizedBox(
                    height: 30,
                  ),
                  Center(
                    child: CallToActionButton('View'),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

 

2) expanded

 

expanded는 child가  row와 column 내에 빈 공간을 채우도록 child를 확장시킨다.

따라서 디바이스 크기에 맞게 component 들이 빈 공간을 찾아 배열되도록 expanded로 감싼다.

 

homebody와 button을 감싼 column에 expanded를 적용하지 않는다면 다음과 같이 overflow가 발생한다. 

 

 

expanded를 적용한 후에는 화면크기를 줄였을 때 component들이 빈공간을 채워

배열되어 있다는 것을 알 수 있다. 

 

 

 

 

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: CenteredView(
        child: Row(
          children: <Widget>[
            NavigationBar(),
            VerticalDivider(
              thickness: 1,
              width: 1,
              color: Colors.black26,
            ),
            Expanded(
              child:
              Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  HomeBody(),
                  SizedBox(height: 30,),
                  Center(
                    child: CallToActionButton('View'),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

 

화면의 높이를 줄였을 때 버튼의 높이가 정해져 있기 때문에 overflow가 발생함 

 

 

 

버튼에 expanded를 적용했을 때 높이가 줄어들어도 버튼이 column의 빈 공간을 찾아

유연하게 변한다는 것을 알 수 있었다. 

 

 

    Expanded(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  HomeBody(),
                  Expanded(
                    child: Center(
                      child: CallToActionButton('View'),
                    ),
                  ),
                ],
              ),
            ),

 

3) ResponsiveBuilder를 이용한 device type 별 사이즈 조절 

class HomeBody extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ResponsiveBuilder(builder: (context, sizingInformation) {
      var textAlignment =
          sizingInformation.deviceScreenType == DeviceScreenType.mobile
              ? TextAlign.left
              : TextAlign.center;

      double titleSize =
          sizingInformation.deviceScreenType == DeviceScreenType.mobile
              ? 30
              : 50;

      double descriptionSize =
          sizingInformation.deviceScreenType == DeviceScreenType.mobile
              ? 10
              : 15;

      return Container(
        color: Colors.white,
        child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(
                "'FLUTTER WEB.\nCOMPONENTS'",
                style: TextStyle(
                    color: Colors.black,
                    fontWeight: FontWeight.w600,
                    fontSize: titleSize,
                    height: 0.9),
              ),
              SizedBox(
                height: 20,
              ),
              Text(
                'In this course we will go over the basics of using Flutter Web for website development.\nTopics will include Responsive Layout, Deploying, Font Changes, Hover Functionality, Modals and more.',
                style: TextStyle(fontSize: descriptionSize, height: 1.7),
                textAlign: textAlignment,
              ),
            ]),
      );
    });
  }
}

 

4) LayoutBuilder

상위 위젯 (parent's widget)에 의존하는 위젯 트리를 생성한다.

 

LayoutBuilder(
        builder: (context, constraints) {
          if (constraints.maxWidth > 600) {
            return _buildWideContainers();
          } else {
            return _buildNormalContainer();
          }
        },
      ),

 

 

5) MediaQuery.of()

현재 앱의 size와 orientation을 가져온다. 

var screenSize = MediaQuery.of(context).size

print(screenSize.width)

var screenSize = MediaQuery.of(context).size;
print(screenSize.width);

 

6) FittedBox

지정해준 fit에 따라 자식 위젯의 크기와 방향을 변화시킨다.

MyBlueRect(
	child: FittedBox(
    	alignment : Alignment.center,
		fit: BoxFit.contain(),
		child: myDashPic(),
	),
),
반응형