Ayrıntılar görünümü oluşturma

Compose ile daha iyi hizmet verin
Android TV OS için Jetpack Compose'u kullanarak minimum kodla etkileyici kullanıcı arayüzleri oluşturun.

androidx.leanback kitaplığı tarafından sağlanan medyaya göz atma arayüzü sınıfları bir medya öğesiyle ilgili açıklama gibi ek bilgileri görüntülemek için sınıflar içeren veya incelemeler. Ayrıca, ürün satın alma veya içeriğini oynatma gibi işlemler yapmaya yönelik dersler de içerir.

Bu kılavuzda, medya öğesi ayrıntıları için sunucu sınıfının nasıl oluşturulacağı ve ayrıntılar görünümünü uygulamak için DetailsSupportFragment sınıfını Kullanıcı bir medya öğesini seçtiğinde bu medya öğesi için.

Not: Burada gösterilen uygulama örneğinde, aşağıdakileri yapmak için ek bir etkinlik kullanılır: DetailsSupportFragment değerini içerir. Ancak bazı durumlarda aynı etkinlik içinde BrowseSupportFragment değerini bir DetailsSupportFragment ile değiştirerek ikinci bir etkinlik oluşturmaktan kaçınabilirsiniz. parça işlemleri. Parça işlemleri hakkında daha fazla bilgi için Parça oluşturma konusuna bakın.

Bir ayrıntı sunucusu oluşturma

Leanback kullanıcı arayüzü araç seti tarafından sağlanan medyaya göz atma çerçevesindeki verilerin ekranda görüntülenmesini denetleyen nesneler (medya öğesi ayrıntıları dahil) Bu amaçla çerçeve AbstractDetailsDescriptionPresenter sağlar medya öğesi sunumu için sunucunun neredeyse eksiksiz bir şekilde uygulandığı bir sınıftır. bolca fırsat sunuyor. Tek yapmanız gereken onBindDescription() aşağıdaki örnekteki gibi görünüm alanlarını veri nesnelerinize şu kod örneğine bakalım:

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

Ayrıntı parçasını genişlet

Görüntüleme için DetailsSupportFragment sınıfı kullanılırken bir önizleme gibi ek içerik sağlamak için bu sınıfı genişletin. resmi ve işlemleri görürsünüz. Ayrıca şöyle ek içerikler de sağlayabilirsiniz: ilgili medya öğeleridir.

Aşağıdaki örnek kod, önceki bölümde, görüntülenmekte olan medya öğesi için bir önizleme resmi ve işlemler ekleyebilirsiniz. Bu örnek ayrıntılar girişinin altında görünen ilgili medya öğeleri satırının eklendiğini de gösterir.

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

Ayrıntı etkinliği oluştur

DetailsSupportFragment gibi parçalar yer almalıdır bir etkinlik içinde gösterilir. Bilgileriniz için etkinlik oluşturma görünüm (göz atma etkinliğinden ayrıdır), Intent Bu bölümünde ayrıntılı görünümün uygulamanızı içermek üzere nasıl etkinlik medya öğelerinizi kontrol edin.

Şu öğelere referans veren bir düzen oluşturarak ayrıntılar etkinliğini oluşturun: 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"
/>

Ardından, önceki kod örneğinde gösterilen düzeni kullanan bir etkinlik sınıfı oluşturun:

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

Son olarak, bu yeni etkinliği manifest dosyasına ekleyin. Başarılı bir sunum için Leanback temasını kullanıcı arayüzünün medya göz atma etkinliğiyle tutarlı olduğundan emin olun.

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

</application>

Tıklanan öğeler için bir işleyici tanımlayın

DetailsSupportFragment öğesini uyguladıktan sonra, bir kullanıcı bir medyayı tıkladığında ayrıntılar görünümüne geçmek için ana medya göz atma görünümünüzü değiştirme öğe. Bu davranışı etkinleştirmek için OnItemViewClickedListener nesne Öğeyi başlatma niyetini tetikleyen BrowseSupportFragment etkinlik ayrıntılarına gidin.

Aşağıdaki örnekte, bir kullanıcı işlemi gerçekleştirdiğinde ayrıntılar görünümünü başlatmak için bir işleyicinin nasıl uygulanacağı gösterilmektedir Ana medya göz atma etkinliğinde bir medya öğesini tıkladığında:

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