Leanback androidx 库提供的媒体浏览界面类包含用于显示媒体项目相关附加信息(如说明或评价)的类,以及用于对该项目采取操作(如购买项目或播放其内容)的类。
本课介绍如何为媒体项目详情创建 Presenter 类,以及如何通过扩展
注意:此处显示的实现示例使用一个额外的 Activity 来容纳 如需详细了解如何使用 Fragment 事务,请参阅使用 Fragment 构建动态界面培训。
构建详情 Presenter
在 Leanback 支持库提供的媒体浏览框架中,您可以使用 Presenter 对象控制数据(包括媒体项目详情)在屏幕上的显示。该框架为此提供了
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.");
}
}
扩展详情 Fragment
在使用
以下示例代码演示了如何利用上一部分中显示的 Presenter 类为正在查看的媒体项目添加预览图片和相关操作。此示例还展示了如何添加相关媒体项目行,该行显示在详情列表下方。
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);
}
}
创建详情 Activity
诸如
创建详情 Activity 时,首先要构建一个引用
android:name="com.example.android.mediabrowser.MediaItemDetailsFragment"
android:id="@+id/details_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
接下来,创建一个使用上一代码示例中所示布局的 Activity 类:
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);
}
}
最后,将这个新 Activity 添加到清单中。请记得应用 Leanback 主题背景,以确保界面与媒体浏览 Activity 保持一致:
...
android:exported="true"
android:theme="@style/Theme.Leanback"/>
为点击的项目定义监听器
在实现
以下示例展示了如何实现一个可在用户点击主媒体浏览 Activity 中的某个媒体项目时启动详情视图的监听器:
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);
}
});
}
}