앱의 위젯 선택 도구 환경을 개선하려면 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를 사용하여 설정하지 않은 경우 생성된 미리보기의 대체로도 사용됩니다.
동적 항목이 포함된 정확한 미리보기 만들기
이 섹션에서는 컬렉션 뷰가 있는 위젯, 즉 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>
가짜 목록 항목을 제공하려면 레이아웃을 여러 번 포함하면 되지만 이렇게 하면 각 목록 항목이 동일해집니다. 고유한 목록 항목을 제공하려면 다음 단계를 따르세요.
텍스트 값의 속성 집합을 만듭니다.
<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>