본문 바로가기
개발

flutter에서 responsive 구현하기

by GreatCoding 2022. 8. 27.

flutter는 iOS, Android, Windows, MacOS, Linux, Web의 6가지 플렛폼을 하나의 코드로 지원한다.
하지만 각각의 기기는 모바일이냐 데스크탑이냐에 따라 화면 크기가 다르고 보여줄 정보의 양도 다르다.

이 글에서는 flutter에서 반응형 디자인을 적용하여 모바일과 데스크탑 모두에 적합하게 보이는 화면을 구현해보도록 하겠다.

import 'package:flutter/material.dart';  

class ResponsiveLayout extends StatelessWidget {  
  final Widget phone;  
  final Widget tablet;  
  final Widget desktop;  

  const ResponsiveLayout({  
    required this.phone,  
    required this.tablet,  
    required this.desktop  
  });  

  // 650, 1100  
  static const int phoneLimit = 650;  
  static const int tabletLimit = 1100;  

  static bool isPhone(BuildContext context) =>  
      MediaQuery.of(context).size.width < phoneLimit;  

  static bool isTablet(BuildContext context) =>  
      MediaQuery.of(context).size.width < tabletLimit &&  
          MediaQuery.of(context).size.width >= phoneLimit;  

  static bool isDesktop(BuildContext context) =>  
      MediaQuery.of(context).size.width >= tabletLimit;  

  @override  
  Widget build(BuildContext context) {  
    return LayoutBuilder(  
      builder: (BuildContext context, BoxConstraints constraints) {  
        if (constraints.maxWidth < phoneLimit) {  
          return phone;  
        }  
        if (constraints.maxWidth < tabletLimit) {  
          return tablet;  
        }  
        return desktop;  
      },  
    );  
  }  
}

LayoutBuilder와 MediaQuery를 통해 화면 사이즈를 비교하여 phone, tablet, desktop 중 어느환경인지 구분하였다.

import 'package:flutter/material.dart';  
import 'responsive_layout.dart';  
import 'main.dart';  

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

  @override  
  Widget build(BuildContext context) {  
    return Scaffold(  
        drawer: Drawer(child: DrawerScreen()),  

        body: ResponsiveLayout(  
          phone: MyHomePage(),
          tablet: Row(  
            children: [  
              Expanded(
                flex: 1,
                child: MyHomePage(),
              ),  
              Expanded(
                flex: 2,
                child: ListScreen(),  
              )  
            ],  
          ),  
          desktop: Row(  
            children: [  
              Expanded(
                flex: 1, 
                child: MyHomePage(),
              ),  
              Expanded(
                flex: 2,
                child: ListScreen(),  
              ),  
              Expanded(
                flex: 2, 
                child: DetailScreen(),  
              ),  
            ],  
          ),  
        ),
    );  
  }  
}

WidgetTree에선 각 환경에서 어떤 화면들을 보여줄지 결정을 해준다. Expanded의 flex를 통하여 보이는 화면의 비율을 조절할 수 있다.

import 'package:flutter/material.dart';  
import 'package:responsive/widget_tree.dart';  

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

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

  @override  
  Widget build(BuildContext context) {  
    return MaterialApp(  
      title: 'Flutter Demo',  
      theme: ThemeData(  
        primarySwatch: Colors.blue,
      ),  
      home: WidgetTree(),
    );  
  }  
}

마지막으로 WidgetTree에 WidgetTree()를 붙여주면 끝난다.

 

레퍼런스

댓글