ListView遍歷每個Item出現NullPointerException的異常

在使用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.) 

現在看一個例子

package com.jackchan.listviewexception;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity {
	
	private ListView mListView;
	private Button btn;
	private String[] items = new String[]{"Item1","Item2","Item3","Item4","Item5","Item6",
			"Item7","Item8","Item9","Item10","Item11","Item12","Item13","Item14","Item15","Item16","Item17","Item18"
			};
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mListView = (ListView)findViewById(R.id.listview);
        btn = (Button)findViewById(R.id.btn);
        mListView.setAdapter(new ListViewAdapter());
        btn.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
			//	for(int i = 0; i < mListView.getChildCount(); i++) 獲取屏幕上可顯示的Item數目
				for(int i = 0; i < mListView.getCount(); i++)//獲取ListView的所有Item數目
		        {
				//    LinearLayout linearlayout = (LinearLayout)mListView.getChildAt(i);
		        	LinearLayout linearlayout = (LinearLayout)mListView.getAdapter().getView(i, null, null);
		        	TextView textview = (TextView)linearlayout.getChildAt(0);
		        	Log.d("text", textview.getText().toString());
		        }
			}
		});
    }

    public class ViewHolder{
    	TextView textview;
    }
    
    private class ListViewAdapter extends BaseAdapter{
    	
    	
		@Override
		public int getCount() {
			// TODO Auto-generated method stub
			return items.length;
		}

		@Override
		public Object getItem(int position) {
			// TODO Auto-generated method stub
			return null;
		}

		@Override
		public long getItemId(int position) {
			// TODO Auto-generated method stub
			return 0;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			ViewHolder viewHolder = new ViewHolder();
			if(convertView == null){
				convertView = LayoutInflater.from(MainActivity.this).inflate(R.layout.listviewitem, null);
				viewHolder.textview = (TextView)convertView.findViewById(R.id.textview);
				convertView.setTag(viewHolder);
			}
			else{
				viewHolder = (ViewHolder)convertView.getTag();
			}
			viewHolder.textview.setText(items[position].toString());
			return convertView;
		}
    	
    }
}

重點看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


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" 
    android:orientation="vertical">
    <Button
        android:id="@+id/btn"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="changetext"
        />
	<ListView 
	    android:id="@+id/listview"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	    />
</LinearLayout>

listviewitem.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="match_parent"
    android:orientation="horizontal" >
    <TextView 
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        />

</LinearLayout>





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章