Dodawanie wygenerowanych podglądów do selektora widżetów

Wygenerowane podglądy widżetów umożliwiają tworzenie dynamicznych, spersonalizowanych podglądów widżetów, które dokładnie odzwierciedlają sposób, w jaki będą one wyświetlane na ekranie głównym użytkownika. Są one udostępniane za pomocą interfejsu Push API, co oznacza, że aplikacja udostępnia podgląd w dowolnym momencie swojego cyklu życia bez otrzymywania wyraźnego żądania od hosta widżetu.

Aby ulepszyć wybieranie widżetów w aplikacji, udostępnij wygenerowaną podgląd widżetu na urządzeniach z Androidem 15 i nowszym, skalowany podgląd widżetu (określając previewLayout) na urządzeniach z Androidem w wersji od 12 do 14 oraz previewImage w przypadku starszych wersji.

Więcej informacji znajdziesz w filmie Wzbogać aplikację o aktualizacje na żywo i widżety w YouTube.

Konfigurowanie aplikacji pod kątem wygenerowanych podglądów widżetów

Aby wyświetlać podglądy wygenerowanych widżetów na urządzeniu z Androidem 15 lub nowszym, najpierw ustaw wartość compileSdk na 35 lub nowszą w pliku modułu build.gradle, aby mieć możliwość przekazywania wartości RemoteViews do selektora widżetów.

Aplikacje mogą następnie używać setWidgetPreviewGlanceAppWidgetManager lub AppWidgetManager. Aby zapobiegać nadużyciom i ograniczać problemy z kondycją systemu, interfejs setWidgetPreview ma ograniczenie liczby żądań. Domyślny limit to około 2 wywołań na godzinę.

Generowanie zaktualizowanego podglądu za pomocą Jetpack Glance

W przypadku widżetów utworzonych za pomocą Jetpack Glance wykonaj te czynności:

  1. Zastąp funkcję GlanceAppWidget.providePreview, aby udostępnić treści do podglądu. Podobnie jak w provideGlance, załaduj dane aplikacji i przekaż je do funkcji kompozycyjnej treści widżetu, aby w podglądzie wyświetlały się prawidłowe dane. W przeciwieństwie do provideGlance jest to pojedyncza kompozycja bez ponownej kompozycji ani efektów.

  2. Wywołaj GlanceAppWidgetManager.setWidgetPreviews, aby wygenerować i opublikować podgląd.

System nie wywołuje zwrotnie funkcji, aby udostępnić podgląd, więc aplikacja musi sama decydować, kiedy wywołać funkcję setWidgetPreviews. Strategia aktualizacji zależy od przypadku użycia widżetu:

  • Jeśli widżet zawiera statyczne informacje lub jest skrótem, ustaw podgląd przy pierwszym uruchomieniu aplikacji.
  • Podgląd możesz ustawić, gdy aplikacja będzie zawierać dane, np. po zalogowaniu się użytkownika lub po początkowej konfiguracji.
  • Możesz skonfigurować zadanie okresowe, aby aktualizować podglądy z wybraną częstotliwością.

Rozwiązywanie problemów z wygenerowanymi podglądami

Częstym problemem jest to, że po wygenerowaniu podglądu na obrazie podglądu mogą nie być widoczne obrazy, ikony ani inne komponenty kompozycyjne w porównaniu z rozmiarem widżetu. Rozmiar elementu do przeciągania jest określony przez parametry targetCellWidthtargetCellHeight (jeśli są podane) lub przez parametry minWidthminHeightpliku informacji o dostawcy widżetu aplikacji.

Dzieje się tak, ponieważ Android domyślnie renderuje tylko elementy kompozycyjne widoczne przy minimalnym rozmiarze widżetu. Innymi słowy, Android domyślnie ustawia wartość previewSizeMode na SizeMode.Single. Używa android:minHeightandroid:minWidthpliku XML z informacjami o widżecie aplikacji, aby określić, które komponenty mają być rysowane.

Aby rozwiązać ten problem, zastąp previewSizeMode w GlanceAppWidget i ustaw wartość SizeMode.Responsive, podając zestaw wartości DpSize. Dzięki temu Android będzie wiedzieć, jakie rozmiary układu ma renderować w podglądzie, co zapewni prawidłowe wyświetlanie wszystkich elementów.

Optymalizuj pod kątem konkretnych formatów. Podaj 1 lub 2 rozmiary, zaczynając od minimalnego i uwzględniając punkty przerwania widżetu. Określ co najmniej 1 obraz dla zachowania zgodności wstecznej. Odpowiednie minimalne wartości DP dla różnych rozmiarów siatki znajdziesz w wytycznych dotyczących projektowania widżetów.

Generowanie zaktualizowanego podglądu bez Jetpack Glance

Możesz korzystać z RemoteViews bez funkcji Glance. W tym przykładzie wczytywany jest zasób układu widżetu XML i ustawiany jako podgląd. Aby setWidgetPreview było widoczne jako metoda w tym fragmencie kodu, ustawienie kompilacji compileSdk musi mieć wartość 35 lub wyższą.

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

Dodawanie skalowalnych podglądów widżetów do selektora widżetów

Od Androida 12 podgląd widżetu wyświetlany w selektorze widżetów jest skalowalny. Podajesz go jako układ XML ustawiony na domyślny rozmiar widżetu. Wcześniej podgląd widżetu był statycznym zasobem rysowalnym, co w niektórych przypadkach powodowało, że podgląd nie odzwierciedlał dokładnie wyglądu widżetów po dodaniu ich do ekranu głównego.

Aby wdrożyć skalowalne podglądy widżetów, użyj atrybutu previewLayout elementu appwidget-provider, aby zamiast tego podać układ XML:

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

Zalecamy używanie tego samego układu co rzeczywisty widżet, z realistycznymi wartościami domyślnymi lub testowymi. Większość aplikacji używa tych samych previewLayoutinitialLayout. Wskazówki dotyczące tworzenia dokładnych układów podglądu znajdziesz w następnej sekcji na tej stronie.

Zalecamy podanie atrybutów previewLayoutpreviewImage, aby w przypadku, gdy urządzenie użytkownika nie obsługuje atrybutu previewLayout, aplikacja mogła użyć atrybutu previewImage. Atrybut previewLayout ma pierwszeństwo przed atrybutem previewImage.

Zgodność wsteczna z podglądami widżetów

Aby selektory widżetów na Androidzie 11 (API na poziomie 30) lub starszym wyświetlały podglądy widżetu lub jako rezerwę dla wygenerowanych podglądów, określ atrybut previewImage.

Jeśli zmienisz wygląd widżetu, zaktualizuj obraz podglądu.

Tworzenie dokładnych podglądów zawierających elementy dynamiczne

Ilustracja 1. Podgląd widżetu bez elementów listy.

W tej sekcji opisujemy zalecane podejście do wyświetlania wielu elementów w podglądzie widżetu z widokiem kolekcji, czyli widżetu, który korzysta z ListView, GridView lub StackView. Nie dotyczy to wygenerowanych podglądów widżetów.

Jeśli widżet korzysta z jednego z tych widoków, utworzenie skalowalnego podglądu przez bezpośrednie podanie rzeczywistego układu widżetu pogorszy komfort użytkowania, gdy podgląd widżetu nie będzie wyświetlać żadnych elementów. Dzieje się tak, ponieważ dane widoku kolekcji są ustawiane dynamicznie w czasie działania programu i wyglądają podobnie do obrazu pokazanego na rysunku 1.

Aby podglądy widżetów z widokami kolekcji wyświetlały się prawidłowo w selektorze widżetów, zalecamy używanie osobnego pliku układu przeznaczonego tylko do podglądu. Ten oddzielny plik układu powinien zawierać:

  • Rzeczywisty układ widżetu.
  • Widok kolekcji z obiektami zastępczymi i fałszywymi elementami. Możesz na przykład naśladować ListView, podając obiekt zastępczy LinearLayout z kilkoma fałszywymi elementami listy.

Aby zilustrować przykład ListView, zacznij od osobnego pliku układu:

// 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>

Podaj plik układu podglądu, gdy podajesz atrybut previewLayout metadanych AppWidgetProviderInfo. Nadal określasz rzeczywisty układ widżetu dla atrybutu initialLayout i używasz rzeczywistego układu widżetu podczas tworzenia RemoteViews w czasie działania.

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

Złożone elementy listy

W przykładzie w poprzedniej sekcji podano przykładowe elementy listy, ponieważ elementy listy są obiektami TextView. W przypadku złożonych układów dostarczanie fałszywych elementów może być trudniejsze.

Rozważmy element listy zdefiniowany w widget_list_item.xml, który składa się z 2 obiektów 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>

Aby podać fałszywe elementy listy, możesz uwzględnić układ wiele razy, ale spowoduje to, że każdy element listy będzie identyczny. Aby podać unikalne elementy listy, wykonaj te czynności:

  1. Utwórz zestaw atrybutów dla wartości tekstowych:

    <resources>
        <attr name="widgetTitle" format="string" />
        <attr name="widgetContent" format="string" />
    </resources>
    
  2. Aby ustawić tekst, użyj tych atrybutów:

    <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. Utwórz tyle stylów, ile jest potrzebnych do podglądu. Zdefiniuj ponownie wartości w każdym stylu:

    <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. Zastosuj style do przykładowych produktów w układzie podglądu:

    <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>