위젯 선택 도구에 미리보기 추가

앱의 위젯 선택 도구 환경을 개선하려면 Android 15 이상 기기에서는 생성된 위젯 미리보기를, Android 12~Android 14 기기에서는 확장된 위젯 미리보기(previewLayout 지정)를, 이전 버전에서는 previewImage를 제공하세요.

생성된 위젯 미리보기를 사용하면 위젯이 사용자의 홈 화면에 어떻게 표시되는지 정확하게 반영하는 동적 맞춤 미리보기를 만들 수 있습니다. Android 15 이상에서는 푸시 API를 통해 제공됩니다. 즉, 앱은 위젯 호스트로부터 명시적인 요청을 받지 않고도 수명 주기 중 어느 시점에서든 미리보기를 제공합니다.

자세한 내용은 YouTube의 실시간 소식 및 위젯으로 앱 보강을 참고하세요.

생성된 미리보기 추가

Android 15 이상 기기에서 생성된 위젯 미리보기를 표시하려면 먼저 모듈 build.gradle 파일에서 compileSdk 값을 35 이상으로 설정하여 위젯 선택 도구에 RemoteViews를 제공할 수 있도록 합니다.

앱은 AppWidgetManager에서 setWidgetPreview를 사용할 수 있습니다. 악용을 방지하고 시스템 상태 문제를 완화하기 위해 setWidgetPreview는 비율 제한 API입니다. 기본 한도는 시간당 약 2회입니다.

미리보기를 제공하는 시스템의 콜백이 없으므로 앱에서 setWidgetPreviews를 호출할 시점을 결정해야 합니다. 업데이트 전략은 위젯의 사용 사례에 따라 다릅니다.

  • 위젯에 정적 정보가 있거나 빠른 작업인 경우 앱이 처음 실행될 때 미리보기를 설정합니다.
  • 앱에 데이터가 있으면 미리보기를 설정할 수 있습니다(예: 사용자 로그인 또는 초기 설정 후).
  • 선택한 주기로 미리보기를 업데이트하는 주기적 작업을 설정할 수 있습니다.

다음 예에서는 XML 위젯 레이아웃 리소스를 로드하고 미리보기로 설정합니다. setWidgetPreview가 이 스니펫에서 메서드로 표시되려면 compileSdk 빌드 설정이 35 이상이어야 합니다.

AppWidgetManager.getInstance(appContext).setWidgetPreview(
    ComponentName(
        appContext,
        ExampleAppWidgetReceiver::class.java
    ),
    AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
    RemoteViews("com.example", R.layout.widget_preview)
)

확장 가능한 위젯 미리보기 추가

Android 12부터 위젯 선택 도구에 표시되는 위젯 미리보기는 확장 가능합니다. 위젯의 기본 크기로 설정된 XML 레이아웃으로 제공합니다. 이전에는 위젯 미리보기가 정적 드로어블 리소스였기 때문에 위젯이 홈 화면에 추가될 때 표시되는 방식이 미리보기에 정확하게 반영되지 않는 경우가 있었습니다.

확장 가능한 위젯 미리보기를 구현하려면 appwidget-provider 요소의 previewLayout 속성을 사용하여 XML 레이아웃을 대신 제공합니다.

<appwidget-provider
    android:previewLayout="@layout/my_widget_preview">
</appwidget-provider>

실제 위젯과 동일한 레이아웃을 사용하고 실제와 같은 기본값 또는 테스트 값을 사용하는 것이 좋습니다. 대부분의 앱은 동일한 previewLayout 및 initialLayout를 사용합니다. 정확한 미리보기 레이아웃을 만드는 방법에 관한 안내는 동적 항목이 포함된 정확한 미리보기 빌드를 참고하세요.

사용자의 기기가 previewLayout를 지원하지 않는 경우 앱이 previewImage를 사용하도록 대체할 수 있도록 previewLayout 및 previewImage 속성을 모두 지정하는 것이 좋습니다. previewLayout 속성은 previewImage 속성보다 우선합니다.

이전 버전과의 호환성을 위해 정적 위젯 미리보기 추가

Android 11 (API 수준 30) 이하의 위젯 선택 도구에서 위젯의 미리보기를 표시하거나 확장 가능한 미리보기의 대체로 사용하려면 previewImage 속성을 지정합니다.

위젯의 모양을 변경하는 경우 미리보기 이미지를 업데이트합니다.

이 속성은 setWidgetPreview를 사용하여 설정하지 않은 경우 생성된 미리보기의 대체로도 사용됩니다.

동적 항목이 포함된 정확한 미리보기 빌드

그림 1: 목록 항목이 표시되지 않는 위젯 미리보기

이 섹션에서는 컬렉션 뷰가 있는 위젯(즉, ListView, GridView 또는 StackView를 사용하는 위젯)의 위젯 미리보기에 여러 항목을 표시하는 권장 방법을 설명합니다. 이는 생성된 미리보기가 아닌 확장 가능한 위젯 미리보기에 적용됩니다.

위젯이 이러한 뷰 중 하나를 사용하는 경우 previewLayout에서 실제 위젯 레이아웃을 직접 제공하여 확장 가능한 미리보기를 만들면 위젯 미리보기에 항목이 표시되지 않을 때 환경이 저하될 수 있습니다. 이는 컬렉션 뷰 데이터가 런타임에 동적으로 설정되기 때문에 발생하며 그림 1에 표시된 이미지와 유사하게 보입니다.

컬렉션 뷰가 있는 위젯의 미리보기가 위젯 선택 도구에 올바르게 표시되도록 하려면 미리보기 전용으로 지정된 별도의 레이아웃 파일을 유지하는 것이 좋습니다. 이 별도의 레이아웃 파일에는 다음이 포함되어야 합니다.

  • 실제 위젯 레이아웃입니다.
  • 가짜 항목이 있는 자리표시자 컬렉션 뷰입니다. 예를 들어 여러 가짜 목록 항목이 있는 플레이스홀더 LinearLayout를 제공하여 ListView를 모방할 수 있습니다.

ListView의 예를 보여주기 위해 별도의 레이아웃 파일로 시작합니다.

// res/layout/widget_preview.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:background="@drawable/widget_background"
   android:orientation="vertical">

    // Include the actual widget layout that contains ListView.
    <include
        layout="@layout/widget_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    // The number of fake items you include depends on the values you provide
    // for minHeight or targetCellHeight in the AppWidgetProviderInfo
    // definition.

    <TextView android:text="@string/fake_item1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginVertical="?attr/appWidgetInternalPadding" />

    <TextView android:text="@string/fake_item2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginVertical="?attr/appWidgetInternalPadding" />

</LinearLayout>

AppWidgetProviderInfo 메타데이터의 previewLayout 속성을 제공할 때 미리보기 레이아웃 파일을 지정합니다. initialLayout 속성의 실제 위젯 레이아웃을 지정하고 런타임에 RemoteViews를 구성할 때 실제 위젯 레이아웃을 사용합니다.

<appwidget-provider
    previewLayout="@layout/widget_preview"
    initialLayout="@layout/widget_view" />

복잡한 목록 항목

이전 섹션의 예에서는 목록 항목이 TextView 객체이므로 가짜 목록 항목을 제공합니다. 항목이 복잡한 레이아웃인 경우 가짜 항목을 제공하는 것이 더 복잡할 수 있습니다.

widget_list_item.xml에 정의되어 있고 두 개의 TextView 객체로 구성된 목록 항목을 생각해 보세요.

<LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

    <TextView android:id="@id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/fake_title" />

    <TextView android:id="@id/content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/fake_content" />
</LinearLayout>

가짜 목록 항목을 제공하려면 레이아웃을 여러 번 포함하면 되지만, 이렇게 하면 각 목록 항목이 동일해집니다. 고유한 목록 항목을 제공하려면 다음 단계를 따르세요.

  1. 텍스트 값의 속성 집합을 만듭니다.

    <resources>
        <attr name="widgetTitle" format="string" />
        <attr name="widgetContent" format="string" />
    </resources>
    
  2. 다음 속성을 사용하여 텍스트를 설정합니다.

    <LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
        <TextView android:id="@id/title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="?widgetTitle" />
    
        <TextView android:id="@id/content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="?widgetContent" />
    </LinearLayout>
    
  3. 미리보기에 필요한 만큼 스타일을 만듭니다. 각 스타일의 값을 재정의합니다.

    <resources>
    
        <style name="Theme.Widget.ListItem">
            <item name="widgetTitle"></item>
            <item name="widgetContent"></item>
        </style>
        <style name="Theme.Widget.ListItem.Preview1">
            <item name="widgetTitle">Fake Title 1</item>
            <item name="widgetContent">Fake content 1</item>
        </style>
        <style name="Theme.Widget.ListItem.Preview2">
            <item name="widgetTitle">Fake title 2</item>
            <item name="widgetContent">Fake content 2</item>
        </style>
    
    </resources>
    
  4. 미리보기 레이아웃의 가짜 항목에 스타일을 적용합니다.

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
       android:layout_width="match_parent"
       android:layout_height="wrap_content" ...>
    
        <include layout="@layout/widget_view" ... />
    
        <include layout="@layout/widget_list_item"
            android:theme="@style/Theme.Widget.ListItem.Preview1" />
    
        <include layout="@layout/widget_list_item"
            android:theme="@style/Theme.Widget.ListItem.Preview2" />
    
    </LinearLayout>