0

我一直在試圖讓我的ListView滾動更平滑的ViewPager,但它不斷崩潰。我已經嘗試過三種解決方案。屏幕打開,負載指示器顯示,但過了一段時間(約3-5秒),它崩潰。要從URL加載圖像,我使用nostra13的Universal-Image-Loader lib。沒有添加ViewHolder,它都運行良好。ListView適配器中的ViewHolder無法正常工作

我的logcat和getView + ViewHolder在適配器類:

logcat的

01-30 17:01:53.713: E/AndroidRuntime(12702): FATAL EXCEPTION: main 
01-30 17:01:53.713: E/AndroidRuntime(12702): java.lang.NullPointerException 
01-30 17:01:53.713: E/AndroidRuntime(12702): at com.example.animalist.AnimalAdapter$1.onLoadingComplete(AnimalAdapter.java:123) 
01-30 17:01:53.713: E/AndroidRuntime(12702): at com.nostra13.universalimageloader.core.DisplayBitmapTask.run(DisplayBitmapTask.java:74) 
01-30 17:01:53.713: E/AndroidRuntime(12702): at android.os.Handler.handleCallback(Handler.java:587) 
01-30 17:01:53.713: E/AndroidRuntime(12702): at android.os.Handler.dispatchMessage(Handler.java:92) 
01-30 17:01:53.713: E/AndroidRuntime(12702): at android.os.Looper.loop(Looper.java:143) 
01-30 17:01:53.713: E/AndroidRuntime(12702): at android.app.ActivityThread.main(ActivityThread.java:4263) 
01-30 17:01:53.713: E/AndroidRuntime(12702): at java.lang.reflect.Method.invokeNative(Native Method) 
01-30 17:01:53.713: E/AndroidRuntime(12702): at java.lang.reflect.Method.invoke(Method.java:507) 
01-30 17:01:53.713: E/AndroidRuntime(12702): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 
01-30 17:01:53.713: E/AndroidRuntime(12702): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 
01-30 17:01:53.713: E/AndroidRuntime(12702): at dalvik.system.NativeStart.main(Native Method) 
01-30 17:01:57.957: I/wpa_supplicant(15739): Reset vh_switch_counter due to receive LINKSPEED cmd 

在AnimalAdapter.java - getView + ViewHolder

static class ViewHolder{ 
     TextView animalView; 
     TextView areaView; 
     ImageView notfound; 
     ImageView animalPic; 
     ProgressBar indicator; 
    } 


    public View getView(int position, View convertView, ViewGroup parent){ 

     ViewHolder holder = null; 



     if(convertView == null){ 
       LayoutInflater mLayoutInflater = LayoutInflater.from(mContext); 
       convertView = mLayoutInflater.inflate(R.layout.animal_row_item, null); 
       holder = new ViewHolder(); 

      holder.animalView = (TextView) convertView.findViewById(R.id.animal_text); 
       holder.areaView = (TextView) convertView.findViewById(R.id.area_text); 
      holder.notfound = (ImageView) convertView.findViewById(R.id.notfoundimg); 
       holder.animalPic = (ImageView)convertView.findViewById(R.id.animal_pic); 
       holder.indicator = (ProgressBar)convertView.findViewById(R.id.progress); 
       convertView.setTag(holder); 
      } 

     else{ 
      holder = (ViewHolder) convertView.getTag(); 

     } 

      final Animal animal = mAnimals.get(position); 




      holder.notfound.setVisibility(View.INVISIBLE); 
      holder.indicator.setVisibility(View.VISIBLE); 
      holder.animalPic.setVisibility(View.INVISIBLE); 

      //Setup a listener we can use to switch from the loading indicator to the Image once it's ready 
      ImageLoadingListener listener = new ImageLoadingListener(){ 


       ViewHolder holder = null; 
       @Override 
       public void onLoadingStarted(String arg0, View arg1) { 
        // TODO Auto-generated method stub 

       } 

       @Override 
       public void onLoadingCancelled(String arg0, View arg1) { 
        // TODO Auto-generated method stub 

       } 

       @Override 
       public void onLoadingComplete(String arg0, View arg1, Bitmap arg2) { 
        holder.indicator.setVisibility(View.INVISIBLE); 
        holder.animalPic.setVisibility(View.VISIBLE); 
        holder.notfound.setVisibility(View.INVISIBLE); 
       } 

       @Override 
       public void onLoadingFailed(String arg0, View view, FailReason arg2) { 
        holder.notfound.setVisibility(View.VISIBLE); 
        holder.indicator.setVisibility(View.INVISIBLE); 
        holder.animalPic.setVisibility(View.INVISIBLE); 
       } 

      }; 



      imageLoader.displayImage(animal.getImgUrl(), holder.animalPic,options, listener); 
      holder.animalView.setText(animal.getAnimal()); 
      holder.areaView.setText(animal.getArea()); 





      convertView.setOnClickListener(new OnClickListener() { 

       @Override 
       public void onClick(View view) { 

        Intent intent = new Intent(getContext(), MoreActivity.class); 

        intent.putExtra("about", animal.getAbout()); 
        intent.putExtra("animal", animal.getAnimal()); 
        intent.putExtra("imgUrl", animal.getImgUrl()); 
        getContext().startActivity(intent); 
       } 
      }); 

      return convertView; 
     } 

你有什麼想法,如何改進它?

在此先感謝

+0

什麼是你AnimalAdapter.java的82th行? – nKn

+0

刪除'View vi = convertView;'並使用if(convertView == null){'和'convertView = mLayoutInflater.inflate(R.layout.animal_row_item,null);' – Raghunandan

+0

嗨,非常感謝您的回答,它的真實性。但我得到了不同的(但我認爲不太嚴重)的錯誤。我更新了我的代碼 – marson

回答

3

的事實,在堆棧跟蹤你有

01-30 16:45:09.003: E/AndroidRuntime(12533): at android.widget.ListView.measureHeightOfChildren(ListView.java:1264) 
01-30 16:45:09.003: E/AndroidRuntime(12533): at android.widget.ListView.onMeasure(ListView.java:1127) 

建議您在返回convertView是null

關於您的第二個問題,您在ImageLoadingListener內的ViewHolder實例始終爲null。你應該照顧到相應的初始化它

+0

你有什麼想法,如何更好地初始化它?現在它終於加載我的文本對象,並且當它加載圖像時,它崩潰。所以這個問題肯定存在 – marson

1

我覺得你的邏輯是不對的,在你的getView()方法你測試:

if (vi == null){ 

但是,你應該測試是否:

if (convertView == null) { 

嘗試改變它應該以這種方式工作。

---- ----編輯

你初始化ViewHolder似乎確定以我的方式,以後可以爲每個實例通過findViewById()一個View,這是確定 - 如果你得到一個NullPointerException設置可見性,這意味着由於某種原因,findViewById()返回一個空對象 - 即它沒有找到名稱爲R.id.progress的ID(可能在您的佈局中沒有該名稱)。

---- ----編輯

這裏去我的適配器的getView()方法的一個例子:

public static class vhItem { 
    TextView maintext; 
    TextView topictext; 
    ImageView mainimage; 
    TextView users; 
} 

@Override 
public View getView(final int position, View convertView, final ViewGroup parent) { 
    vhItem viewHolder; 

    if (convertView == null) { 
    final LayoutInflater inflater = ((Activity) context).getLayoutInflater(); 
    convertView = inflater.inflate(resourceId, parent, false); 

    viewHolder = new vhItem(); 
    viewHolder.maintext = (TextView) convertView.findViewById(R.id.chanlist_chan); 
    viewHolder.topictext = (TextView) convertView.findViewById(R.id.chanlist_topic); 
    viewHolder.mainimage = (ImageView) convertView.findViewById(R.id.chanlist_featured); 
    viewHolder.users = (TextView) convertView.findViewById(R.id.chanlist_usercount); 

    // I've set a contextual menu for each row this way, but it's not required 
    ((Activity) context).registerForContextMenu(convertView); 
    } 
    else 
    viewHolder = (vhItem) convertView.getTag(); 

    viewHolder.maintext.setText((String) getItem(position)); 
    viewHolder.mainimage.setTag(getItem(position)); 
    viewHolder.mainimage.setOnClickListener(new View.OnClickListener() { 
    public void onClick(final View v) { 
     AlertDialog.Builder builder = new AlertDialog.Builder(context); 
     ... 
     dialog.show(); 
    } 
    }); 

    return convertView; 
} 
+0

在getView的第一行OP將'converView'設置爲'vi',這不是問題 –

+0

嗨,非常感謝你的回答,它的真實性。但我得到了不同的(但我認爲不太嚴重)的錯誤。我更新了我的代碼 – marson

+0

線123是什麼? – Raghunandan

相關問題