Dieses Dokument enthält Details zur Verwendung der Vorlagen-Builder in Android Jetpack zum Erstellen von Slices.
Slice-Vorlage definieren
Slices werden mit einem ListBuilder
erstellt. Mit ListBuilder können Sie verschiedene Zeilentypen hinzufügen, die in einer Liste angezeigt werden. In diesem Abschnitt werden die einzelnen Zeilentypen und ihr Aufbau beschrieben.
SliceAction (Slice-Aktion)
Das einfachste Element einer Slice-Vorlage ist ein SliceAction
. Ein SliceAction
enthält ein Label und einen PendingIntent
und ist eines der folgenden:
- Symbolschaltfläche
- Standard-Ein/Aus-Schaltfläche
- Benutzerdefinierte Ein/Aus-Schaltfläche (ein Drawable mit Ein/Aus-Zustand)
SliceAction
wird von den im Rest dieses Abschnitts beschriebenen Vorlagen-Builder verwendet. Für SliceAction
kann ein Bildmodus definiert werden, der bestimmt, wie das Bild für die Aktion präsentiert wird:
ICON_IMAGE
: winzig und abtönbarSMALL_IMAGE
: klein, nicht abtönbarLARGE_IMAGE
: größte Größe und nicht abtönbar
HeaderBuilder
In den meisten Fällen sollten Sie mit HeaderBuilder
einen Header für Ihre Vorlage festlegen.
Ein Header kann Folgendes unterstützen:
- Titel
- Untertitel
- Untertitel der Zusammenfassung
- Primäre Aktion
Im Folgenden finden Sie einige Beispiele für Header-Konfigurationen. In den grauen Feldern werden mögliche Symbole und Positionen angezeigt, die mit einem Innenrand versehen sind:
Rendering von Headern auf verschiedenen Oberflächen
Wenn ein Slice erforderlich ist, bestimmt die Anzeigeoberfläche, wie das Slice gerendert wird. Das Rendering kann je nach Hosting-Oberfläche etwas variieren.
In kleineren Formaten wird normalerweise nur der Header angezeigt, falls vorhanden. Wenn Sie eine Zusammenfassung für die Kopfzeile angegeben haben, wird anstelle des Untertiteltexts der Zusammenfassungstext angezeigt.
Wenn Sie in der Vorlage keine Kopfzeile angegeben haben, wird normalerweise die erste Zeile angezeigt, die dem ListBuilder
hinzugefügt wird.
HeaderBuilder-Beispiel – Einfaches Listen-Slice mit Header
Kotlin
fun createSliceWithHeader(sliceUri: Uri) = list(context, sliceUri, ListBuilder.INFINITY) { setAccentColor(0xff0F9D) // Specify color for tinting icons header { title = "Get a ride" subtitle = "Ride in 4 min" summary = "Work in 1 hour 45 min | Home in 12 min" } row { title = "Home" subtitle = "12 miles | 12 min | $9.00" addEndItem( IconCompat.createWithResource(context, R.drawable.ic_home), ListBuilder.ICON_IMAGE ) } }
Java
public Slice createSliceWithHeader(Uri sliceUri) { if (getContext() == null) { return null; } // Construct the parent. ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY) .setAccentColor(0xff0F9D58) // Specify color for tinting icons. .setHeader( // Create the header and add to slice. new HeaderBuilder() .setTitle("Get a ride") .setSubtitle("Ride in 4 min.") .setSummary("Work in 1 hour 45 min | Home in 12 min.") ).addRow(new RowBuilder() // Add a row. .setPrimaryAction( createActivityAction()) // A slice always needs a SliceAction. .setTitle("Home") .setSubtitle("12 miles | 12 min | $9.00") .addEndItem(IconCompat.createWithResource(getContext(), R.drawable.ic_home), SliceHints.ICON_IMAGE) ); // Add more rows if needed... return listBuilder.build(); }
SliceActions in Headern
Slice-Header können auch SliceActions anzeigen:
Kotlin
fun createSliceWithActionInHeader(sliceUri: Uri): Slice { // Construct our slice actions. val noteAction = SliceAction.create( takeNoteIntent, IconCompat.createWithResource(context, R.drawable.ic_pencil), ICON_IMAGE, "Take note" ) val voiceNoteAction = SliceAction.create( voiceNoteIntent, IconCompat.createWithResource(context, R.drawable.ic_mic), ICON_IMAGE, "Take voice note" ) val cameraNoteAction = SliceAction.create( cameraNoteIntent, IconCompat.createWithResource(context, R.drawable.ic_camera), ICON_IMAGE, "Create photo note" ) // Construct the list. return list(context, sliceUri, ListBuilder.INFINITY) { setAccentColor(0xfff4b4) // Specify color for tinting icons header { title = "Create new note" subtitle = "Easily done with this note taking app" } addAction(noteAction) addAction(voiceNoteAction) addAction(cameraNoteAction) } }
Java
public Slice createSliceWithActionInHeader(Uri sliceUri) { if (getContext() == null) { return null; } // Construct our slice actions. SliceAction noteAction = SliceAction.create(takeNoteIntent, IconCompat.createWithResource(getContext(), R.drawable.ic_pencil), ListBuilder.ICON_IMAGE, "Take note"); SliceAction voiceNoteAction = SliceAction.create(voiceNoteIntent, IconCompat.createWithResource(getContext(), R.drawable.ic_mic), ListBuilder.ICON_IMAGE, "Take voice note"); SliceAction cameraNoteAction = SliceAction.create(cameraNoteIntent, IconCompat.createWithResource(getContext(), R.drawable.ic_camera), ListBuilder.ICON_IMAGE, "Create photo note"); // Construct the list. ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY) .setAccentColor(0xfff4b400) // Specify color for tinting icons .setHeader(new HeaderBuilder() // Construct the header. .setTitle("Create new note") .setSubtitle("Easily done with this note taking app") ) .addRow(new RowBuilder() .setTitle("Enter app") .setPrimaryAction(createActivityAction()) ) // Add the actions to the ListBuilder. .addAction(noteAction) .addAction(voiceNoteAction) .addAction(cameraNoteAction); return listBuilder.build(); }
RowBuilder
Sie können eine Inhaltszeile mithilfe eines RowBuilder
erstellen. Eine Zeile kann Folgendes unterstützen:
- Titel
- Untertitel
- Startelement: SliceAction, Symbol oder Zeitstempel
- Endelemente: SliceAction, Symbol oder Zeitstempel
- Primäre Aktion
Zeileninhalte lassen sich auf verschiedene Arten kombinieren. Dabei gelten die folgenden Einschränkungen:
- Startelemente werden nicht in der ersten Zeile eines Slice angezeigt.
- Endelemente dürfen nicht gleichzeitig
SliceAction
- undIcon
-Objekte sein - Eine Zeile darf nur einen Zeitstempel enthalten
In den folgenden Bildern sehen Sie Beispielzeilen für Inhalte. Die grauen Felder zeigen mögliche Symbole und die entsprechenden Positionen an:
RowBuilder-Beispiel – WLAN-Ein/Aus-Schaltfläche
Das folgende Beispiel zeigt eine Zeile mit einer primären Aktion und einer Standard-Ein/Aus-Schaltfläche.
Kotlin
fun createActionWithActionInRow(sliceUri: Uri): Slice { // Primary action - open wifi settings. val wifiAction = SliceAction.create( wifiSettingsPendingIntent, IconCompat.createWithResource(context, R.drawable.ic_wifi), ICON_IMAGE, "Wi-Fi Settings" ) // Toggle action - toggle wifi. val toggleAction = SliceAction.createToggle( wifiTogglePendingIntent, "Toggle Wi-Fi", isConnected /* isChecked */ ) // Create the parent builder. return list(context, wifiUri, ListBuilder.INFINITY) { setAccentColor(0xff4285) // Specify color for tinting icons / controls. row { title = "Wi-Fi" primaryAction = wifiAction addEndItem(toggleAction) } } }
Java
public Slice createActionWithActionInRow(Uri sliceUri) { if (getContext() == null) { return null; } // Primary action - open wifi settings. SliceAction primaryAction = SliceAction.create(wifiSettingsPendingIntent, IconCompat.createWithResource(getContext(), R.drawable.ic_wifi), ListBuilder.ICON_IMAGE, "Wi-Fi Settings" ); // Toggle action - toggle wifi. SliceAction toggleAction = SliceAction.createToggle(wifiTogglePendingIntent, "Toggle Wi-Fi", isConnected /* isChecked */); // Create the parent builder. ListBuilder listBuilder = new ListBuilder(getContext(), wifiUri, ListBuilder.INFINITY) // Specify color for tinting icons / controls. .setAccentColor(0xff4285f4) // Create and add a row. .addRow(new RowBuilder() .setTitle("Wi-Fi") .setPrimaryAction(primaryAction) .addEndItem(toggleAction)); // Build the slice. return listBuilder.build(); }
GridBuilder
Mit GridBuilder
können Sie ein Inhaltsraster erstellen. Ein Raster kann die folgenden Bildtypen unterstützen:
ICON_IMAGE
: winzig und abtönbarSMALL_IMAGE
: klein, nicht abtönbarLARGE_IMAGE
: größte Größe und nicht abtönbar
Eine Zelle im Raster wird mit einem CellBuilder
konstruiert. Eine Zelle kann bis zu zwei Textzeilen und ein Bild unterstützen. Eine Zelle darf nicht leer sein.
In den folgenden Bildern sehen Sie Beispiele für Raster:
GridRowBuilder-Beispiel – Restaurants in der Nähe
Das folgende Beispiel zeigt eine Rasterzeile, die Bilder und Text enthält.
Kotlin
fun createSliceWithGridRow(sliceUri: Uri): Slice { // Create the parent builder. return list(context, sliceUri, ListBuilder.INFINITY) { header { title = "Famous restaurants" primaryAction = SliceAction.create( pendingIntent, icon, ListBuilder.ICON_IMAGE, "Famous restaurants" ) } gridRow { cell { addImage(image1, LARGE_IMAGE) addTitleText("Top Restaurant") addText("0.3 mil") contentIntent = intent1 } cell { addImage(image2, LARGE_IMAGE) addTitleText("Fast and Casual") addText("0.5 mil") contentIntent = intent2 } cell { addImage(image3, LARGE_IMAGE) addTitleText("Casual Diner") addText("0.9 mi") contentIntent = intent3 } cell { addImage(image4, LARGE_IMAGE) addTitleText("Ramen Spot") addText("1.2 mi") contentIntent = intent4 } } } }
Java
public Slice createSliceWithGridRow(Uri sliceUri) { if (getContext() == null) { return null; } // Create the parent builder. ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY) .setHeader( // Create the header. new HeaderBuilder() .setTitle("Famous restaurants") .setPrimaryAction(SliceAction .create(pendingIntent, icon, ListBuilder.ICON_IMAGE, "Famous restaurants")) ) // Add a grid row to the list. .addGridRow(new GridRowBuilder() // Add cells to the grid row. .addCell(new CellBuilder() .addImage(image1, ListBuilder.LARGE_IMAGE) .addTitleText("Top Restaurant") .addText("0.3 mil") .setContentIntent(intent1) ).addCell(new CellBuilder() .addImage(image2, ListBuilder.LARGE_IMAGE) .addTitleText("Fast and Casual") .addText("0.5 mil") .setContentIntent(intent2) ) .addCell(new CellBuilder() .addImage(image3, ListBuilder.LARGE_IMAGE) .addTitleText("Casual Diner") .addText("0.9 mi") .setContentIntent(intent3)) .addCell(new CellBuilder() .addImage(image4, ListBuilder.LARGE_IMAGE) .addTitleText("Ramen Spot") .addText("1.2 mi") .setContentIntent(intent4)) // Every slice needs a primary action. .setPrimaryAction(createActivityAction()) ); return listBuilder.build(); }
RangeBuilder
Mit einem RangeBuilder
können Sie eine Zeile erstellen, die entweder eine Fortschrittsanzeige oder einen Eingabebereich wie einen Schieberegler enthält.
Beispiele für den Fortschritt und Schieberegler sind in den folgenden Bildern zu sehen:
RangeBuilder-Beispiel – Slider
Das folgende Beispiel zeigt, wie Sie mithilfe eines InputRangeBuilder
ein Slice erstellen, das einen Volume-Schieberegler enthält. Verwenden Sie addRange()
, um eine Fortschrittszeile zu erstellen.
Kotlin
fun createSliceWithRange(sliceUri: Uri): Slice { return list(context, sliceUri, ListBuilder.INFINITY) { inputRange { title = "Ring Volume" inputAction = volumeChangedPendingIntent max = 100 value = 30 } } }
Java
public Slice createSliceWithRange(Uri sliceUri) { if (getContext() == null) { return null; } // Construct the parent. ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY) .addRow(new RowBuilder() // Every slice needs a row. .setTitle("Enter app") // Every slice needs a primary action. .setPrimaryAction(createActivityAction()) ) .addInputRange(new InputRangeBuilder() // Create the input row. .setTitle("Ring Volume") .setInputAction(volumeChangedPendingIntent) .setMax(100) .setValue(30) ); return listBuilder.build(); }
Verzögerte Inhalte
Sie sollten ein Slice so schnell wie möglich von SliceProvider.onBindSlice()
zurückgeben.
Zeitintensive Aufrufe können zu Darstellungsproblemen wie Flackern oder einer abrupten Größenanpassung führen.
Wenn Sie Slice-Inhalte haben, die nicht schnell geladen werden können, können Sie den Slice mit Platzhalterinhalten erstellen und im Builder darauf hinweisen, dass der Inhalt geladen wird. Sobald der Inhalt zur Anzeige bereit ist, rufen Sie getContentResolver().notifyChange(sliceUri, null)
mit Ihrem Slice-URI auf. Dies führt zu einem weiteren Aufruf von SliceProvider.onBindSlice()
, bei dem Sie das Slice noch einmal mit neuem Inhalt erstellen können.
Beispiel für verzögerten Inhalt – Zur Arbeit fahren
In der Zeile „Zur Arbeit fahren“ unten wird die Entfernung zur Arbeit dynamisch bestimmt und ist möglicherweise nicht sofort verfügbar. Der Beispielcode zeigt, wie beim Laden des Inhalts ein Nulluntertitel als Platzhalter verwendet wird:
Kotlin
fun createSliceShowingLoading(sliceUri: Uri): Slice { // We’re waiting to load the time to work so indicate that on the slice by // setting the subtitle with the overloaded method and indicate true. return list(context, sliceUri, ListBuilder.INFINITY) { row { title = "Ride to work" setSubtitle(null, true) addEndItem(IconCompat.createWithResource(context, R.drawable.ic_work), ICON_IMAGE) } } }
Java
public Slice createSliceShowingLoading(Uri sliceUri) { if (getContext() == null) { return null; } // Construct the parent. ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY) // Construct the row. .addRow(new RowBuilder() .setPrimaryAction(createActivityAction()) .setTitle("Ride to work") // We’re waiting to load the time to work so indicate that on the slice by // setting the subtitle with the overloaded method and indicate true. .setSubtitle(null, true) .addEndItem(IconCompat.createWithResource(getContext(), R.drawable.ic_work), ListBuilder.ICON_IMAGE) ); return listBuilder.build(); } private SliceAction createActivityAction() { return SliceAction.create( PendingIntent.getActivity( getContext(), 0, new Intent(getContext(), MainActivity.class), 0 ), IconCompat.createWithResource(getContext(), R.drawable.ic_home), ListBuilder.ICON_IMAGE, "Enter app" ); }
Deaktiviertes Scrollen im Slice behandeln
Die Oberfläche, auf der Ihre Slice-Vorlage zu sehen ist, unterstützt möglicherweise kein Scrollen innerhalb der Vorlage. In diesem Fall werden einige Ihrer Inhalte möglicherweise nicht angezeigt.
Betrachten Sie als Beispiel einen Slice, der eine Liste von WLAN-Netzwerken zeigt:
Wenn die WLAN-Liste lang ist und das Scrollen deaktiviert ist, können Sie die Schaltfläche Mehr anzeigen hinzufügen, damit Nutzer alle Elemente in der Liste sehen können. Sie können diese Schaltfläche mit addSeeMoreAction()
hinzufügen, wie im folgenden Beispiel gezeigt:
Kotlin
fun seeMoreActionSlice(sliceUri: Uri) = list(context, sliceUri, ListBuilder.INFINITY) { // [START_EXCLUDE] // [END_EXCLUDE] setSeeMoreAction(seeAllNetworksPendingIntent) // [START_EXCLUDE] // [END_EXCLUDE] }
Java
public Slice seeMoreActionSlice(Uri sliceUri) { if (getContext() == null) { return null; } ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY); // [START_EXCLUDE] listBuilder.addRow(new RowBuilder() .setTitle("Hello") .setPrimaryAction(createActivityAction()) ); // [END_EXCLUDE] listBuilder.setSeeMoreAction(seeAllNetworksPendingIntent); // [START_EXCLUDE] // [END_EXCLUDE] return listBuilder.build(); }
Dies wird wie in der folgenden Abbildung dargestellt angezeigt:
Wenn Sie auf Mehr anzeigen tippen, wird seeAllNetworksPendingIntent
gesendet.
Wenn Sie eine benutzerdefinierte Nachricht oder Zeile bereitstellen möchten, können Sie alternativ einen RowBuilder hinzufügen:
Kotlin
fun seeMoreRowSlice(sliceUri: Uri) = list(context, sliceUri, ListBuilder.INFINITY) { // [START_EXCLUDE] // [END_EXCLUDE] seeMoreRow { title = "See all available networks" addEndItem( IconCompat.createWithResource(context, R.drawable.ic_right_caret), ICON_IMAGE ) primaryAction = SliceAction.create( seeAllNetworksPendingIntent, IconCompat.createWithResource(context, R.drawable.ic_wifi), ListBuilder.ICON_IMAGE, "Wi-Fi Networks" ) } }
Java
public Slice seeMoreRowSlice(Uri sliceUri) { if (getContext() == null) { return null; } ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY) // [START_EXCLUDE] .addRow(new RowBuilder() .setTitle("Hello") .setPrimaryAction(createActivityAction()) ) // [END_EXCLUDE] .setSeeMoreRow(new RowBuilder() .setTitle("See all available networks") .addEndItem(IconCompat .createWithResource(getContext(), R.drawable .ic_right_caret), ListBuilder.ICON_IMAGE) .setPrimaryAction(SliceAction.create(seeAllNetworksPendingIntent, IconCompat.createWithResource(getContext(), R.drawable.ic_wifi), ListBuilder.ICON_IMAGE, "Wi-Fi Networks")) ); // [START_EXCLUDE] // [END_EXCLUDE] return listBuilder.build(); }
Die über diese Methode hinzugefügte Zeile oder Aktion wird nur angezeigt, wenn eine der folgenden Bedingungen erfüllt ist:
- Der Vortragende Ihres Slice hat das Scrollen in der Ansicht deaktiviert
- Im verfügbaren Platz können nicht alle Zeilen angezeigt werden
Vorlagen kombinieren
Sie können einen umfangreichen, dynamischen Slice erstellen, indem Sie mehrere Zeilentypen kombinieren. Ein Slice kann beispielsweise eine Kopfzeile, ein Raster mit einem einzelnen Bild und ein Raster mit zwei Textzellen enthalten.
Hier sehen Sie ein Slice mit einer Kopfzeile und einem Raster, das drei Zellen enthält.