Flutter Responsive App (LayoutBuilder)

강정우·2023년 5월 21일
0

Flutter&Dart

목록 보기
36/82
post-thumbnail

세로 고정

  • 이 방법은 사용자가 세로로 디바이스를 돌려도 무조건 세로고정하여 개발자의 의도에 사용자를 맞추는 것이다. 사용자 입장에서는 별로 유쾌한 경험은 아니겠지만 앱이 최적으로 쓰이기 위해 강제할 수도 있다.

0. import및 객체 준비하기

import 'package:flutter/services.dart';

void main(){
	SystemChrome.setPreferredOrientations([])).then((){});
    ...

  • 우선 flutter에서 제공하는 services 파일에 SystemChrome 객체를 가져온다.

1. setPreferredOrientations

  • 즉, 선호하는 방향은 set하겠다는 함수로 인수로는 사용자에게 제공할 방향들을 List로서 제공하면 된다.

  • 즉, 여기에 명시되지 않은 방향들은 방지된다.

  • 이제 해당 함수가 Promise 처럼 Future 객체를 반환하기 때문에 이를 .then이나 await으로 받아서 해결해줘야한다.
    그리고 .then은 항상 함수를 return한다.

  • 따라서 여기서는 setPreferredOrientations 즉, 선호하는 방향이 설정되면 그 다음(.then())에 앱을 실행(run) 해줘야한다.

2. WidgetsFlutterBinding.ensureInitialized();

  • 위 코드라인이 있어야 SystemChrome.setPreferredOrientations이 정상적으로 로그인 되고 그 다음(.then()) runApp이 작동한다.

responsive app (반응형)

  • 반응형 앱이란 레이아웃과 스타일이 사용 가능한 공간과 사용 가능한 너비 앱이 실행되는 모드에 맞춰 조정되는 앱이다.

  • 즉, portait 모드와 landscape 모드 모두 지원하는 앱이 바로 반응형 앱이다.

1. MediaQuery 이용하기

  • 바로 앞전 포스팅에서 black theme를 지정할 때 MediaQuery를 이용해 사용자 Bringhtness에 접근하여 3항 연산자로 다크 테마를 결정한 바 있다.
    이와 똑같이 MediaQuery를 이용하여 사용자의 size에 접근해 가로길이가 특정 숫자를 넘지기 않을 때 landscape 모드를 적용시키면 된다.

  • 이때 또 주의할 부분은 Row의 가로 길이는 따로 지정하지 않으면 최대한을 차지한다고 하였다. 그런데 위 코드의 Chart 위젯을 보면 가로 길이를 무한하게 차지하고 있는 것으로 보인 이는 당연히 버그를 야기한다. 최대한의 부모 width에 자식 width도 무한하면 아예 표시할 수 없기 때문이다. 이를 방지하고자 부모 위젯에서 child를 부모 width값 만큼 딱 지정을 해주는 것이다. (Row의 children의 0번째 위젯에 Expanded)

understand widget size constrain

  • 기본적으노 Column은 세로를 최대한 가져가려고 하고 Row는 가로를 최대한으로 가져가려고 한다.
    하지만 Scaffold를 이용한다면 애초에 높이값과 너비값을 디바이스에 맞추기 때문에 추가적으로 Expanded 위젯을 사용할 일이 없다.
    그리고 높이값과 너비값을 각각 비교하여 더 작은 것을 최종 높이와 너비로 가져간다.

  • 즉, 이 말은 Column의 높이값은 자식과 상관이 없어지게 된다. 이말은 column은 높이값을 row는 너비값을 지정하지 않으면 자식이 무한하게 공간을 차지하려고 한다면 뻑난다는 뜻이다.

2. viewInsets 설정하기

  • viewInsets은 다른 UI를 덮어씌운 UI에 대한 추가정보를 담고 있다.

  • 즉, 위 코드는 키보드가 차지하는 양 만큼의 길이를 얻을 수 있다는 것이다.

  • 따라서 위 키보드가 차지하는 값 만큼을 패딩에 추가로 부여해야하고 이를 scrollable하게 만들어야 우리가 의도한 대로 동작할 것이다.

3. useSafeArea

  • 하지만 위 코드를 자세 보면 매우 하드코딩 되어있는 padding을 볼 수 있다. 이는 카메라가 달려있는 핸드폰 특성상 카메라 부분의 값을 padding을 준 것인데 이는 각 기종마다 다른 것을 감안하면 매우 불완전한 코드이다. 이를 방지하기위해 존재하는 것이 바로 showModalBottomSheet라는 플러터에서 제공하는 함수 내부의 useSafeArea 속성값이다.

  • 이 속성값만 넣어주면 알아서 flutter에서 상위 상태창을 계산해서 그 값 만큼을 확보해준다.

4. LayoutBuilder 위젯 사용하기

  • constraints가 나타내는 바는 현재 위젯의 부모위젯으로부터 어떠한 제약조건(constraint)를 받고있는지 담고 있는 객체이다.

  • constaint가 사용 가능한 공간이 얼마나 되는지 정확히 알 수 있고 또 이것으로 어떤 레이아웃을 렌더링할지 결정할 수 있다.

  • 사용 가능한 화면 너비나 높이는 신경 쓰지 않아도 된다. 왜? constraint 객체 내에 다 담겨있지 때문이다.

  • 여기서 매우 중요한 것은!!!

빌더는 제약 조건이 바뀔 때마다 빌더 함수를 호출한다.

  • 이는 위젯이 다른 곳으로 이동하거나 최소 너비와 최대 너비 값이 바뀌면 즉, 예를 들어 장치 방향을 바꾸면 UI가 업데이트된다는 뜻이다.

  • 이제 LayoutBUilder위젯을 사용하면 부모 위젯만 신경 쓰면 된다.

profile
智(지)! 德(덕)! 體(체)!

0개의 댓글