Die von der eingestellten androidx.leanback-Bibliothek bereitgestellten Klassen für die Medienübersicht enthalten Klassen zum Anzeigen zusätzlicher Informationen zu einem Media-Element, z. B. einer Beschreibung oder Rezensionen. Sie enthalten auch Klassen für Aktionen, die für das Element ausgeführt werden können, z. B. zum Kaufen oder Abspielen der Inhalte.
In diesem Leitfaden wird beschrieben, wie Sie eine Presenter-Klasse für Details zu Media-Elementen erstellen und wie Sie die Klasse DetailsSupportFragment
erweitern, um eine Detailansicht für ein Media-Element zu implementieren, wenn der Nutzer es auswählt.
Hinweis:Im hier gezeigten Implementierungsbeispiel wird eine zusätzliche Aktivität verwendet, um die DetailsSupportFragment
zu enthalten. Es ist jedoch möglich, die Erstellung einer zweiten Aktivität zu vermeiden, indem Sie die BrowseSupportFragment
durch eine DetailsSupportFragment
innerhalb derselben Aktivität ersetzen. Verwenden Sie dazu Fragmenttransaktionen. Weitere Informationen zur Verwendung von Fragment-Transaktionen finden Sie unter Fragment erstellen.
Details-Presenter erstellen
Im Framework für das Durchsuchen von Medien, das vom Leanback UI-Toolkit bereitgestellt wird, verwenden Sie Presenter-Objekte, um die Anzeige von Daten auf dem Bildschirm zu steuern, einschließlich der Details zu Media-Elementen.
Dazu stellt das Framework die Klasse AbstractDetailsDescriptionPresenter
bereit, die eine nahezu vollständige Implementierung des Presenters für die Details von Media-Elementen ist. Sie müssen lediglich die Methode onBindDescription()
implementieren, um die Ansichtsfelder an Ihre Datenobjekte zu binden, wie im folgenden Codebeispiel gezeigt:
Kotlin
class DetailsDescriptionPresenter : AbstractDetailsDescriptionPresenter() { override fun onBindDescription(viewHolder: AbstractDetailsDescriptionPresenter.ViewHolder, itemData: Any) { val details = itemData as MyMediaItemDetails // In a production app, the itemData object contains the information // needed to display details for the media item: // viewHolder.title.text = details.shortTitle // Here we provide static data for testing purposes: viewHolder.apply { title.text = itemData.toString() subtitle.text = "2014 Drama TV-14" body.text = ("Lorem ipsum dolor sit amet, consectetur " + "adipisicing elit, sed do eiusmod tempor incididunt ut labore " + " et dolore magna aliqua. Ut enim ad minim veniam, quis " + "nostrud exercitation ullamco laboris nisi ut aliquip ex ea " + "commodo consequat.") } } }
Java
public class DetailsDescriptionPresenter extends AbstractDetailsDescriptionPresenter { @Override protected void onBindDescription(ViewHolder viewHolder, Object itemData) { MyMediaItemDetails details = (MyMediaItemDetails) itemData; // In a production app, the itemData object contains the information // needed to display details for the media item: // viewHolder.getTitle().setText(details.getShortTitle()); // Here we provide static data for testing purposes: viewHolder.getTitle().setText(itemData.toString()); viewHolder.getSubtitle().setText("2014 Drama TV-14"); viewHolder.getBody().setText("Lorem ipsum dolor sit amet, consectetur " + "adipisicing elit, sed do eiusmod tempor incididunt ut labore " + " et dolore magna aliqua. Ut enim ad minim veniam, quis " + "nostrud exercitation ullamco laboris nisi ut aliquip ex ea " + "commodo consequat."); } }
Detailfragment erweitern
Wenn Sie die Klasse DetailsSupportFragment
verwenden, um die Details Ihres Media-Elements anzuzeigen, erweitern Sie diese Klasse, um zusätzliche Inhalte wie ein Vorschaubild und Aktionen für das Media-Element bereitzustellen. Sie können auch zusätzliche Inhalte wie eine Liste mit zugehörigen Media-Elementen angeben.
Der folgende Beispielcode zeigt, wie Sie mit der im vorherigen Abschnitt gezeigten Präsentationsklasse ein Vorschaubild und Aktionen für das angezeigte Media-Element hinzufügen. In diesem Beispiel wird auch eine Zeile mit zugehörigen Media-Elementen hinzugefügt, die unter der Detailauflistung angezeigt wird.
Kotlin
private const val TAG = "MediaItemDetailsFragment" class MediaItemDetailsFragment : DetailsSupportFragment() { private lateinit var rowsAdapter: ArrayObjectAdapter override fun onCreate(savedInstanceState: Bundle?) { Log.i(TAG, "onCreate") super.onCreate(savedInstanceState) buildDetails() } private fun buildDetails() { val selector = ClassPresenterSelector().apply { // Attach your media item details presenter to the row presenter: FullWidthDetailsOverviewRowPresenter(DetailsDescriptionPresenter()).also { addClassPresenter(DetailsOverviewRow::class.java, it) } addClassPresenter(ListRow::class.java, ListRowPresenter()) } rowsAdapter = ArrayObjectAdapter(selector) val res = activity.resources val detailsOverview = DetailsOverviewRow("Media Item Details").apply { // Add images and action buttons to the details view imageDrawable = res.getDrawable(R.drawable.jelly_beans) addAction(Action(1, "Buy $9.99")) addAction(Action(2, "Rent $2.99")) } rowsAdapter.add(detailsOverview) // Add a related items row val listRowAdapter = ArrayObjectAdapter(StringPresenter()).apply { add("Media Item 1") add("Media Item 2") add("Media Item 3") } val header = HeaderItem(0, "Related Items") rowsAdapter.add(ListRow(header, listRowAdapter)) adapter = rowsAdapter } }
Java
public class MediaItemDetailsFragment extends DetailsSupportFragment { private static final String TAG = "MediaItemDetailsFragment"; private ArrayObjectAdapter rowsAdapter; @Override public void onCreate(Bundle savedInstanceState) { Log.i(TAG, "onCreate"); super.onCreate(savedInstanceState); buildDetails(); } private void buildDetails() { ClassPresenterSelector selector = new ClassPresenterSelector(); // Attach your media item details presenter to the row presenter: FullWidthDetailsOverviewRowPresenter rowPresenter = new FullWidthDetailsOverviewRowPresenter( new DetailsDescriptionPresenter()); selector.addClassPresenter(DetailsOverviewRow.class, rowPresenter); selector.addClassPresenter(ListRow.class, new ListRowPresenter()); rowsAdapter = new ArrayObjectAdapter(selector); Resources res = getActivity().getResources(); DetailsOverviewRow detailsOverview = new DetailsOverviewRow( "Media Item Details"); // Add images and action buttons to the details view detailsOverview.setImageDrawable(res.getDrawable(R.drawable.jelly_beans)); detailsOverview.addAction(new Action(1, "Buy $9.99")); detailsOverview.addAction(new Action(2, "Rent $2.99")); rowsAdapter.add(detailsOverview); // Add a related items row ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter( new StringPresenter()); listRowAdapter.add("Media Item 1"); listRowAdapter.add("Media Item 2"); listRowAdapter.add("Media Item 3"); HeaderItem header = new HeaderItem(0, "Related Items", null); rowsAdapter.add(new ListRow(header, listRowAdapter)); setAdapter(rowsAdapter); } }
Detailaktivität erstellen
Fragmente wie DetailsSupportFragment
müssen in einer Aktivität enthalten sein, damit sie angezeigt werden können. Wenn Sie eine Aktivität für die Detailansicht erstellen, die sich von der Browseraktivität unterscheidet, können Sie die Detailansicht mit einem Intent
aufrufen. In diesem Abschnitt wird beschrieben, wie Sie eine Aktivität erstellen, die die Implementierung der Detailansicht für Ihre Media-Elemente enthält.
Erstellen Sie die Detailansicht, indem Sie ein Layout erstellen, das auf Ihre Implementierung von DetailsSupportFragment
verweist:
<!-- file: res/layout/details.xml --> <fragment xmlns:android="http://schemas.android.com/apk/res/android" android:name="com.example.android.mediabrowser.MediaItemDetailsFragment" android:id="@+id/details_fragment" android:layout_width="match_parent" android:layout_height="match_parent" />
Erstellen Sie als Nächstes eine Aktivitätsklasse, die das im vorherigen Codebeispiel gezeigte Layout verwendet:
Kotlin
class DetailsActivity : FragmentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.details) } }
Java
public class DetailsActivity extends FragmentActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.details); } }
Fügen Sie diese neue Aktivität schließlich dem Manifest hinzu. Denken Sie daran, das Leanback-Theme anzuwenden, damit die Benutzeroberfläche mit der Medienbrowsing-Aktivität übereinstimmt.
<application> ... <activity android:name=".DetailsActivity" android:exported="true" android:theme="@style/Theme.Leanback"/> </application>
Listener für angeklickte Elemente definieren
Nachdem Sie DetailsSupportFragment
implementiert haben, ändern Sie die Hauptansicht für das Durchsuchen von Medien so, dass die Detailansicht aufgerufen wird, wenn ein Nutzer auf ein Media-Element klickt. Fügen Sie zum Aktivieren dieses Verhaltens dem BrowseSupportFragment
ein OnItemViewClickedListener
-Objekt hinzu, das einen Intent auslöst, um die Aktivität mit den Artikeldetails zu starten.
Im folgenden Beispiel wird gezeigt, wie Sie einen Listener implementieren, um die Detailansicht zu starten, wenn ein Nutzer in der Hauptaktivität zum Durchsuchen von Medien auf ein Media-Element klickt:
Kotlin
class BrowseMediaActivity : FragmentActivity() { ... override fun onCreate(savedInstanceState: Bundle?) { ... // Create the media item rows buildRowsAdapter() // Add a listener for selected items browseFragment.onItemViewClickedListener = OnItemViewClickedListener { _, item, _, _ -> println("Media Item clicked: ${item}") val intent = Intent(this@BrowseMediaActivity, DetailsActivity::class.java).apply { // Pass the item information extras.putLong("id", item.getId()) } startActivity(intent) } } }
Java
public class BrowseMediaActivity extends FragmentActivity { ... @Override protected void onCreate(Bundle savedInstanceState) { ... // Create the media item rows buildRowsAdapter(); // Add a listener for selected items browseFragment.OnItemViewClickedListener( new OnItemViewClickedListener() { @Override public void onItemClicked(Object item, Row row) { System.out.println("Media Item clicked: " + item.toString()); Intent intent = new Intent(BrowseMediaActivity.this, DetailsActivity.class); // Pass the item information intent.getExtras().putLong("id", item.getId()); startActivity(intent); } }); } }