Ulepsz swój widżet

Wypróbuj Compose
Jetpack Compose to zalecany zestaw narzędzi do tworzenia interfejsu na Androidzie. Dowiedz się, jak tworzyć widżety za pomocą interfejsów API w stylu Compose.

Ta strona zawiera szczegółowe informacje o opcjonalnych ulepszeniach widżetów, które są dostępne od Androida 12 (poziom API 31). Te funkcje są opcjonalne, ale łatwe do wdrożenia i poprawiają komfort użytkowników.

Używanie kolorów dynamicznych

Od Androida 12 widżet może używać kolorów motywu urządzenia w przypadku przycisków, tła i innych komponentów. Zapewnia to płynniejsze przejścia i spójność między różnymi widżetami.

Kolory dynamiczne można uzyskać na 2 sposoby:

Gdy motyw jest ustawiony w układzie głównym, możesz użyć typowych atrybutów koloru w układzie głównym lub w dowolnym z jego elementów podrzędnych, aby wybrać kolory dynamiczne.

Oto kilka przykładów atrybutów koloru, których możesz użyć:

  • ?attr/primary
  • ?attr/primaryContainer
  • ?attr/onPrimary
  • ?attr/onPrimaryContainer

W tym przykładzie używającym motywu Material 3 kolor motywu urządzenia to „purpurowy”. Kolor uzupełniający i tło widżetu dostosowują się do trybów jasnego i ciemnego, jak pokazano na rysunkach 1 i 2.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="?attr/colorPrimaryContainer"
  android:theme="@style/Theme.Material3.DynamicColors.DayNight">

  <ImageView
    ...
    app:tint="?attr/colorPrimaryContainer"
    android:src="@drawable/ic_partly_cloudy" />

    <!-- Other widget content. -->

</LinearLayout>
Widżet w trybie jasnym
Rysunek 1. Widżet w trybie jasnym.
Widżety w trybie ciemnym
Rysunek 2. Widżet w trybie ciemnym.

Zgodność wsteczna z kolorami dynamicznymi

Kolory dynamiczne są dostępne tylko na urządzeniach z Androidem 12 lub nowszym. Aby zapewnić niestandardowy motyw w starszych wersjach, utwórz motyw domyślny ze spersonalizowanymi kolorami i nowym kwalifikatorem (values-v31) za pomocą atrybutów motywu domyślnego.

Oto przykład użycia motywu Material 3:

/values/styles.xml

<resources>
  <style name="MyWidgetTheme" parent="Theme.Material3.DynamicColors.DayNight">
    <!-- Override default colorBackground attribute with custom color. -->
    <item name="android:colorBackground">@color/my_background_color</item>

    <!-- Add other colors/attributes. -->

  </style>
</resources>

/values-v31/styles.xml

<resources>
  <!-- Do not override any color attribute. -->
  <style name="MyWidgetTheme" parent="Theme.Material3.DynamicColors.DayNight" />
</resources>

/layout/my_widget_layout.xml

<resources>
  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    android:background="?android:attr/colorBackground"
    android:theme="@style/MyWidgetTheme" />
</resources>

Włączanie obsługi głosu

Akcje w aplikacji umożliwiają Asystentowi Google wyświetlanie widżetów w odpowiedzi na odpowiednie polecenia głosowe użytkownika. Konfigurując swój widżet tak, aby reagował na wbudowane intencje (BII), możesz sprawić, że Twoja aplikacja będzie proaktywnie wyświetlać widżety na powierzchniach Asystenta, takich jak Android i Android Auto. Użytkownicy mogą przypinać widżety wyświetlane przez Asystenta do swojego programu uruchamiającego, co zachęca do dalszego korzystania z nich.

Możesz na przykład skonfigurować widżet podsumowania treningu w aplikacji do ćwiczeń aby realizować polecenia głosowe użytkownika, które wywołują GET_EXERCISE_OBSERVATION BII. Asystent proaktywnie wyświetla Twój widżet, gdy użytkownicy wywołują tę BII, wysyłając prośby takie jak „OK Google, ile kilometrów przebiegłem w tym tygodniu w aplikacji ExampleApp?”

Istnieją dziesiątki BII obejmujących kilka kategorii interakcji z użytkownikiem, dzięki czemu niemal każda aplikacja na Androida może ulepszyć swoje widżety pod kątem obsługi głosu. Aby rozpocząć, przeczytaj artykuł Integrowanie akcji w aplikacji z widżetami na Androida.

Dodawanie nazwy do widżetu

Widżety muszą mieć unikalną nazwę, gdy są wyświetlane w selektorze widżetów.

Nazwy widżetów są wczytywane z atrybutu label elementu receiver widżetu w pliku AndroidManifest.xml.

<receiver
    ….
   android:label="Memories">
     ….
</receiver>

Dodawanie opisu widżetu

Od Androida 12 możesz podać opis, który będzie wyświetlany w selektorze widżetów.

Obraz przedstawiający selektor widżetów z widżetem i jego opisem
Rysunek 3. Przykładowy selektor widżetów pokazujący widżet i jego opis.

Aby podać opis widżetu, użyj atrybutu description elementu &lt;appwidget-provider&gt;:

<appwidget-provider
    android:description="@string/my_widget_description">
</appwidget-provider>

W starszych wersjach Androida możesz użyć atrybutu descriptionRes, ale jest on ignorowany przez selektor widżetów.

Włączanie płynniejszych przejść

Od Androida 12 programy uruchamiające zapewniają płynniejsze przejście, gdy użytkownik uruchamia aplikację z widżetu.

Aby włączyć to ulepszone przejście, użyj @android:id/background lub android.R.id.background, aby zidentyfikować element tła:

// Top-level layout of the widget.
<LinearLayout
    android:id="@android:id/background">
</LinearLayout>

Aplikacja może używać @android:id/background w starszych wersjach Androida bez powodowania błędów, ale jest on ignorowany.

Używanie modyfikacji RemoteViews w czasie działania

Od Androida 12 możesz korzystać z kilku metod RemoteViews, które umożliwiają modyfikowanie atrybutów RemoteViews w czasie działania. Pełną listę dodanych metod znajdziesz w dokumentacji interfejsu API RemoteViews.

Poniższy przykład kodu pokazuje, jak używać kilku z tych metod.

Kotlin

// Set the colors of a progress bar at runtime.
remoteView.setColorStateList(R.id.progress, "setProgressTintList", createProgressColorStateList())

// Specify exact sizes for margins.
remoteView.setViewLayoutMargin(R.id.text, RemoteViews.MARGIN_END, 8f, TypedValue.COMPLEX_UNIT_DP)

Java

// Set the colors of a progress bar at runtime.
remoteView.setColorStateList(R.id.progress, "setProgressTintList", createProgressColorStateList());

// Specify exact sizes for margins.
remoteView.setViewLayoutMargin(R.id.text, RemoteViews.MARGIN_END, 8f, TypedValue.COMPLEX_UNIT_DP);