Vorlagen für App-Teile

Dieses Dokument enthält Details zur Verwendung der Vorlagen-Builder in Android Jetpack zum Erstellen von Slices

Slice-Vorlage definieren

Segmente werden mithilfe eines ListBuilder ListBuilder können Sie verschiedene Arten von Zeilen hinzufügen, die in einer Liste angezeigt werden. Dieses werden die einzelnen Zeilentypen und deren Konstruktion beschrieben.

SliceAction

Das grundlegendste Element einer Slice-Vorlage ist ein SliceAction Ein SliceAction enthält ein Label zusammen mit einem PendingIntent und gehört zu den Folgendes:

  • Symbolschaltfläche
  • Standard-Ein/Aus-Schaltfläche
  • Benutzerdefinierte Ein/Aus-Schaltfläche (Drawable)

SliceAction wird von den im Folgenden beschriebenen Vorlagenerstellern verwendet. . Für ein SliceAction kann ein Bildmodus definiert sein, der bestimmt, wie der wird für die Aktion angezeigt:

  • ICON_IMAGE: winzige Größe und färbbar
  • SMALL_IMAGE: klein und nicht verfärbbar
  • LARGE_IMAGE: größte Größe und nicht färbbar

HeaderBuilder

In den meisten Fällen sollten Sie eine Überschrift für Ihre Vorlage mithilfe eines HeaderBuilder Ein Header kann Folgendes unterstützen:

  • Titel
  • Untertitel
  • Zusammenfassung der Untertitel
  • Primäre Aktion

Im Folgenden finden Sie einige Beispiele für Headerkonfigurationen. Die grauen Felder werden potenzielle Symbole und Abstände:

Header-Rendering auf verschiedenen Oberflächen

Wenn ein Slice benötigt wird, bestimmt die Anzeigeoberfläche, wie das Slice gerendert wird. Segment. Das Rendering kann auf den Hosting-Oberflächen leicht variieren.

Bei kleineren Formaten wird normalerweise nur der Header angezeigt, falls vorhanden. Wenn Sie eine Zusammenfassung für die Überschrift angegeben haben, wird der Text der Zusammenfassung des Untertiteltexts.

Wenn Sie in der Vorlage keine Überschrift angegeben haben, wird die erste Zeile In der Regel wird stattdessen ListBuilder angezeigt.

Beispiel für HeaderBuilder – Einfaches Listensegment 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 Überschriften

In Slice-Headern können auch SliceActions angezeigt werden:

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 A-Reihe kann Folgendes unterstützen:

  • Titel
  • Untertitel
  • Startelement: SliceAction, Symbol oder Zeitstempel
  • Endelemente: SliceAction, Symbol oder ein Zeitstempel
  • Primäre Aktion

Sie können Zeileninhalt auf verschiedene Weise kombinieren. Beachten Sie dabei Folgendes: Einschränkungen:

  • Startelemente werden nicht in der ersten Zeile eines Slice angezeigt
  • Endelemente dürfen nicht gleichzeitig aus SliceAction-Objekten und Icon-Objekten bestehen
  • Eine Zeile darf nur einen Zeitstempel enthalten

In den folgenden Bildern sind Beispielzeilen mit Inhalten zu sehen. Die grauen Felder Potenzielle Symbole und Positionen im Abstand einblenden:

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

Sie können ein Inhaltsraster mithilfe eines GridBuilder Ein Raster kann unterstützen folgende Image-Typen:

  • ICON_IMAGE: winzige Größe und färbbar
  • SMALL_IMAGE: klein und nicht verfärbbar
  • LARGE_IMAGE: größte Größe und nicht färbbar

Eine Rasterzelle wird mithilfe eines CellBuilder A kann bis zu zwei Textzeilen und ein Bild unterstützen. Zellen dürfen nicht leer sein.

In den folgenden Bildern sind Rasterbeispiele zu sehen:

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 enthält, z. B. als Slider.

In den folgenden Bildern sind Beispiele für Fortschritt und Schieberegler zu sehen:

RangeBuilder-Beispiel – Slider

Das folgende Beispiel zeigt, wie ein Slice erstellt wird, das ein Volume enthält mit InputRangeBuilder. Um eine Fortschrittszeile zu erstellen, verwenden Sie addRange()

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 so schnell wie möglich ein Slice vom SliceProvider.onBindSlice() Zeitaufwendige Anrufe können zu Problemen mit der Anzeige führen, z. B. zu Flackern oder plötzlichen Missverständnissen. Größenanpassung.

Wenn Sie Slice-Inhalte haben, die nicht schnell geladen werden können, Segmentieren Sie mit Platzhalterinhalten und stellen Sie dabei im Builder fest, dass der Inhalt wird geladen. Sobald der Inhalt bereit zur Anzeige ist, rufen Sie getContentResolver().notifyChange(sliceUri, null) unter Verwendung des Slice-URI. Dies führt zu einem weiteren Aufruf der SliceProvider.onBindSlice(), wo Sie das Slice mit einer neuen Inhalte.

Beispiel für verspäteten Inhalt – Fahrt zur Arbeit

In der unten stehenden Zeile "Zur Arbeit fahren" wird die Entfernung zur Arbeit dynamisch ermittelt. und sind möglicherweise nicht sofort verfügbar. Der Beispielcode zeigt die Verwendung eines Null-Untertitel als Platzhalter, während der Inhalt geladen 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"
    );
}

Umgang mit deaktiviertem Scrollen im Slice

Die Oberfläche, auf der Ihre Slice-Vorlage zu sehen ist, unterstützt möglicherweise kein Scrollen im Vorlage. In diesem Fall werden einige Ihrer Inhalte möglicherweise nicht angezeigt.

Sehen Sie sich als Beispiel ein Slice mit einer Liste von WLAN-Netzwerken an:

Ist die WLAN-Liste lang und das Scrollen deaktiviert, können Sie eine Mehr anzeigen, damit Nutzer alle Artikel im Liste. Sie können diese Schaltfläche hinzufügen, indem Sie addSeeMoreAction(), Dies wird 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:

Durch Tippen auf Mehr anzeigen wird seeAllNetworksPendingIntent gesendet.

Wenn Sie eine benutzerdefinierte Nachricht oder Zeile angeben möchten, können Sie auch RowBuilder:

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: erfüllt ist:

  • Der Vortragende Ihres Slice hat das Scrollen in der Ansicht deaktiviert
  • Nicht alle Zeilen können im verfügbaren Bereich angezeigt werden

Vorlagen kombinieren

Sie können mehrere Zeilentypen kombinieren, um ein umfangreiches, dynamisches Slice zu erstellen. Für Ein Slice kann beispielsweise eine Kopfzeile, ein Raster mit einem einzelnen Bild und ein Raster mit zwei Textzellen.

Hier ist ein Slice mit einer Kopfzeile und einem Raster, das drei Zellen enthält.