首页 > 技术文章 > ListView遍历每个Item出现NullPointerException的异常

sishahu 2016-05-17 13:46 原文

在使用ListView过程中我们有时候需要遍历取得每个Item项中的一些数据(比如每个Item里面有TextView,需要获取它的文本等等),但是我们在遍历过程中经常会遇到NullPointerException的异常,其实这不过是listview中getCount()和getChildCount()这个两个函数的一些使用上的不同导致的。

getChildCount():这个函数是获取ListView在当前界面上能够被看到的(不是所有)Item的数目,因为ListView中当Item很多的时候,有些无法显示在屏幕上。

getCount():这个函数就是可以获取ListView中可见的和不可见的所有Item项数目(附上该函数返回值的官方英文解释)

The number of items owned by the Adapter associated with this AdapterView. (This is the number of data items, which may be larger than the number of visible views.) 

现在看一个例子

 

[java] view plain copy
 
  1. package com.jackchan.listviewexception;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.util.Log;  
  6. import android.view.LayoutInflater;  
  7. import android.view.View;  
  8. import android.view.View.OnClickListener;  
  9. import android.view.ViewGroup;  
  10. import android.widget.BaseAdapter;  
  11. import android.widget.Button;  
  12. import android.widget.LinearLayout;  
  13. import android.widget.ListView;  
  14. import android.widget.TextView;  
  15.   
  16. public class MainActivity extends Activity {  
  17.       
  18.     private ListView mListView;  
  19.     private Button btn;  
  20.     private String[] items = new String[]{"Item1","Item2","Item3","Item4","Item5","Item6",  
  21.             "Item7","Item8","Item9","Item10","Item11","Item12","Item13","Item14","Item15","Item16","Item17","Item18"  
  22.             };  
  23.     @Override  
  24.     public void onCreate(Bundle savedInstanceState) {  
  25.         super.onCreate(savedInstanceState);  
  26.         setContentView(R.layout.main);  
  27.         mListView = (ListView)findViewById(R.id.listview);  
  28.         btn = (Button)findViewById(R.id.btn);  
  29.         mListView.setAdapter(new ListViewAdapter());  
  30.         btn.setOnClickListener(new OnClickListener() {  
  31.               
  32.             @Override  
  33.             public void onClick(View v) {  
  34.             //  for(int i = 0; i < mListView.getChildCount(); i++) 获取屏幕上可显示的Item数目  
  35.                 for(int i = 0; i < mListView.getCount(); i++)//获取ListView的所有Item数目  
  36.                 {  
  37.                 //    LinearLayout linearlayout = (LinearLayout)mListView.getChildAt(i);  
  38.                     LinearLayout linearlayout = (LinearLayout)mListView.getAdapter().getView(i, null, null);  
  39.                     TextView textview = (TextView)linearlayout.getChildAt(0);  
  40.                     Log.d("text", textview.getText().toString());  
  41.                 }  
  42.             }  
  43.         });  
  44.     }  
  45.   
  46.     public class ViewHolder{  
  47.         TextView textview;  
  48.     }  
  49.       
  50.     private class ListViewAdapter extends BaseAdapter{  
  51.           
  52.           
  53.         @Override  
  54.         public int getCount() {  
  55.             // TODO Auto-generated method stub  
  56.             return items.length;  
  57.         }  
  58.   
  59.         @Override  
  60.         public Object getItem(int position) {  
  61.             // TODO Auto-generated method stub  
  62.             return null;  
  63.         }  
  64.   
  65.         @Override  
  66.         public long getItemId(int position) {  
  67.             // TODO Auto-generated method stub  
  68.             return 0;  
  69.         }  
  70.   
  71.         @Override  
  72.         public View getView(int position, View convertView, ViewGroup parent) {  
  73.             ViewHolder viewHolder = new ViewHolder();  
  74.             if(convertView == null){  
  75.                 convertView = LayoutInflater.from(MainActivity.this).inflate(R.layout.listviewitem, null);  
  76.                 viewHolder.textview = (TextView)convertView.findViewById(R.id.textview);  
  77.                 convertView.setTag(viewHolder);  
  78.             }  
  79.             else{  
  80.                 viewHolder = (ViewHolder)convertView.getTag();  
  81.             }  
  82.             viewHolder.textview.setText(items[position].toString());  
  83.             return convertView;  
  84.         }  
  85.           
  86.     }  
  87. }  


重点看Button的OnClickListener事件,当我们使用for(int i = 0; i < mListView.getChildCount(); i++) 

 

就只能对当前屏幕可见的Item做遍历,不能到达我们要对所有Item遍历的目的。

在for循环里还有一个被我注释起来的方法getChildAt();

getChildAt():这个函数是用来获得ListView的Item,它能取到的Item的最大值为当前可见的Item数目,比如,当前屏幕只能看到ListView的6个Item,但你调用了getChildAt(6),相当于要获得ListView第七个可见的Item,这个时候就会报出NullPointerException ,我在这里提供的解决方法就是调用adapter的getView方法,这个方法可以获取ListView的所有Item,mListView.getAdapter().getView(i, null, null);

ListView在Android开发中是经常用到的组件,除非只做展示功能,否则一般建议自定义Adapter,这样可以省去很多麻烦。最后附上两个.xml的代码

main.xml

 

 

[html] view plain copy
 
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"   
  5.     android:orientation="vertical">  
  6.     <Button  
  7.         android:id="@+id/btn"  
  8.         android:layout_width="fill_parent"  
  9.         android:layout_height="wrap_content"  
  10.         android:text="changetext"  
  11.         />  
  12.     <ListView   
  13.         android:id="@+id/listview"  
  14.         android:layout_width="fill_parent"  
  15.         android:layout_height="wrap_content"  
  16.         />  
  17. </LinearLayout>  


listviewitem.xml

 

 


 
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    3.     android:layout_width="match_parent"  
    4.     android:layout_height="match_parent"  
    5.     android:orientation="horizontal" >  
    6.     <TextView   
    7.         android:id="@+id/textview"  
    8.         android:layout_width="wrap_content"  
    9.         android:layout_height="wrap_content"  
    10.         android:textSize="20sp"  
    11.         />  
    12.   
    13. </LinearLayout>  

推荐阅读