flutter

여러가지 화면크기와 화면방향으로 개발하기

paulaner80 2019. 4. 23. 12:02
반응형


모바일 앱들은 다양한 화면크기, 해상도, 화면방향을 지원해야합니다. 앱은 확장할 수 있어야하고, 화면방향을 다루어야하고 어러면서도 데이터를 유지해야합니다. 플러터에서는 이렇게 할 수는 여러가지 방법이 있습니다.


큰화면을 다루기 위한 안드로이드 솔루션


안드로이드에서는 landscapte/portrait와 화면 넓이에 따라 레이아웃 파일을 다르게하여 태블릿과 같이 큰 화면을 다룹니다. 즉, 폰 용 세로 레이아웃, 가로 레이아웃, 태블릿용 세로 레이아웃, 가로 레이아웃  런식으로 레이아웃 파일을 정의합니다. 이렇게 정의된 레이아웃 파일은 디바이스의 실행상태에 따라서 인스턴스화 됩니다. 그리고 어떤 레이아웃이 활성화 되는 지 확인하고 그에 따라 초기화 합니다. 


많은 어플리케이션에서 마스터-디테일 플로우 큰 화면사이즈 를 다루는데 사용됩니다.  마스터-디테일 플로우가 무엇인지 살펴 보겠습니다.


안드로이드에서 프래그먼트는 컴포넌트를 재상용하는데 필수 적입니다. 프래그먼트는 자신의 레이웃과  데이터나 생명주기를 제어하기위한 자바/코틀린 클래스를 가지고 있습니다. 이렇게 하기위해서는 많은 코드를 필요로 합니다.


먼저 화면방향을 다루는 것을 먼저보고 그 다음 화면크기를 다루는 것을 보겠습니다.



플러터에서 화면방향 작업


화면방향 작업을 하면, 화면 전체 넓이를 사용할 수 있고, 많은 정보를 화면에 보여줄 수 있습니다. 아래 예제는 두 방향에서 기본적인 프로파일 페이지를 생성하는데 화면방향에 따라 다른 레이아웃을 빌드하고 있습니다.


우리는 가로화면과 세로화면에대해 서로 다른 레이아웃을 가지고 있습니다. 에제를 만들어 보면서 플러터에서 레이아웃을 어떻게 변경하는지 이해해보겠습니다.


어떻게할까요?


개념적으로 동작하는 것은 안드로이드 방식과 매우 비슷합니다. 가로레이아웃과 세로레이아웃을 가지고 있고, 디바이스가 방향을 전환하면 레이아웃을 리빌드하게 됩니다.


어떻게 화면방향이 바뀌는 것을 알까요?


OrientationBuilder라는 것을 사용합니다. OrientationBuilder는 oriorientation이 변경되면 리빌드하는 위젯입니다.


@override

Widget build(BuildContext context){

  return Scaffold(

    appBar : AppBar(),

    body : OrientationBuilder(

      builder : (context, orientation){

        return orientation == Orientation.portrait

          ? _buildVerticalLayout()

          : _buildHorizontalLayout();

      }

    )

  )

}



OrientationBuilder는 레이아웃을 빌드하기위한 builder 함수를 가지고 있습니다. builder 함수는 oriorientation이 변경되면 호출됩니다.

oriorientation의 값은 Orientation.portrait 이거나 Orientation.landscape 입니다.


이 에제에서 orientation이 Orientation.portrait 이면 세로 레이아웃을 빌드하는 _buildVerticalLayout()을 호출하고 아니면 가로 레이아웃을 빌드하는 _buildHorizontalLayout()를 호출합니다.


원하는 곳에서 oriorientation을 체크하기위해서는 다음과 같은 코드를 사용합니다.

MediaQuery.of(context).orientation


세로방향 화면만 사용한다면 다음과 같은 코드를 사용합니다.

SystemChrome.setPreferredOrientations(DeviceOrientation.portraitUp);




플러터에서 큰 화면 만들기


더 큰 화면 크기를 처리 할 때 화면에서 사용 가능한 공간을 사용하도록 화면을 조정해야합니다. 이렇게하는 가장 간단한 방법은 레이아웃을 두개 (태블릿용/폰용) 만드는 것입니다.

(여기에서 "레이아웃"은 화면의 시각적 부분을 의미합니다. "화면"은 레이아웃과 연결된 모든 백엔드 코드를 나타냅니다. (화면 = 레이아웃 + 코드))

그러나 여기에는 많은 불필요한 코드가 있어서 코드를 반복해야합니다.


이문제를 풀려면 어떻게 해야할 까요?

먼저 가장 일반적인 유스케이스를 봅시다.

마스터-디테일 플로우로 돌아가서 이 것에 대해 이야기 해 봅시다. 이것을 앱에 적용하면 마스터에 있는 아이템 리스트중 아이템을 클릭하면 디테일 화면으로 이동한는 패턴을 볼 수 있습니다.

지메일 예를 보면 메일목록이 있고 그 중 하나를 클릭하면, 메일내용과 함께 디테일 화면으로 넘어갑니다.


이것과 비슷한 예제를 만들어 보겠습니다.


이 앱은 마스터에서는단순한 숫자 리스트를 보여주고 디테일 뷰 에서는 탭한 숫자를 크게 보여줍니다.


만약 테블릿에서 이런 레이아웃을 사요하게된다면, 많은 공간을 낭비하게됩니다. 이를 해결하기위해서 한 화면에서 마스터 리스트와 디테일 뷰를 보여 줄 수 있습니다. 


그러면 두 가지 스크린을 작성해야하는 일을 줄이기 위해서 무엇을 해야할 까요?


안드로이드에서 이것을 어떻게 해결하는 지 봅시다. 안드로이드에서는 마스터와 디테일뷰를 프레그먼트라는 재사용가능한 뷰를 사용해 만듭니다. 프레그먼트는 화면과 별도로 정의 할 수 있으며 코드를 두 번 반복하지 않고 화면에 추가 할 수 있습니다.

프레그먼트A는 마스터 리스트이고, 프레그먼트B는 디테일 프레그먼트 입니다. 폰과같이 작은 넓이의 화면에서는 목록화면을 클릭하면 별도의 페이지로 이동하지만 테블릿이나 가로방향 폰과 괕이 넓은 가로를 가지는 화면에서는 디테일 프레그먼트가 변경됩니다.



Flutter의 모든 위젯은 본질적으로 재사용이 가능하고 프레그먼트와 비슷하기 때문에 이식으로 사용할 수 있습니다.


개요


1. 두 위젯을 정의하겠습니다. 하나는 마스터리스트이고 하나는 디테일 뷰입니다.

2. 디바이스가 이 두위젯을 다룰수 있는 넓이를 가지는 체크합니다. 

    MediaQuery.of(context).size.width

    (size는 넓이와 높이를 dp단위로 넘겨줍니다. 600dp 이하일 때는 화면을 이동시키도록하겠습니다.)

3. 넓이가 충분하면 한 화면에서 두 위젯모두 사용하고 아니면 아이템을 탭했을 때 디테일뷰로 이동합니다.









https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434

'flutter' 카테고리의 다른 글

dart lang cheatsheet  (0) 2019.10.29
flutter cheatsheet  (0) 2019.10.29
bloc todo  (0) 2019.04.19
Widget, State, BuildContext 그리고 InheritedWidget  (1) 2019.04.16
플러터용 파이어 베이스 1부  (0) 2019.04.11