ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Large screen - 다양한 화면 크기 지원
    프로그래밍/Android 2021. 9. 6. 23:38
    반응형

    아래는 하나의 APK에서 여러 크기 화면 지원하는 방법이다. 

    • 레이아웃 크기 조정이 허용되는 뷰 크기 사용
    • 화면 구성에 따라 대체 UI 레이아웃 만들기
    • 뷰에서 확장할 수 있는 비트맵 제공

    This page shows you how to support different screen sizes with the following techniques:

    • Use view dimensions that allow the layout to resize
    • Create alternative UI layouts according to the screen configuration
    • Provide bitmaps that can stretch with the views

     

    유연한 레이아웃 만들기 (Create a flexible layout)

    • LinearLayout 보다는 ConstraintLayout 을 사용해야한다. LinearLayout은 여러 레이아웃에 전달하며 계산해서 UI 성능이 느려진다.  
    • 하드코딩대신 "wrap_content" 및 "match_parent" 속성을 사용한다. 
    • 작은 화면에서는 하나의 리스트가 나오게 하고 큰 화면에서는 두 개의 팬으로 나오게 하는 SlidingPaneLayout 사용 
    • To ensure that your layout is flexible and adapts to different screen sizes, you should use "wrap_content" or "match_parent" for the width and height of most view components, instead of hard-coded sizes.
    • ConstraintLayout can achieve nearly all layouts possible with LinearLayout without the performance impacts.
    • A list/detail UI may need to behave differently for different screen sizes. You can use SlidingPaneLayout to manage the logic for determining which of these two user experiences is appropriate for the current window size:
      • <?xml version="1.0" encoding="utf-8"?>
        <androidx.slidingpanelayout.widget.SlidingPaneLayout xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            xmlns:tools="http://schemas.android.com/tools"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".MainActivity">
        
            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/recycler_view"
                android:layout_width="280dp"
                android:layout_height="match_parent"
                android:layout_gravity="start" />
        
            <androidx.fragment.app.FragmentContainerView
                android:id="@+id/nav_host_fragment"
                android:name="androidx.navigation.fragment.NavHostFragment"
                android:layout_width="300dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                app:defaultNavHost="true"
                app:navGraph="@navigation/item_navigation" />
        
        </androidx.slidingpanelayout.widget.SlidingPaneLayout>
      • 두 팬이 한 화면에 표시되려면 최소 580dp(280dp + 300dp) 너비가 필요하다. SlidingPaneLayout V1.2.0-alpha0 을 사용하면 화면이 580dp 보다 클 때 280dp 팬이 표시되고 나머지 영역은 두 번째 팬이 표시되게 된다.
      • The widths and weight here are the key factors that determine the behavior. If the window is large enough to display both views (at least 580dp) then the side- by-side UI is used. However, if it is smaller than that, then the full-screen list replaced by full-screen detail UI is used instead.
      • When in side-by-side mode, the window may be larger than the minimum requirement of 580dp in this example. Weight values will be used to size the two panes proportionally. In the example, the list pane will always be 280dp and the detail pane will fill the remaining space. The one exception to this is when using SlidingPaneLayout V1.2.0-alpha01 and later on foldable devices. In these cases SlidingPaneLayout will automatically adjust the size of the panes so that they are on either side of any fold or hinge.

     

    대체 레이아웃 만들기 (Create alternative layouts)

    현재 앱이 스마트폰용 UI로 디자인되어있다면 태블릿에는 어색해보일 것이다. 앱은 특정 화면 크기에 맞게 디자인된 UI를 최적화할 대체 레이아웃 리소스도 제공해야한다. 

    Your app should also provide alternative layout resources to optimize the UI design for certain screen sizes.

    같은 앱이 서로 다른 레이아웃 사용

    리소스 한정자 (Resource qualifier)

    너비 한정자
    (the available width qualifier)
    layout-w600dp 현재 사용 가능한 윈도우 너비가 600dp 
    Screens that have 600dp of available width.
    멀티 윈도우 모드시 사용 가능 
    (With multi-window)
    최소 너비 한정자
    (the smallest width qualifier)
    layout-sw600dp 최소 사용 가능한 윈도우 너비가 600dp
    To change your layout based on how much width or height is currently available.
    스마트폰, 태블릿화면 분리 시 사용 가능 
    (
    방향 한정자 
    (orientation qualifiers)
    layout-land
    layout-port
    layout-sw600dp-land
    세로/가로 방향 전환시 사용 
    To change the user experience when the user switches between portrait and landscape orientations.
     

    최소 너비 한정자(The smallest width qualifier)

    • 320dp: 일반적인 전화 화면(240x320 ldpi, 320x480 mdpi, 480x800 hdpi 등).
    • 480dp: 대형 스마트폰 화면, 최대 5인치까지(480x800 mdpi).
    • 600dp: 7” 태블릿(600x1024 mdpi).
    • 720dp: 10” 태블릿(720x1280 mdpi, 800x1280 mdpi 등).
    • 320dp: a typical phone screen (240x320 ldpi, 320x480 mdpi, 480x800 hdpi, etc).
    • 480dp: a large phone screen ~5" (480x800 mdpi).
    • 600dp: a 7” tablet (600x1024 mdpi).
    • 720dp: a 10” tablet (720x1280 mdpi, 800x1280 mdpi, etc).
    res/layout/main_activity.xml           # For handsets (smaller than 600dp available width)
    res/layout-sw600dp/main_activity.xml   # For 7” tablets (600dp wide and bigger)

     

    리소스 한정자 예시

    다음과 같이 최소 너비 한정자를 추가해 놓았을 때, 768dp인 태블릿에서 실행하면?

    700dp의 레이아웃이 실행된다.

     

    프래그먼트로 UI 구성요소 모듈화

    프래그먼트를 결합하여 큰 화면에서 실행할 때 다중창 레이아웃을 만들거나 핸드셋에서 실행할 때 개별 활동에 배치할 수 있습니다.

    예를 들어 태블릿의 뉴스 앱은 왼쪽에 기사 목록을 표시하고 오른쪽에 특정 기사 전체를 표시할 수 있습니다. 왼쪽의 기사를 선택하면 오른쪽의 기사 보기가 업데이트됩니다. 하지만 핸드셋에서는 이러한 두 구성요소가 별개의 화면으로 표시되어야 합니다. 목록에서 기사를 선택하면 전체 화면이 변경되어 해당 기사가 표시됩니다.

    You can then combine fragments to create multi-pane layouts when running on a large screen or place in separate activities when running on a handset.

    For example, a news app on a tablet might show a list of articles on the left side and a full article on the right side—selecting an article on the left updates the article view on the right. On a handset, however, these two components should appear on separate screens—selecting an article from a list changes the entire screen to show that article.

     

    Android 3.1 이하 지원

    res/layout/main_activity.xml           # For handsets (smaller than 640dp x 480dp)
    res/layout-large/main_activity.xml     # For small tablets (640dp x 480dp and bigger)
    res/layout-xlarge/main_activity.xml    # For large tablets (960dp x 720dp and bigger)
    
    // For devices over 3.1
    res/layout-sw600dp/main.xml			   # For 7” tablets

     

    Jetpack Compose

    Create a flexible layout

    You can easily achieve flexible layouts in Jetpack Compose by using weights in much the same way that weights are used for traditional views. For more complex layouts, you can also use ConstraintLayout in Compose.

    Create alternative layouts

    Jetpack Compose doesn't use resources to represent layouts, so you can't use resource qualifiers to provide alternate layouts. Instead, you can build this logic into your Composables. A LocalConfiguration instance provides information about the current device configuration. This is broadly in line with the qualifiers used to specify alternate resources in traditional View-based UIs. For example, the screen orientation, size, whether the keyboard is visible, and so on. can be determined from the following sample:

    @Composable
    fun DynamicLayout() {
        val configuration = LocalConfiguration.current
        if (configuration.smallestScreenWidthDp < 580 ) {
             SmallLayout()
         } else {
             LargeLayout()
         }
    }

    If you handle configuration changes yourself then this composable is recomposed when the configuration changes. Otherwise your activity is recreated as usual on configuration changes causing a new composition to be created.

    Sometimes components might depend on the size allocated to them, rather than the entire screen. In this case, use BoxWithConstraints. This defers composition until the after the measurement phase and the allocated size and other constraints are known. These constraints are available in the scope of the lambda:

    @Composable
    fun AdaptiveLayout() {
        BoxWithConstraints {
            if (maxWidth < 580.dp) {
                SmallLayout()
            } else {
                LargeLayout()
            }
        }
    }

    In this example, different layouts are emitted depending on whether the maximum width of the AdaptiveLayout composable is greater than or less than 580dp. 

     

    나인 패치 이미지 사용 (Create stretchable nine-patch bitmaps)

    뷰의 크기가 변경될 때 안드로이드에서 백그라운드 이미지의 크기를 조정한다. 이 때 나인 패치 이미지를 사용하는 것이 좋다. 나인 패치 비트맵은 늘릴 수 있는 영역과 늘릴 수 없는 영역을 나타내는 특수한 형식의 PNG 파일이다.

    나인 패치 비트맵은 기본적으로 표준 PNG 파일이지만 확장해야 하는 픽셀을 나타내는 추가 1px 테두리가 있고 단순한 .png 대신 .9.png 확장자를 사용한다. 그림 5와 같이 왼쪽 위 가장자리의 검은색 선 사이의 교차점이 확장할 수 있는 비트맵 영역이다. (안드로이스 스튜디오에서 만드는 방법)

    나인 패치를 뷰의 백그라운드로 적용하는 경우 프레임워크가 버튼 크기에 맞게 이미지를 올바른 크기로 늘리게 된다.

    If you use a bitmap as the background in a view that changes size, you will notice Android scales your images as the view grows or shrinks based on the size of the screen or content in the view. This often leads to visible blurring or other scaling artifacts. The solution is using nine-patch bitmaps, which are specially formatted PNG files that indicate which areas can and cannot be stretched.

    A nine-patch bitmap is basically a standard PNG file, but with an extra 1px border that indicates which pixels should be stretched (and with a .9.png extension instead of just .png). As shown in figure 5, the intersection between the black lines on the left and top edge is the area of the bitmap that can be stretched.

    When you apply a nine-patch as the background to a view, the framework stretches the image correctly to accommodate the size of the button.

     

    모든 화면 크기로 테스트 (Test on all screen sizes)

    애뮬레이터 혹은 실제 기기에서 테스트한다. 

    Android 10 이상부터 Aspect ratio를 더 많이 지원한다. 예를 들면 1:1 ~ 21:9와 같은 폴더블 기기도 지원한다. 

     

    지원할 수 없는 Ratio가 있다면 maxAspectRatio와 minAspectRatio를 매니페스트에 추가해 지원할 수 없는 Ratio를 지정할 수 있다. 

    If you cannot support some of those ratios, you can use the maxAspectRatio (as before), as well as minAspectRatio to indicate the highest and lowest ratios your app can handle. In cases with screens that exceed these limits, your app might be put in compatibility mode.

     

    특정 화면 크기 지원 선언 (Declare specific screen size support)

    https://developer.android.com/guide/practices/screens-distribution

     

    ----

    https://developer.android.com/training/multiscreen/screensizes

    반응형
Designed by Tistory.