[Flutter] 플러터 웹 사이트 반응형으로 생성하기
기존에 만들었던 웹사이트는 반응형 웹을 위한 설정이 적용되어있지 않기 때문에
웹 화면을 조절했을 때 아래와 같이 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(),
),
),