2013-06-19 141 views
0

ALL,應用程序的奇怪崩潰

我遇到了非常奇怪的Android應用程序崩潰。 這裏是代碼:

@Override 
public View getView(int position, View convert, ViewGroup parent) 
{ 
    View row = convert; 
    ImageView image = null; 
    TextView name = null, price = null; 
    if(row == null) 
    { 
     LayoutInflater inflater = ((Activity) context).getLayoutInflater(); 
     row = inflater.inflate(resource, parent, false); 
     image = (ImageView) row.findViewById(R.id.product_picture); 
     name = (TextView) row.findViewById(R.id.product_name); 
     price = (TextView) row.findViewById(R.id.product_price); 
     row.setTag(products.get(position)); 
    } 
    Product product = products.get(position); 
    name.setText(product.getProduct_name()); 
    image.setImageBitmap(product.getProduct_picture()); 
    price.setText(String.valueOf(product.getProduct_price())); 
    return row; 
} 

此列表視圖有3行。前兩個是可見的,沒有問題。但是,當我嘗試滾動顯示第三行程序崩潰與行「name.setText(...);」NULL指針異常「

我在我的HTC手機上運行,​​而不是模擬器。

有沒有人經歷過這樣的事情?你如何調試和修復它?或者,也許它是一個指示手機壞了?

謝謝。

回答

3

Listview重複使用滾動而不是創建新的行視圖。因此,在滾動中,您的「convert」不會爲空,並且您不會運行「name =(TextView)row.findViewById(R.id.product_name)」,並且「name」將保留爲空。所以,當你稍後將嘗試將文本設置爲名稱時,您將得到NullReferenceException。

您應該始終通過findViewById啓動您的小部件對象。

更改您的代碼,它應該工作的好:

@Override 
public View getView(int position, View convert, ViewGroup parent) 
{ 
    View row = convert; 
    ImageView image = null; 
    TextView name = null, price = null; 
    if(row == null) 
    { 
     LayoutInflater inflater = ((Activity) context).getLayoutInflater(); 
     row = inflater.inflate(resource, parent, false); 
    } 
    image = (ImageView) row.findViewById(R.id.product_picture); 
    name = (TextView) row.findViewById(R.id.product_name); 
    price = (TextView) row.findViewById(R.id.product_price); 
    row.setTag(products.get(position)); 

    Product product = products.get(position); 
    name.setText(product.getProduct_name()); 
    image.setImageBitmap(product.getProduct_picture()); 
    price.setText(String.valueOf(product.getProduct_price())); 
    return row; 
} 
+3

很明顯,代碼需要更改,但是您能否詳細說明爲什麼/需要更改,以便OP瞭解錯誤? – codeMagic

+0

當然。列表視圖在滾動而不是創建新視圖時重用您的行視圖。在這種情況下,您的「convert」不會爲空,並且您不會運行「name =(TextView)row.findViewById(R.id.product_name)」,並且「name」將保留爲空。所以,當你的信將嘗試設置文本的名字,你會得到NullReference – Dimmerg

+0

這更好,但它會更有幫助,如果你更新你的答案與解釋。它只是讓OP和其他人更容易閱讀和理解問題,以及爲什麼這會解決問題。代碼只回答一般皺眉:( – codeMagic

3

這是非常合情合理的。

首先您將name設置爲空。 如果row爲空,那麼你創建了一個新行並得到了name等,這應該可以正常工作。

但是,如果row不爲空(即當convertView不爲空),然後name將永遠不會被設置,因此將是,當你達到name.setText(product.getProduct_name());

+1

好的解釋。要解決這個問題,我可能會建議使用[Viewholder](http://developer.android.com/training/improving-layouts/smooth-scrolling.html#ViewHolder)並觀看[Google I/O Turbo Charge your UI](http ://www.google.com/events/io/2009/sessions/TurboChargeUiAndroidFast.html)有點舊但仍值得關注 – codeMagic

1

更改爲空:

if(row == null){ 
    LayoutInflater inflater = ((Activity) context).getLayoutInflater(); 
    row = inflater.inflate(resource, parent, false); 
} 

image = (ImageView) row.findViewById(R.id.product_picture); 
name = (TextView) row.findViewById(R.id.product_name); 
price = (TextView) row.findViewById(R.id.product_price); 
row.setTag(products.get(position)); 

這種改變的原因是,如果你的行不是空的,你仍然需要告訴你的變量它們指向哪些對象,然後才能使用它們,否則你只會在創建一個新行時設置你的變量。