نمای جزئیات بسازید

با Compose بهتر بسازید
با استفاده از Jetpack Compose برای سیستم عامل Android TV، رابط‌های کاربری زیبا با حداقل کد ایجاد کنید.

کلاس‌های واسط مرورگر رسانه ارائه شده توسط کتابخانه androidx.leanback شامل کلاس‌هایی برای نمایش اطلاعات اضافی در مورد یک آیتم رسانه، مانند توضیحات یا نظرات است. آنها همچنین شامل کلاس هایی برای اقدام در مورد آن آیتم هستند، مانند خرید آن یا پخش محتوای آن.

این راهنما نحوه ایجاد یک کلاس ارائه کننده برای جزئیات آیتم رسانه و نحوه گسترش کلاس DetailsSupportFragment را برای پیاده سازی نمای جزئیات برای یک آیتم رسانه در هنگام انتخاب کاربر مورد بحث قرار می دهد.

توجه: مثال پیاده سازی نشان داده شده در اینجا از یک فعالیت اضافی برای حاوی DetailsSupportFragment استفاده می کند. با این حال، می‌توان با جایگزین کردن BrowseSupportFragment با DetailsSupportFragment در همان اکتیویتی با استفاده از تراکنش‌های قطعه، از ایجاد فعالیت دوم جلوگیری کرد. برای اطلاعات بیشتر در مورد استفاده از تراکنش های قطعه، به ایجاد یک قطعه مراجعه کنید.

ارائه دهنده جزئیات بسازید

در چارچوب مرور رسانه ارائه شده توسط جعبه ابزار Leanback UI، شما از اشیاء ارائه کننده برای کنترل نمایش داده ها روی صفحه، از جمله جزئیات آیتم رسانه، استفاده می کنید. برای این منظور، این فریم ورک کلاس AbstractDetailsDescriptionPresenter را ارائه می دهد که تقریباً یک پیاده سازی کامل از ارائه دهنده برای جزئیات آیتم های رسانه ای است. تنها کاری که باید انجام دهید این است که روش onBindDescription() را پیاده سازی کنید تا فیلدهای view را به اشیاء داده خود متصل کنید، همانطور که در نمونه کد زیر نشان داده شده است:

کاتلین

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

جاوا

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

بخش جزئیات را گسترش دهید

هنگامی که از کلاس DetailsSupportFragment برای نمایش جزئیات آیتم رسانه خود استفاده می کنید، آن کلاس را برای ارائه محتوای اضافی مانند تصویر پیش نمایش و اقدامات برای آیتم رسانه گسترش دهید. همچنین می‌توانید محتوای اضافی، مانند فهرستی از آیتم‌های رسانه‌ای مرتبط، ارائه دهید.

کد مثال زیر نحوه استفاده از کلاس ارائه‌دهنده نشان‌داده‌شده در بخش قبل را برای افزودن یک تصویر پیش‌نمایش و اقدامات برای آیتم رسانه‌ای در حال مشاهده نشان می‌دهد. این مثال همچنین اضافه شدن یک ردیف آیتم های رسانه مرتبط را نشان می دهد که در زیر لیست جزئیات ظاهر می شود.

کاتلین

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

جاوا

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

یک فعالیت جزئیات ایجاد کنید

قطعاتی مانند DetailsSupportFragment باید در یک اکتیویتی وجود داشته باشد تا برای نمایش استفاده شود. ایجاد یک فعالیت برای نمای جزئیات شما - جدا از فعالیت مرور - به شما امکان می دهد نمای جزئیات خود را با استفاده از Intent فراخوانی کنید. این بخش نحوه ایجاد فعالیتی را توضیح می دهد که شامل اجرای نمای جزئیات برای موارد رسانه شما باشد.

با ساختن طرح‌بندی که به پیاده‌سازی 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"
/>

در مرحله بعد، یک کلاس فعالیت ایجاد کنید که از طرح بندی نشان داده شده در مثال کد قبلی استفاده می کند:

کاتلین

class DetailsActivity : FragmentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.details)
    }
}

جاوا

public class DetailsActivity extends FragmentActivity
{
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.details);
    }
}

در نهایت، این فعالیت جدید را به مانیفست اضافه کنید. به خاطر داشته باشید که از تم Leanback استفاده کنید تا اطمینان حاصل کنید که رابط کاربری با فعالیت مرور رسانه سازگار است.

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

</application>

برای موارد کلیک شده شنونده تعریف کنید

پس از پیاده سازی DetailsSupportFragment ، نمای اصلی مرور رسانه خود را تغییر دهید تا زمانی که کاربر روی یک مورد رسانه کلیک می کند، به نمای جزئیات منتقل شود. برای فعال کردن این رفتار، یک شی OnItemViewClickedListener را به BrowseSupportFragment اضافه کنید که قصد شروع فعالیت جزئیات مورد را ایجاد می کند.

مثال زیر نحوه پیاده سازی شنونده را برای شروع نمای جزئیات زمانی که کاربر روی یک مورد رسانه در فعالیت مرور رسانه اصلی کلیک می کند، نشان می دهد:

کاتلین

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

جاوا

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