Creare una visualizzazione dei dettagli

Migliora la creazione con Compose
Crea splendide UI con un minimo codice utilizzando Jetpack Compose per il sistema operativo Android TV.

Le classi dell'interfaccia di navigazione dei contenuti multimediali fornite dalla libreria androidx.leanback includono classi per visualizzare informazioni aggiuntive su un elemento multimediale, come una descrizione o recensioni. Includono anche corsi per compiere azioni su quell'articolo, ad esempio acquistarlo o riprodurne i contenuti.

Questa guida illustra come creare una classe Presentatore per i dettagli degli elementi multimediali e come estenderla la classe DetailsSupportFragment per implementare una visualizzazione dei dettagli per un elemento multimediale quando l'utente lo seleziona.

Nota: l'esempio di implementazione mostrato qui utilizza un'attività aggiuntiva per contengono DetailsSupportFragment. Tuttavia, è possibile Evita di creare una seconda attività sostituendo BrowseSupportFragment con un DetailsSupportFragment nella stessa attività utilizzando delle transazioni di frammento. Per saperne di più sull'utilizzo delle transazioni con frammenti, consulta Creare un frammento.

Crea un presentatore dei dettagli

Nel framework di navigazione dei contenuti multimediali fornito dal toolkit dell'interfaccia utente Leanback, puoi usare il presentatore per controllare la visualizzazione dei dati sullo schermo, inclusi i dettagli degli elementi multimediali. A questo scopo, il framework fornisce l'AbstractDetailsDescriptionPresenter , che è un'implementazione quasi completa del presentatore per l'elemento multimediale i dettagli. Non devi fare altro che implementare onBindDescription() per associare i campi della vista agli oggetti dati, come illustrato nel nell'esempio di codice riportato di seguito:

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.");
    }
}

Estendi il frammento dei dettagli

Quando si utilizza la classe DetailsSupportFragment per la visualizzazione dettagli dell'elemento multimediale, estendi la classe per fornire contenuti aggiuntivi, come un'anteprima immagine e azioni per l'elemento multimediale. Puoi anche fornire contenuti aggiuntivi, ad esempio un elenco di elementi multimediali correlati.

Il codice di esempio seguente mostra come utilizzare la classe presentatore mostrata in sezione precedente per aggiungere un'immagine di anteprima e azioni per l'elemento multimediale visualizzato. Questo esempio mostra anche l'aggiunta di una riga di elementi multimediali correlati, che viene visualizzata sotto l'elenco dei dettagli.

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);
    }
}

Crea un'attività di dettagli

Devono essere contenuti frammenti come DetailsSupportFragment all'interno di un'attività da usare per la visualizzazione. Creazione di un'attività per i tuoi dettagli separata dall'attività di esplorazione, ti consente di richiamare la visualizzazione dei dettagli utilizzando una Intent. Questo spiega come creare un'attività che contenga l'implementazione della visualizzazione dei dettagli per gli elementi multimediali.

Crea l'attività di dettaglio creando un layout che faccia riferimento alla tua implementazione DetailsSupportFragment:

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

Successivamente, crea una classe di attività utilizzando il layout mostrato nell'esempio di codice precedente:

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);
    }
}

Infine, aggiungi questa nuova attività al file manifest. Ricorda di applicare il tema Leanback per assicurarti che l'interfaccia utente sia coerente con l'attività di esplorazione dei contenuti multimediali.

<application>
  ...
  <activity android:name=".DetailsActivity"
    android:exported="true"
    android:theme="@style/Theme.Leanback"/>

</application>

Definisci un listener per gli elementi selezionati

Dopo aver implementato DetailsSupportFragment, modifica la visualizzazione navigazione principale dei contenuti multimediali per passare alla visualizzazione dei dettagli quando un utente fa clic su un elemento multimediale molto utile. Per abilitare questo comportamento, aggiungi un parametro OnItemViewClickedListener all'oggetto BrowseSupportFragment che attiva un intent per avviare l'elemento Dettagli dell'attività.

L'esempio seguente mostra come implementare un listener per avviare la visualizzazione dei dettagli quando un utente fa clic su un elemento multimediale nell'attività di navigazione multimediale principale:

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);
                }
            });
    }
}