Android开发:自定义对象ArrayList填充ListView时应用崩溃求助
嘿,刚接触Android几周就遇到这个头疼的崩溃?别慌,我帮你捋捋最常见的几个坑,还有对应的解决办法!你说崩溃发生在list.setAdapter(adapter)这一行,大概率是空指针或者初始化错误导致的,咱们一步步排查:
最可能的几个原因&解决步骤
1. ListView根本没正确找到(最常见!)
你在Fragment里初始化ListView的时候,是不是直接用了getActivity().findViewById()?这可不行!Fragment的视图是在onCreateView里通过inflater创建的,必须从你返回的myView里找ListView,否则拿到的就是null,调用setAdapter自然会崩。
正确写法示例:
@Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { myView = inflater.inflate(R.layout.fragment_npc_editor, container, false); // 一定要从myView里查找ListView! ListView list = myView.findViewById(R.id.your_list_view_id); // 后续初始化Adapter和设置的代码... return myView; }
2. 自定义Adapter存在问题
Adapter是连接数据和ListView的桥梁,稍有不慎就会出问题:
- 构造函数没传对上下文:比如Adapter里的Context是null,inflater视图的时候就会报错;
- getCount()返回错误值:比如返回0或者null,ListView无法渲染;
- getView()里的空指针:比如没正确初始化convertView,或者绑定数据时NPC对象的属性是null。
给你一个靠谱的自定义Adapter示例:
public class NPCAdapter extends BaseAdapter { private Context mContext; private ArrayList<NPC> mNpcList; // 构造函数必须传入上下文和数据列表 public NPCAdapter(Context context, ArrayList<NPC> npcList) { mContext = context; mNpcList = npcList; } @Override public int getCount() { // 直接返回列表大小,别瞎写固定值! return mNpcList.size(); } @Override public Object getItem(int position) { return mNpcList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; // 复用convertView优化性能,避免重复创建视图 if (convertView == null) { convertView = LayoutInflater.from(mContext).inflate(R.layout.list_item_npc, parent, false); holder = new ViewHolder(); holder.npcName = convertView.findViewById(R.id.tv_npc_name); holder.npcLevel = convertView.findViewById(R.id.tv_npc_level); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } // 绑定数据前先做非空判断,防止空指针 NPC currentNpc = mNpcList.get(position); if (currentNpc != null) { holder.npcName.setText(currentNpc.getName()); holder.npcLevel.setText(currentNpc.getLevel()); } return convertView; } // ViewHolder模式,减少findViewById的次数 static class ViewHolder { TextView npcName; TextView npcLevel; } }
3. 你的NPC数据列表是空的?
如果NPCs列表里没有任何数据,虽然不一定会崩溃,但也可能引发奇怪的问题。建议先添加几个测试数据,验证Adapter是否能正常工作:
// 在初始化Adapter前,先填充测试数据 private void addTestNpcs() { NPCs.add(new NPC("铁匠", "15级", "矮人")); NPCs.add(new NPC("守卫", "10级", "人类")); }
最后关键提醒:看LogCat!
崩溃的时候一定要看Android Studio里的LogCat,里面会明确告诉你是哪一行代码出了问题(比如NullPointerException会指向具体的null对象),这才是最快定位问题的方法!比如如果Log说Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference,那就是ListView没找到,回到第一步排查。
内容的提问来源于stack exchange,提问作者Ivaldir

