场景是这样,底部4个tab导航栏,用的fragment。
但其中一个fragmentActivity1中使用ListVIew的setAdapter()方法时,总是报NullPointerException错误。
一整天都没有解决,晚上看国外的论坛上,看到对于ListView的深入讲解,才忽然理解了问题所在。
对于ListView,刚开始写应用的时候都是拿来就用,没有深入了解过它的本质。
从博友的博客上摘录一段话,一个ListView通常有两个职责:
(1)将数据填充到布局。
(2)处理用户的选择点击等操作。
第一点很好理解,ListView就是实现这个功能的。第二点也不难做到,在后面的学习中读者会发现,这非常简单。
一个ListView的创建需要3个元素:
(1)ListView中的每一列的View。
(2)填入View的数据或者图片等。
(3)连接数据与ListView的适配器。
也就是说,要使用ListView,首先要了解什么是适配器。适配器是一个连接数据和AdapterView(ListView就是一个典型的AdapterView)的桥梁,通过它能够将相互分离的数据和AdapterView整合到一起。
上面这段话很重要,这就是ListView的本质。也就是说,实际工作中,要让ListView工作,一般应该包含4部分:
1,用来装ListView的总(布局)文件:如index_order.xml
2,嵌入到ListView里的可重复的View(布局)文件:如index_order_listview.xml
3,填充到index_order_listview.xml的数据:文字、图片等,通常是一个List<Map<String,Object>>数组
4,将数据和布局文件融合到一起的适配器,我将其理解为一个方法:如setAdapter()
理解了上面的部分,我们再来说报空指针NullPointerException的问题。
我们直接看执行代码:
SimpleAdapter adapter = new SimpleAdapter(this.getActivity(), res,R.layout.index_order_listview, new String[]{"order_id"}, new int[]{R.id.order_id} );
上面的代码中,res为ArrayList<>数组,我相信大家都无数次打印过,确保它是有值的。那么,再看执行的时候:
orderListView.setAdapter(adapter);
我的代码中,事先声明了private ListView orderListView,也就是这一步报NullPointerException错误。
如果大家理解了上面刚才关于ListView本质的说法,那么应该很明显地注意到,这里的问题是没有取得orderListView的id。需要加下如下的代码:
orderListView = (ListView)this.getActivity().findViewById(R.id.orderListView);
R.id.orderListView是定义在ListView的布局文件里面。
一个对象在使用它的方法时,一定要记得是否有实例化。一般情况下,ListView正常工作必须是要有两个布局文件:一个总文件用来装View,如index_order.xml;一个就是View(用来装内容,可以无限重复,如index_order_listview.xml)。
大家一般都只注意程序,而很少注意到布局也会造成应用的运行失败。