생성된 위젯 미리보기를 사용하면 위젯이 사용자의 홈 화면에 표시되는 방식을 정확하게 반영하는 동적이고 개인화된 위젯 미리보기를 만들 수 있습니다. 이러한 미리보기는 푸시 API를 통해 제공됩니다. 즉, 앱은 위젯 호스트로부터 명시적 요청을 받지 않고도 수명 주기 중 언제든지 미리보기를 제공합니다.
앱의 위젯 선택 도구 환경을 개선하려면 Android 15 이상 기기에서는 생성된 위젯 미리보기를, Android 12~Android 14 기기에서는 확장된 위젯 미리보기(previewLayout
지정)를, 이전 버전에서는 previewImage
를 제공하세요.
자세한 내용은 YouTube의 실시간 업데이트 및 위젯으로 앱 개선을 참고하세요.
생성된 위젯 미리보기를 위한 앱 설정
Android 15 이상 기기에서 생성된 위젯 미리보기를 표시하려면 먼저 모듈 build.gradle
파일에서 compileSdk
값을 35 이상으로 설정하여 위젯 선택 도구에 RemoteViews
를 제공할 수 있도록 합니다.
그러면 앱이 GlanceAppWidgetManager
또는 AppWidgetManager
에서 setWidgetPreview
를 사용할 수 있습니다. 악용을 방지하고 시스템 상태 문제를 완화하기 위해 setWidgetPreview
는 비율 제한 API입니다. 기본 제한은 시간당 약 2회 호출입니다.
Jetpack Glance로 업데이트된 미리보기 생성
Jetpack Glance로 빌드된 위젯의 경우 다음을 실행합니다.
GlanceAppWidget.providePreview
함수를 재정의하여 미리보기에 사용할 컴포저블 콘텐츠를 제공합니다.provideGlance
에서와 마찬가지로 앱의 데이터를 로드하고 위젯의 콘텐츠 컴포저블에 전달하여 미리보기에 정확한 데이터가 표시되도록 합니다.provideGlance
와 달리 재구성이나 효과가 없는 단일 컴포지션입니다.GlanceAppWidgetManager.setWidgetPreviews
를 호출하여 미리보기를 생성하고 게시합니다.
미리보기를 제공하는 시스템의 콜백이 없으므로 앱에서 setWidgetPreviews
를 호출할 시기를 결정해야 합니다. 업데이트 전략은 위젯의 사용 사례에 따라 달라집니다.
- 위젯에 정적 정보가 있거나 빠른 작업인 경우 앱이 처음 실행될 때 미리보기를 설정합니다.
- 앱에 데이터가 있는 경우(예: 사용자가 로그인하거나 초기 설정한 후) 미리보기를 설정할 수 있습니다.
- 선택한 빈도로 미리보기를 업데이트하는 주기적 작업을 설정할 수 있습니다.
생성된 미리보기 문제 해결
일반적인 문제는 미리보기를 생성한 후 위젯의 드롭 크기에 비해 미리보기 이미지에서 이미지, 아이콘 또는 기타 컴포저블이 누락될 수 있다는 것입니다. 이 드롭 크기는 targetCellWidth
및 targetCellHeight
(지정된 경우) 또는 앱 위젯 제공자 정보 파일의 minWidth
및 minHeight
에 의해 정의됩니다.
이는 Android가 기본적으로 위젯의 최소 크기에서 보이는 컴포저블만 렌더링하기 때문에 발생합니다. 즉, Android는 기본적으로 previewSizeMode
을 SizeMode.Single
로 설정합니다. 앱 위젯 제공자 정보 XML에서 android:minHeight
및 android:minWidth
을 사용하여 그릴 컴포저블을 결정합니다.
이 문제를 해결하려면 GlanceAppWidget
에서 previewSizeMode
를 재정의하고 SizeMode.Responsive
로 설정하여 DpSize
값 집합을 제공하세요. 이렇게 하면 Android에 미리보기를 렌더링하는 데 필요한 모든 레이아웃 크기가 표시되어 모든 요소가 올바르게 표시됩니다.
특정 폼 팩터에 맞게 최적화합니다. 최소 크기부터 시작하여 위젯의 중단점을 따르는 크기를 1~2개 제공합니다. 이전 버전과의 호환성을 위해 이미지를 하나 이상 지정합니다. 다양한 그리드 크기에 적합한 최소 DP 값은 위젯 디자인 안내에서 확인할 수 있습니다.
Jetpack Glance 없이 업데이트된 미리보기 생성
글랜스 없이 RemoteViews
를 사용할 수 있습니다. 다음 예에서는 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
속성을 지정합니다.
위젯의 모양을 변경하면 미리보기 이미지를 업데이트합니다.
동적 항목이 포함된 정확한 미리보기 만들기

이 섹션에서는 컬렉션 뷰가 있는 위젯, 즉 ListView
, GridView
또는 StackView
를 사용하는 위젯의 위젯 미리보기에 여러 항목을 표시하는 권장 방법을 설명합니다. 생성된 위젯 미리보기에는 적용되지 않습니다.
위젯이 이러한 뷰 중 하나를 사용하는 경우 실제 위젯 레이아웃을 직접 제공하여 확장 가능한 미리보기를 만들면 위젯 미리보기에 항목이 표시되지 않을 때 환경이 저하됩니다. 이는 컬렉션 뷰 데이터가 런타임에 동적으로 설정되기 때문에 발생하며, 그림 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_previe"
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>
가짜 목록 항목을 제공하려면 레이아웃을 여러 번 포함하면 되지만 이렇게 하면 각 목록 항목이 동일해집니다. 고유한 목록 항목을 제공하려면 다음 단계를 따르세요.
텍스트 값의 속성 집합을 만듭니다.
<resources> <attr name="widgetTitle" format="string" /> <attr name="widgetContent" format="string" /> </resources>
다음 속성을 사용하여 텍스트를 설정합니다.
<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>
미리보기에 필요한 만큼 스타일을 만듭니다. 각 스타일의 값을 재정의합니다.
<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>
미리보기 레이아웃의 가짜 항목에 스타일을 적용합니다.
<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>