در درس قبلی، شما یک مرورگر کاتالوگ ایجاد کردید که در یک قطعه مرور پیاده سازی شده است که لیستی از آیتم های رسانه را نمایش می دهد. در این درس، نماهای کارت را برای آیتم های رسانه ای خود ایجاد می کنید و آنها را در قسمت مرور ارائه می دهید.
کلاس BaseCardView
و زیر کلاسها ابرداده مرتبط با یک آیتم رسانه را نمایش میدهند. کلاس ImageCardView
مورد استفاده در این درس یک تصویر برای محتوا همراه با عنوان آیتم رسانه نمایش می دهد.
همچنین اجرای نمونه را در برنامه نمونه Leanback مشاهده کنید.
![نمای کارت برنامه](https://developer.android.com/static/images/tv/card-view.png?hl=fa)
شکل 1. نمای کارت تصویر برنامه Leanback در صورت انتخاب.
یک ارائه دهنده کارت ایجاد کنید
یک Presenter
نماها را تولید می کند و اشیاء را در صورت درخواست به آنها متصل می کند. در قسمت مرور که برنامه شما محتوای خود را به کاربر ارائه میکند، یک Presenter
برای کارتهای محتوا ایجاد میکنید و آن را به آداپتوری که محتوا را به صفحه اضافه میکند، ارسال میکنید. در کد زیر، CardPresenter
در پاسخ به تماس onLoadFinished()
LoaderManager
ایجاد می شود:
کاتلین
override fun onLoadFinished(loader: Loader<HashMap<String, List<Movie>>>, data: HashMap<String, List<Movie>>) { rowsAdapter = ArrayObjectAdapter(ListRowPresenter()) val cardPresenter = CardPresenter() var i = 0L data.entries.forEach { entry -> val listRowAdapter = ArrayObjectAdapter(cardPresenter).apply { entry.value.forEach { movie -> add(movie) } } val header = HeaderItem(i, entry.key) i++ rowsAdapter.add(ListRow(header, listRowAdapter)) } val gridHeader = HeaderItem(i, getString(R.string.more_samples)) val gridRowAdapter = ArrayObjectAdapter(GridItemPresenter()).apply { add(getString(R.string.grid_view)) add(getString(R.string.error_fragment)) add(getString(R.string.personal_settings)) } rowsAdapter.add(ListRow(gridHeader, gridRowAdapter)) adapter = rowsAdapter updateRecommendations() }
جاوا
@Override public void onLoadFinished(Loader<HashMap<String, List<Movie>>> arg0, HashMap<String, List<Movie>> data) { rowsAdapter = new ArrayObjectAdapter(new ListRowPresenter()); CardPresenter cardPresenter = new CardPresenter(); int i = 0; for (Map.Entry<String, List<Movie>> entry : data.entrySet()) { ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter); List<Movie> list = entry.getValue(); for (int j = 0; j < list.size(); j++) { listRowAdapter.add(list.get(j)); } HeaderItem header = new HeaderItem(i, entry.getKey()); i++; rowsAdapter.add(new ListRow(header, listRowAdapter)); } HeaderItem gridHeader = new HeaderItem(i, getString(R.string.more_samples)); GridItemPresenter gridPresenter = new GridItemPresenter(); ArrayObjectAdapter gridRowAdapter = new ArrayObjectAdapter(gridPresenter); gridRowAdapter.add(getString(R.string.grid_view)); gridRowAdapter.add(getString(R.string.error_fragment)); gridRowAdapter.add(getString(R.string.personal_settings)); rowsAdapter.add(new ListRow(gridHeader, gridRowAdapter)); setAdapter(rowsAdapter); updateRecommendations(); }
یک نمای کارت ایجاد کنید
در این مرحله، ارائهدهنده کارت را با یک نگهدارنده نمایش برای نمای کارت میسازید که موارد محتوای رسانهای شما را توصیف میکند. توجه داشته باشید که هر ارائه دهنده باید فقط یک نوع نمایش ایجاد کند. اگر دو نوع نمایش کارت دارید، به دو ارائه دهنده کارت نیاز دارید.
در Presenter
، یک callback onCreateViewHolder()
را پیاده سازی کنید که یک view دارنده ایجاد می کند که می تواند برای نمایش یک آیتم محتوا استفاده شود:
کاتلین
private const val CARD_WIDTH = 313 private const val CARD_HEIGHT = 176 class CardPresenter : Presenter() { private lateinit var mContext: Context private lateinit var defaultCardImage: Drawable override fun onCreateViewHolder(parent: ViewGroup): Presenter.ViewHolder { mContext = parent.context defaultCardImage = mContext.resources.getDrawable(R.drawable.movie) ...
جاوا
@Override public class CardPresenter extends Presenter { private Context context; private static int CARD_WIDTH = 313; private static int CARD_HEIGHT = 176; private Drawable defaultCardImage; @Override public ViewHolder onCreateViewHolder(ViewGroup parent) { context = parent.getContext(); defaultCardImage = context.getResources().getDrawable(R.drawable.movie); ...
در متد onCreateViewHolder()
یک نمای کارت برای آیتم های محتوا ایجاد کنید. نمونه زیر از ImageCardView
استفاده می کند.
هنگامی که یک کارت انتخاب می شود، رفتار پیش فرض آن را به اندازه بزرگتر گسترش می دهد. اگر می خواهید رنگ دیگری را برای کارت انتخاب شده تعیین کنید، setSelected()
را همانطور که در اینجا نشان داده شده است فراخوانی کنید:
کاتلین
... val cardView = object : ImageCardView(context) { override fun setSelected(selected: Boolean) { val selected_background = context.resources.getColor(R.color.detail_background) val default_background = context.resources.getColor(R.color.default_background) val color = if (selected) selected_background else default_background findViewById<View>(R.id.info_field).setBackgroundColor(color) super.setSelected(selected) } } ...
جاوا
... ImageCardView cardView = new ImageCardView(context) { @Override public void setSelected(boolean selected) { int selected_background = context.getResources().getColor(R.color.detail_background); int default_background = context.getResources().getColor(R.color.default_background); int color = selected ? selected_background : default_background; findViewById(R.id.info_field).setBackgroundColor(color); super.setSelected(selected); } }; ...
وقتی کاربر برنامه شما را باز می کند، Presenter.ViewHolder
اشیاء CardView
را برای آیتم های محتوای شما نمایش می دهد. برای دریافت فوکوس از کنترلر D-pad با فراخوانی setFocusable(true)
و setFocusableInTouchMode(true)
نیاز دارید، همانطور که در کد زیر نشان داده شده است:
کاتلین
... cardView.isFocusable = true cardView.isFocusableInTouchMode = true return ViewHolder(cardView) }
جاوا
... cardView.setFocusable(true); cardView.setFocusableInTouchMode(true); return new ViewHolder(cardView); }
هنگامی که کاربر ImageCardView
را انتخاب میکند، آن را گسترش میدهد تا ناحیه متن خود را با رنگ پسزمینهای که شما مشخص کردهاید نشان دهد، همانطور که در شکل 1 نشان داده شده است.