如何为Android TV左侧菜单添加图片?已实现右上角图片添加
在Android TV左侧导航菜单添加图片的解决方案
嘿,针对你在Android TV左侧菜单添加图片的需求,我来给你捋捋具体的实现方案~你之前用setBadgeDrawable(getActivity().getResources().getDrawable(R.drawable.icon))搞定了右上角的图片,这个一般是给BrowseFragment的标题栏设置徽章,而左侧导航栏的实现逻辑不一样,分两种常见场景来说:
一、如果你用的是Leanback库的BrowseFragment(Android TV官方推荐)
Leanback的左侧是分类导航栏,默认只有文字,要加图片得自定义它的Presenter,步骤如下:
1. 先做导航条目的布局
创建一个nav_item_with_icon.xml布局文件,把图片和文字放一起:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="16dp" android:gravity="center_vertical"> <ImageView android:id="@+id/nav_icon" android:layout_width="28dp" android:layout_height="28dp" android:marginEnd="12dp"/> <TextView android:id="@+id/nav_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="18sp" android:textColor="@color/white"/> </LinearLayout>
2. 自定义导航Presenter
写一个继承HeaderPresenter的子类,用来绑定布局和数据:
public class IconHeaderPresenter extends HeaderPresenter { @Override protected ViewHolder onCreateViewHolder(ViewGroup parent) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); View view = inflater.inflate(R.layout.nav_item_with_icon, parent, false); return new ViewHolder(view); } @Override protected void onBindViewHolder(ViewHolder viewHolder, Object item) { HeaderItem headerItem = (HeaderItem) item; super.onBindViewHolder(viewHolder, item); // 给每个导航条目设置对应的图标 ImageView iconView = viewHolder.view.findViewById(R.id.nav_icon); // 这里可以根据headerItem的id或者name来区分不同图标,比如: if (headerItem.getId() == 1) { iconView.setImageDrawable(viewHolder.view.getContext().getResources().getDrawable(R.drawable.home_icon)); } else if (headerItem.getId() == 2) { iconView.setImageDrawable(viewHolder.view.getContext().getResources().getDrawable(R.drawable.settings_icon)); } // 设置导航文字 TextView titleView = viewHolder.view.findViewById(R.id.nav_title); titleView.setText(headerItem.getName()); } }
3. 给BrowseFragment设置这个自定义Presenter
在你的BrowseFragment子类里,替换默认的导航Presenter:
@Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // 你已经实现的右上角徽章 setBadgeDrawable(getActivity().getResources().getDrawable(R.drawable.icon)); // 给左侧导航栏设置自定义Presenter setHeaderPresenterSelector(new PresenterSelector() { @Override public Presenter getPresenter(Object item) { return new IconHeaderPresenter(); } }); // 接下来正常添加你的Rows数据就好 loadRows(); }
二、如果你用的是普通AndroidX的NavigationView(抽屉导航)
这种情况更简单,直接在菜单资源里配置就行:
1. 在menu文件里给菜单项加图标
比如nav_menu.xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/nav_home" android:title="首页" android:icon="@drawable/home_icon"/> <item android:id="@+id/nav_settings" android:title="设置" android:icon="@drawable/settings_icon"/> </menu>
2. 代码里确保图标显示
有时候TV端的NavigationView默认可能隐藏图标,手动开启:
NavigationView navigationView = findViewById(R.id.nav_view); // 强制显示图标 navigationView.setIconVisibility(true); // 设置菜单点击监听 navigationView.setNavigationItemSelectedListener(item -> { // 处理点击逻辑 return true; });
最后提个小建议:TV端的图标尽量用简洁的矢量图,尺寸别太大,符合Android TV的交互规范,另外记得给选中状态加个样式,提升用户体验~
内容的提问来源于stack exchange,提问作者Halil Ozel




