2012-03-07 85 views
0

好吧,我用這個項目作爲起點,以我的項目: https://github.com/thest1/LazyList/懶圖像加載到ListView控件

相反,他LazyAdapter我用一個,我提出,以下內容:

public class CardAdapter extends ArrayAdapter<Card> { 
    private Card[] cards; 
    private Context context; 
    private LayoutInflater mInflater; 
    public ImageLoader imageLoader; 


    public CardAdapter (Context context, int textViewResourcesId, Card[] cards) 
    { 
     super(context, textViewResourcesId, cards); 
     this.cards = cards; 
     this.context = context; 
     mInflater = LayoutInflater.from(context); 
    } 

    private static class ViewHolder { 
     public ImageView iconView; 
     public TextView nameTextView; 
     public TextView descText; 
     public TextView manaText; 
     public TextView atkdef; 
     public TextView edicao; 
     public TextView tipo; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) 
    { 
     ViewHolder holder; 
     if (convertView == null) { 
      convertView = mInflater.inflate(R.layout.listrow, parent, false); 
     TextView nameTextView = (TextView) convertView 
        .findViewById(R.id.Nome); 
      TextView descText = (TextView) convertView 
        .findViewById(R.id.descricao); 
      TextView manaText = (TextView) convertView 
        .findViewById(R.id.mana); 
      TextView atkdef = (TextView) convertView 
      .findViewById(R.id.atkdef); 
      TextView edicao = (TextView) convertView 
       .findViewById(R.id.edicao); 
      TextView tipo = (TextView) convertView 
       .findViewById(R.id.tipo); 
      ImageView iconView = (ImageView) convertView 
        .findViewById(R.id.imageView1); 

      holder = new ViewHolder(); 
      holder.nameTextView = nameTextView; 
      holder.descText = descText; 
      holder.manaText = manaText; 
      holder.atkdef = atkdef; 
      holder.edicao = edicao; 
      holder.tipo = tipo; 
      holder.iconView = iconView; 
      holder.iconView.setTag(cards[position].URL); 

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

     holder.nameTextView.setText(cards[position].name);           holder.descText.setText(setSpanOnText(cards[position].descricao),BufferType.SPANNABLE); 
     holder.manaText.setText(setSpanOnManaText(cards[position].mana), BufferType.SPANNABLE); 
     if (cards[position].tipo.toLowerCase().contains("creature")) 
      holder.atkdef.setText(cards[position].power + "/" + cards[position].toughness); 
     else 
      holder.atkdef.setText(""); 
     holder.edicao.setText("Edition: " + cards[position].edicao); 
     holder.tipo.setText(cards[position].tipo); 
     holder.iconView.setTag(cards[position].URL); 
     imageLoader.DisplayImage(cards[position].URL, holder.iconView); 
     return convertView; 
    } 
} 

這是工作直到我添加了「imageLoader.DisplayImage(cards [position] .URL,holder.iconView);」這是懶惰的負載部分,當我嘗試訪問列表視圖時,它開始崩潰,有人在想什麼?我沒有改變在ImageLoader/FileCache/MemoryCache/Utils從另一個項目...

謝謝你的建議!

+3

它開始崩潰,然後把你的Logcat? – 2012-03-07 09:58:33

+0

發佈您的logcat錯誤也 – 2012-03-07 09:58:35

+0

請把你的錯誤日誌在這裏 – chengbo 2012-03-07 09:58:46

回答

0

我以前使用過這個lazy-loader代碼,它試圖訪問你的SD卡,因此請確保你在清單中設置了正確的權限。

此外,你不應該訪問ListView,只是對應於標籤的ImageView。你確定你做得對嗎?您可能需要使用此類發佈代碼。

在ListView使用它的正確方法是:

imageView.setTag(image_url); 
imageLoader.DisplayImage(image_url, imageView); 
的順序

+0

正是,holder.iconView.setTag(卡[位置] .URL); imageLoader.DisplayImage(cards [position] .URL,holder.iconView); – 2012-03-07 10:14:50

+0

我有兩個權限,要訪問SD和INTERNET ...仍然不工作 – 2012-03-07 10:54:57

+0

在你的代碼中,你正在分離setTag和displayImage調用。嘗試像我在我的回答中所建議的那樣做。 – josephus 2012-03-08 01:31:12

0
package com.jaapp; 

    import java.util.ArrayList; 

    import android.app.Activity; 
    import android.app.ProgressDialog; 
    import android.content.Context; 
    import android.content.Intent; 
    import android.graphics.Color; 
    import android.os.AsyncTask; 
    import android.os.Bundle; 
    import android.view.LayoutInflater; 
    import android.view.View; 
    import android.view.View.OnClickListener; 
    import android.view.ViewGroup; 
    import android.widget.BaseAdapter; 
    import android.widget.ImageView; 
    import android.widget.ListView; 
    import android.widget.TextView; 

    import com.jaapp.application.JaappApplication; 
    import com.jaapp.db.Jaappdb; 
    import com.jaapp.dto.SubtypeDto; 
    import com.jaapp.lazyloader.ImageLoader; 

    public class SubTypeActivity extends Activity { 

     ArrayList<SubtypeDto> arrylistsubtype = new ArrayList<SubtypeDto>(); 
     ListView list; 

     @Override 
     public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 

      setContentView(R.layout.subtype); 
      new subtypeAsyncTask().execute(); 

     } 

     public class subtypeAsyncTask extends AsyncTask<Void, Void, Void> { 
      private ProgressDialog progrssdilaog; 

      @Override 
      protected void onPreExecute() { 

       progrssdilaog = ProgressDialog.show(SubTypeActivity.this, 
         "Please wait", "Loading Data ...", true); 

      } 

      @Override 
      protected Void doInBackground(Void... params) { 

       arrylistsubtype = Jaappdb.getSubtypeDtos(); 

       return null; 
      } 

      @Override 
      protected void onPostExecute(Void result) { 

       progrssdilaog.dismiss(); 

       list = (ListView) findViewById(R.id.list); 
       list.setAdapter(new Listadatper(SubTypeActivity.this, 
         arrylistsubtype)); 

      } 

     } 

     public class Listadatper extends BaseAdapter { 
      private Activity activity; 

      public ImageLoader imageLoader; 

      ArrayList<SubtypeDto> mlist; 

      public int[] selected; 
      public int countcolor = 0; 

      public int i = 0; 
      public String[] Colorname = { "#FFFF00", "#ACCC00" }; 

      public Listadatper(SubTypeActivity secondActivity, 
        ArrayList<SubtypeDto> arrylistsubtype) { 

       this.activity = secondActivity; 
       mlist = arrylistsubtype; 

       selected = new int[mlist.size()]; 

       for (int i = 0; i < mlist.size(); i++) { 
        selected[i] = 0; 
       } 

      } 

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

       LayoutInflater inflater = (LayoutInflater) activity 
         .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

       View gridView; 

       gridView = inflater.inflate(R.layout.list_row, null); 

       TextView txt_name = (TextView) gridView 
         .findViewById(R.id.txt_entrepreneur); 

       ImageView img_icon = (ImageView) gridView 
         .findViewById(R.id.img_entrepreneur); 
       txt_name.setText(mlist.get(position).getName()); 

       imageLoader = new ImageLoader(activity.getApplicationContext()); 
       imageLoader.DisplayImage(getString(R.string.imagelink) + mlist.get(position).getLogo(), activity, img_icon); 
       if(position % 2 == 0) { 
        gridView.setBackgroundColor(Color.parseColor(Colorname[0])); 
       } else { 
        gridView.setBackgroundColor(Color.parseColor(Colorname[1])); 
       } 

       gridView.setOnClickListener(new OnClickListener() { 

        @Override 
        public void onClick(View v) { 

         Intent i = new Intent(SubTypeActivity.this, 
           SubOptionTypeActivity.class); 
         JaappApplication.subtypeid = mlist.get(position).getId(); 
         startActivity(i); 

        } 
       }); 

       return gridView; 
      } 

      @Override 
      public int getCount() { 
       return mlist.size(); 
      } 

      @Override 
      public Object getItem(int position) { 
       return null; 
      } 

      @Override 
      public long getItemId(int position) { 
       return 0; 
      } 

     } 

    } 


    ------------------------------------------------------------------------------------------ 
    package com.jaapp.lazyloader; 

    import java.io.File; 
    import java.io.FileInputStream; 
    import java.io.FileNotFoundException; 
    import java.io.FileOutputStream; 
    import java.io.InputStream; 
    import java.io.OutputStream; 
    import java.net.URL; 
    import java.util.HashMap; 
    import java.util.Stack; 

    import android.app.Activity; 
    import android.content.Context; 
    import android.graphics.Bitmap; 
    import android.graphics.BitmapFactory; 
    import android.widget.ImageView; 

    import com.jaapp.R; 


    public class ImageLoader { 

     private HashMap<String, Bitmap> cache=new HashMap<String, Bitmap>(); 

     private File cacheDir; 

     public ImageLoader(Context context){ 

      photoLoaderThread.setPriority(Thread.NORM_PRIORITY-1); 


      if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) 
       cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"LazyList"); 
      else 
       cacheDir=context.getCacheDir(); 
      if(!cacheDir.exists()) 
       cacheDir.mkdirs(); 
     } 

     final int stub_id=R.drawable.stub; 
     public void DisplayImage(String url, Activity activity, ImageView imageView) 
     { 
      if(cache.containsKey(url)) 
       imageView.setImageBitmap(cache.get(url)); 
      else 
      { 
       queuePhoto(url, activity, imageView); 
       imageView.setImageResource(stub_id); 
      }  
     } 

     private void queuePhoto(String url, Activity activity, ImageView imageView) 
     { 
      photosQueue.Clean(imageView); 
      PhotoToLoad p=new PhotoToLoad(url, imageView); 
      synchronized(photosQueue.photosToLoad){ 
       photosQueue.photosToLoad.push(p); 
       photosQueue.photosToLoad.notifyAll(); 
      } 

      if(photoLoaderThread.getState()==Thread.State.NEW) 
       photoLoaderThread.start(); 
     } 

     private Bitmap getBitmap(String url) 
     { 

      String filename=String.valueOf(url.hashCode()); 
      File f=new File(cacheDir, filename); 

      //from SD cache 
      Bitmap b = decodeFile(f); 
      if(b!=null) 
       return b; 

      //from web 
      try { 
       Bitmap bitmap=null; 
       InputStream is=new URL(url).openStream(); 
       OutputStream os = new FileOutputStream(f); 
       Utils.CopyStream(is, os); 
       os.close(); 
       bitmap = decodeFile(f); 
       return bitmap; 
      } catch (Exception ex){ 
       ex.printStackTrace(); 
       return null; 
      } 
     } 

     //decodes image and scales it to reduce memory consumption 
     private Bitmap decodeFile(File f){ 
      try { 
       //decode image size 
       BitmapFactory.Options o = new BitmapFactory.Options(); 
       o.inJustDecodeBounds = true; 
       BitmapFactory.decodeStream(new FileInputStream(f),null,o); 

       //Find the correct scale value. It should be the power of 2. 
       final int REQUIRED_SIZE=70; 
       int width_tmp=o.outWidth, height_tmp=o.outHeight; 
       int scale=1; 
       while(true){ 
        if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE) 
         break; 
        width_tmp/=2; 
        height_tmp/=2; 
        scale++; 
       } 

       //decode with inSampleSize 
       BitmapFactory.Options o2 = new BitmapFactory.Options(); 
       o2.inSampleSize=scale; 
       return BitmapFactory.decodeStream(new FileInputStream(f), null, o2); 
      } catch (FileNotFoundException e) {} 
      return null; 
     } 

     //Task for the queue 
     private class PhotoToLoad 
     { 
      public String url; 
      public ImageView imageView; 
      public PhotoToLoad(String u, ImageView i){ 
       url=u; 
       imageView=i; 
      } 
     } 

     PhotosQueue photosQueue=new PhotosQueue(); 

     public void stopThread() 
     { 
      photoLoaderThread.interrupt(); 
     } 

     //stores list of photos to download 
     class PhotosQueue 
     { 
      private Stack<PhotoToLoad> photosToLoad=new Stack<PhotoToLoad>(); 

      //removes all instances of this ImageView 
      public void Clean(ImageView image) 
      { 
       for(int j=0 ;j<photosToLoad.size();){ 
        if(photosToLoad.get(j).imageView==image) 
         photosToLoad.remove(j); 
        else 
         ++j; 
       } 
      } 
     } 

     class PhotosLoader extends Thread { 
      public void run() { 
       try { 
        while(true) 
        { 
         //thread waits until there are any images to load in the queue 
         if(photosQueue.photosToLoad.size()==0) 
          synchronized(photosQueue.photosToLoad){ 
           photosQueue.photosToLoad.wait(); 
          } 
         if(photosQueue.photosToLoad.size()!=0) 
         { 
          PhotoToLoad photoToLoad; 
          synchronized(photosQueue.photosToLoad){ 
           photoToLoad=photosQueue.photosToLoad.pop(); 
          } 
          Bitmap bmp=getBitmap(photoToLoad.url); 
          cache.put(photoToLoad.url, bmp); 
          //if(((String)photoToLoad.imageView.getTag()).equals(photoToLoad.url)){ 
           BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad.imageView); 
           Activity a=(Activity)photoToLoad.imageView.getContext(); 
           a.runOnUiThread(bd); 
          // } 
         } 
         if(Thread.interrupted()) 
          break; 
        } 
       } catch (InterruptedException e) { 
        //allow thread to exit 
       } 
      } 
     } 

     PhotosLoader photoLoaderThread=new PhotosLoader(); 

     //Used to display bitmap in the UI thread 
     class BitmapDisplayer implements Runnable 
     { 
      Bitmap bitmap; 
      ImageView imageView; 
      public BitmapDisplayer(Bitmap b, ImageView i){bitmap=b;imageView=i;} 
      public void run() 
      { 
       if(bitmap!=null) 
        imageView.setImageBitmap(bitmap); 
       else 
        imageView.setImageResource(stub_id); 
      } 
     } 

     public void clearCache() { 
      //clear memory cache 
      cache.clear(); 

      //clear SD cache 
      File[] files=cacheDir.listFiles(); 
      for(File f:files) 
       f.delete(); 
     } 

    } 
    ------------------------------------------------------------------------------------------ 
    package com.jaapp.lazyloader; 

    import java.io.InputStream; 
    import java.io.OutputStream; 

    public class Utils { 
     public static void CopyStream(InputStream is, OutputStream os) 
     { 
      final int buffer_size=1024; 
      try 
      { 
       byte[] bytes=new byte[buffer_size]; 
       for(;;) 
       { 
        int count=is.read(bytes, 0, buffer_size); 
        if(count==-1) 
         break; 
        os.write(bytes, 0, count); 
       } 
      } 
      catch(Exception ex){} 
     } 
    }