如何通过Adapter在ListView中无XML添加图标?添加时应用崩溃求助
嘿,我来帮你搞定这个ListView加图标的问题!
首先得说清楚为啥会崩溃:你现在用的ArrayAdapter<String>只能处理纯字符串的数据源,而你尝试用videoList.add(R.drawable.mi_icon, "Genel Bilgiler")这种方式添加图标ID(int类型)和字符串,不仅ArrayList<String>存不了int类型的数据导致类型不匹配,而且默认的ArrayAdapter根本没有处理图标的逻辑,这就是应用崩溃的核心原因。
下面给你两种实用的解决方案,你可以根据自己的需求选:
方法一:用SimpleAdapter快速实现(适合简单场景)
SimpleAdapter本身就支持自定义布局,能同时展示图标和文本,步骤很清晰:
1. 先写列表项的自定义布局
创建一个名为list_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:padding="16dp" android:orientation="horizontal" android:gravity="center_vertical"> <!-- 图标控件 --> <ImageView android:id="@+id/item_icon" android:layout_width="40dp" android:layout_height="40dp" /> <!-- 文本控件 --> <TextView android:id="@+id/item_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="16dp" android:textSize="18sp" /> </LinearLayout>
2. 修改Genel.java里的代码
把原来的字符串列表改成存储HashMap的列表,每个HashMap存图标ID和文本,再用SimpleAdapter绑定:
MediaController mediaController; VideoView videoview; ListView listView; // 换成存储HashMap的ArrayList,每个HashMap存图标和文本数据 ArrayList<HashMap<String, Object>> videoList; SimpleAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_genel); final VideoView videoview = findViewById(R.id.Videogenel); listView = findViewById(R.id.lgvideo); videoList = new ArrayList<>(); // 添加第一个列表项的数据 HashMap<String, Object> firstItem = new HashMap<>(); firstItem.put("icon", R.drawable.mi_icon); firstItem.put("text", "Genel Bilgiler"); videoList.add(firstItem); // 初始化SimpleAdapter,把数据和布局绑定 adapter = new SimpleAdapter( this, videoList, R.layout.list_item_with_icon, // 刚才写的自定义布局 new String[]{"icon", "text"}, // HashMap里的键名 new int[]{R.id.item_icon, R.id.item_text} // 布局里对应的控件ID ); listView.setAdapter(adapter); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { switch (position){ case 0: videoview.setVideoPath("/storage/A6D3-E544/videos/genel1.mp4"); break; } final MediaController mediacontroller = new MediaController(Genel.this); mediacontroller.setAnchorView(videoview); videoview.setMediaController(mediacontroller); videoview.requestFocus(); // 别忘了加这句启动播放 videoview.start(); } }); }
方法二:自定义ArrayAdapter(适合复杂需求)
如果以后你想给列表项加更多交互或者更复杂的样式,自定义Adapter会更灵活:
1. 同样先准备自定义列表项布局list_item_with_icon.xml
和方法一里的布局完全一样就行。
2. 写一个自定义的Adapter类
这个类继承自ArrayAdapter,专门处理带图标的列表项:
public class IconTextAdapter extends ArrayAdapter<IconTextAdapter.IconTextItem> { public IconTextAdapter(Context context, ArrayList<IconTextItem> items) { super(context, 0, items); } @NonNull @Override public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { // 复用convertView提升列表滚动性能 if (convertView == null) { convertView = LayoutInflater.from(getContext()).inflate(R.layout.list_item_with_icon, parent, false); } // 获取当前位置的列表项数据 IconTextItem item = getItem(position); // 找到布局里的控件 ImageView iconView = convertView.findViewById(R.id.item_icon); TextView textView = convertView.findViewById(R.id.item_text); // 设置数据 iconView.setImageResource(item.getIconResId()); textView.setText(item.getText()); return convertView; } // 定义一个数据模型类,用来存图标ID和文本 public static class IconTextItem { private int iconResId; private String text; public IconTextItem(int iconResId, String text) { this.iconResId = iconResId; this.text = text; } public int getIconResId() { return iconResId; } public String getText() { return text; } } }
3. 修改Genel.java的代码
用自定义的Adapter和数据模型来替换原来的ArrayAdapter:
MediaController mediaController; VideoView videoview; ListView listView; // 换成存储自定义数据模型的ArrayList ArrayList<IconTextAdapter.IconTextItem> videoList; IconTextAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_genel); final VideoView videoview = findViewById(R.id.Videogenel); listView = findViewById(R.id.lgvideo); videoList = new ArrayList<>(); // 添加列表项数据,用自定义的IconTextItem videoList.add(new IconTextAdapter.IconTextItem(R.drawable.mi_icon, "Genel Bilgiler")); // 初始化自定义Adapter adapter = new IconTextAdapter(this, videoList); listView.setAdapter(adapter); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { switch (position){ case 0: videoview.setVideoPath("/storage/A6D3-E544/videos/genel1.mp4"); break; } final MediaController mediacontroller = new MediaController(Genel.this); mediacontroller.setAnchorView(videoview); videoview.setMediaController(mediacontroller); videoview.requestFocus(); videoview.start(); } }); }
额外提醒
- 权限问题:如果你的视频存在外部存储,Android 10及以上系统可能需要特殊权限才能访问,要么把视频放到应用的私有目录,要么申请
MANAGE_EXTERNAL_STORAGE权限(或者用MediaStore来访问),不然可能加载不了视频。 - 样式调整:你可以根据自己的需求修改
list_item_with_icon.xml里的控件属性,比如图标大小、文本颜色、内边距等。
内容的提问来源于stack exchange,提问作者user10991969
相关产品推荐
相关产品推荐

