강력한 MediaQuery로 반응형 Flutter 앱 구축

먼저 null-safety stable을 갖춘 Flutter 2.2의 새로운 릴리스에 대해 매우 흥분된다고 말하고 싶습니다. 하지만 나중에 이야기하겠습니다.


Flutter와 같은 다중 플랫폼 프레임워크로 앱을 개발할 때. 반응형과 적응형은 신경써야 할 중요한 것입니다. 우리 앱은 스마트폰에서만 실행되는 것이 아니라 종횡비와 시각적 밀도가 다른 다양한 장치에서 실행되기 때문입니다. 따라서 개발자로서 우리의 임무는 앱 레이아웃이 안정적이고 양호하며 모든 장치에 적응할 수 있도록 하는 것입니다.
좋습니다. 이 기사에서는 Flutter로 반응형 앱을 빌드하는 방법을 단계별로 보여드리겠습니다. 부담 없이 따라해 보세요.

프로젝트 로드



시작 프로젝트를 만들었습니다. 따라서 처음부터 프로젝트를 만들 필요가 없습니다. 이 저장소를 복제하십시오.


우주비행사 / flutter_responsive_onboarding


MediaQuery를 사용한 데모 Flutter 응답 핸들




Note:
On that repository, select the branch flutter_responsive_onboarding_starter. Now, you’re ready to start



해당 소스 코드에서 별도의 패키지/폴더를 만들어 코드를 보다 깨끗하고 유지 관리하기 쉽게 유지합니다. lib 폴더는 다음과 같습니다.



lib 폴더 안에는 여러 폴더가 있습니다.
  • 화면: 모든 앱 화면 또는 레이아웃을 넣는 데 사용됨
  • 유틸리티: 모든 유틸리티(예: 상수, 도우미 등)를 넣는 데 사용됩니다
  • .
  • 위젯: 위젯을 넣는 데 사용됨

  • Remember:
    When developing an app, make sure to create single-responsibility functions, classes, and widgets (on Flutter). That's why it's better to separate the code into small pieces.



    위젯 작업



    위젯 폴더부터 시작하겠습니다. 레이아웃을 구성하는 몇 가지 코드를 작성합니다.
  • 제목 위젯

  • import 'package:flutter/material.dart';
    import 'package:flutter_responsive_onboarding/utils/utils.dart';
    
    class TitleWidget extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        double deviceWidth = MediaQuery.of(context).size.width;
    
        return Center(
          child: Image(
            image: AssetImage('assets/title.png'),
            width: Utils.getDeviceType() == 'phone'
                ? deviceWidth / 2
                : deviceWidth / 3,
          ),
        );
      }
    }
    

  • 일러스트레이션 위젯

  • import 'package:flutter/material.dart';
    import 'package:flutter_responsive_onboarding/utils/utils.dart';
    
    class IllustrationWidget extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        double deviceWidth = MediaQuery.of(context).size.width;
    
        return Center(
          child: Image(
            image: AssetImage(
              'assets/illustration.png',
            ),
            width:
                Utils.getDeviceType() == 'phone' ? deviceWidth : deviceWidth / 1.2,
          ),
        );
      }
    }
    

  • 캡션 위젯

  • import 'package:flutter/material.dart';
    import 'package:flutter_responsive_onboarding/utils/utils.dart';
    import 'package:google_fonts/google_fonts.dart';
    
    class CaptionWidget extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Container(
          child: Column(
            children: [
              Text(
                'Play Anywhere',
                style: GoogleFonts.inter(
                  fontSize: Utils.getDeviceType() == 'phone' ? 28.0 : 46.0,
                  fontWeight: FontWeight.w800,
                ),
              ),
              SizedBox(
                height: 16.0,
              ),
              Text(
                'The video call feature can be\naccessed from anywhere in your\nhouse to help you.',
                textAlign: TextAlign.center,
                style: GoogleFonts.inter(
                  fontSize: Utils.getDeviceType() == 'phone' ? 18.0 : 28.0,
                  fontWeight: FontWeight.w300,
                  color: Color(0xFFA6A6A6),
                ),
              ),
            ],
          ),
        );
      }
    }
    

  • 표시기 위젯

  • import 'package:flutter/material.dart';
    import 'package:flutter_responsive_onboarding/utils/utils.dart';
    
    class IndicatorWidget extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Container(
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Icon(
                Icons.paid,
                color: Color(0xFF4756DF),
                size: Utils.getDeviceType() == 'phone' ? 24.0 : 32.0,
              ),
              Icon(
                Icons.paid,
                color: Color(0xFFB9BFF3),
                size: Utils.getDeviceType() == 'phone' ? 24.0 : 32.0,
              ),
              Icon(
                Icons.paid,
                color: Color(0xFFB9BFF3),
                size: Utils.getDeviceType() == 'phone' ? 24.0 : 32.0,
              ),
            ],
          ),
        );
      }
    }
    

  • 버튼 위젯

  • import 'package:flutter/material.dart';
    import 'package:flutter_responsive_onboarding/utils/utils.dart';
    import 'package:google_fonts/google_fonts.dart';
    
    class ButtonWidget extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        double deviceWidth = MediaQuery.of(context).size.width;
    
        return Container(
          width: Utils.getDeviceType() == 'phone'
              ? deviceWidth / 2
              : deviceWidth / 2.5,
          height: Utils.getDeviceType() == 'phone' ? 56.0 : 72.0,
          child: ElevatedButton(
            child: Text(
              'Get Started',
              style: GoogleFonts.roboto(
                fontSize: Utils.getDeviceType() == 'phone' ? 18.0 : 24.0,
              ),
            ),
            style: ElevatedButton.styleFrom(
              primary: Color(0xFF4756DF),
              elevation: 0.0,
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(
                  Utils.getDeviceType() == 'phone' ? 15.0 : 20.0,
                ),
              ),
            ),
            onPressed: () {},
          ),
        );
      }
    }
    

    좋습니다. 모든 위젯이 준비되었으며 단일 책임이 있습니다. 아시다시피 MediaQuery를 사용하여 장치 너비를 가져옵니다. 그런 다음 스마트폰과 태블릿에서 앱을 실행할 때 더 이해하기 쉽도록 모든 위젯의 너비를 조작합니다.

    double deviceWidth = MediaQuery.of(context).size.width;
    

    deviceWidth 변수와 장치 유형이 변경됩니다. 이 단계까지는 위젯 코드에 오류가 있을 수 있습니다. UI 동작을 제어하려면 Utils 클래스에 다음 코드를 추가합니다.

    import 'package:flutter/material.dart';
    
    class Utils {
      static String getDeviceType() {
        final data = MediaQueryData.fromWindow(WidgetsBinding.instance!.window);
        return data.size.shortestSide < 550 ? 'phone' : 'tablet';
      }
    }
    

    Utils 클래스에서 MediaQueryData를 사용하여 장치 종류를 지정합니다. 우리는 장치의 가장 짧은 쪽을 얻습니다. 가장 짧은 변을 지정할 수 있습니다 < 550은 스마트폰입니다. 그렇지 않으면 태블릿이어야 합니다.

    페이지 완료



    on_boarding_screens.dart를 완성합시다! 열에 모든 위젯을 배치합니다. 다음은 위젯의 배열입니다.

    import 'package:flutter/material.dart';
    import 'package:flutter_responsive_onboarding/widgets/button_widget.dart';
    import 'package:flutter_responsive_onboarding/widgets/caption_widget.dart';
    import 'package:flutter_responsive_onboarding/widgets/illustration_widget.dart';
    import 'package:flutter_responsive_onboarding/widgets/indicator_widget.dart';
    import 'package:flutter_responsive_onboarding/widgets/title_widget.dart';
    
    class OnBoardingScreen extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: SafeArea(
            child: Padding(
              padding: const EdgeInsets.symmetric(
                horizontal: 16.0,
                vertical: 24.0,
              ),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: [
                  // Here is where the widget will build
                  TitleWidget(),
                  Column(
                    children: [
                      IllustrationWidget(),
                      CaptionWidget(),
                      SizedBox(
                        height: 16.0,
                      ),
                      IndicatorWidget(),
                    ],
                  ),
    
                  ButtonWidget(),
                ],
              ),
            ),
          ),
        );
      }
    }
    

    이제 앱이 준비되었습니다. 스마트폰과 태블릿에서 모두 실행하고 결과를 확인해 봅시다. 결과는 다음과 같습니다.



    괜찮은. 이것이 모든 종류의 기기에서 Flutter 앱의 반응성을 높이는 방법의 단계입니다. 웹 및 기타 OS의 경우 Utils 파일에 더 많은 조건을 추가할 수 있습니다.

    이것은 앱을 반응형으로 만드는 전통적인 방법입니다. Flutter는 이를 위한 도구를 제공했습니다. 그러나 더 빠르게 작업하려면 다음과 같은 타사 패키지를 사용하는 것이 좋습니다.
  • 사이저 ( Link to Pub.dev )
  • 반응형 프레임워크 ( Link to Pub.dev )


  • 그게 전부입니다. 이런 글이 마음에 드셨다면 박수 부탁드립니다 :) 또한 질문이 있으시면 이 글에 댓글을 달아주세요. 정말 고맙습니다!

    전체 소스 코드는 여기에서 확인할 수 있습니다.


    우주비행사 / flutter_responsive_onboarding


    MediaQuery를 사용한 데모 Flutter 응답 핸들

    좋은 웹페이지 즐겨찾기