简体   繁体   English

使用AsyncTask将图像加载到ListView适配器中

[英]Using AsyncTask to load images into a adapter for ListView

Hello So I Was Having Problems With My List View That Contains Songs And There AlbumArt and I Want To make an AsyncTask To Get The Album Art In background. 您好,所以我在包含歌曲和ListArt的列表视图中遇到问题,我想创建一个AsyncTask来获取背景中的Album Art。

Put Its either giving Me A NullPointer Or The Album Art is Blank Please Help 把它给我一个NullPointer或专辑封面是空白的请帮助

ImageLoader.java ImageLoader.java

public class ImageLoader extends AsyncTask<Object, String, Bitmap> {

private View view;
private Bitmap bitmap = null;
public static BitmapDrawable drawable = null;
Context context;
Cursor cursor;
long albumId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));

@Override
protected Bitmap doInBackground(Object... parameters) {

    // Get the passed arguments here
    final Uri ART_CONTENT_URI = Uri.parse("content://media/external/audio/albumart");
    Uri albumArtUri = ContentUris.withAppendedId(ART_CONTENT_URI, albumId);
    ContentResolver res = context.getContentResolver();
      InputStream in;

      try {
          if(bitmap != null)
          {
            bitmap = null;
              if(drawable != null)
              {
                  drawable = null;
              }
          }
          in = res.openInputStream(albumArtUri);
          bitmap = BitmapFactory.decodeStream(in);
          Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, 1280, 720, false);
          // bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), albumArtUri);
          drawable = new BitmapDrawable(context.getResources(), resizedBitmap);
      } catch (FileNotFoundException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
          drawable = (BitmapDrawable) context.getResources().getDrawable(R.drawable.default_artwork);
      };
    return bitmap;
}

@Override
protected void onPostExecute(Bitmap bitmap) {
    if (bitmap != null && view != null) {
        ImageView albumArt = (ImageView) view.getTag(R.id.iconlist);
        albumArt.setImageBitmap(bitmap);
    }
}
}

SongAdapter.java SongAdapter.java

public class SongAdapter extends CursorAdapter implements SectionIndexer{
private String mSections = "#ABCDEFGHIJKLMNOPQRSTUVWXYZ";



private final LayoutInflater mInflater;


 public SongAdapter(Context context, Cursor c, int textViewResourceId,
        List<String> objects) {
    super(context, c,textViewResourceId);
    new ImageLoader().execute();
    mInflater=LayoutInflater.from(context);

}





@Override
public void bindView(View view, Context context, Cursor cursor) {
    TextView title1 = (TextView) view.findViewById(R.id.titlelist);
    TextView artist1 = (TextView) view.findViewById(R.id.artistlist);
    ImageView album1 = (ImageView) view.findViewById(R.id.iconlist);

    String title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
    String artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
    String album = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM));
   long albumId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));
      StringBuilder titleBuild = new StringBuilder();
      titleBuild.append(title);
      if(titleBuild.length() > 35)
      {
      titleBuild.setLength(32);
      title = titleBuild.toString()+"...";
      }
      else
      {
          title = titleBuild.toString();
      }
      StringBuilder artistBuild = new StringBuilder();
      artistBuild.append(artist);
      if(artistBuild.length() > 35)
      {
      artistBuild.setLength(32);
      artist = artistBuild.toString()+"...";
      }
      else
      {
      artist = artistBuild.toString();
      }






album1.setImageDrawable(ImageLoader.drawable);
title1.setText(title);
artist1.setText(artist);
}







@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
    // TODO Auto-generated method stub
    LayoutInflater inflater = (LayoutInflater)context.getSystemService
              (Context.LAYOUT_INFLATER_SERVICE);
    return inflater.inflate(R.layout.rowlayout, parent, false);
}@Override
public int getPositionForSection(int section) {
    // If there is no item for current section, previous section will be selected
    for (int i = section; i >= 0; i--) {
        for (int j = 0; j < getCount(); j++) {
            if (i == 0) {
                // For numeric section
                for (int k = 0; k <= 9; k++) {
                    if (StringMatcher.match(String.valueOf(( getItem(j))), String.valueOf(k)))
                        return j;
                }
            } else {
                if (StringMatcher.match(String.valueOf(getItem(j)), String.valueOf(mSections.charAt(i))))
                    return j;
            }
        }
    }
    return 0;
}

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

@Override
public Object[] getSections() {
    String[] sections = new String[mSections.length()];
    for (int i = 0; i < mSections.length(); i++)
        sections[i] = String.valueOf(mSections.charAt(i));
    return sections;
}
}

Now This Code Gives Me A Null Pointer So Any Help Would Be Great 现在,此代码为我提供了一个空指针,因此任何帮助都将非常有用

Your view object in the Async task is never initialized, atleast I don't see that code. 您在Async任务中的视图对象永远不会初始化,至少我看不到该代码。 What I think you could do is launch a new AsyncTask for every "new" view you're creating in your adapter. 我认为您可以为在适配器中创建的每个“新”视图启动一个新的AsyncTask。 You would need to make the async task have a reference to the imageview you want to populate though. 您需要使异步任务具有对要填充的imageview的引用。 One way to do this is like this. 一种方法是这样的。

public class ImageLoader extends AsyncTask<Object, String, Bitmap> {

private WeakReference<ImageView> mReference;
private View view;
private Bitmap bitmap = null;
public static BitmapDrawable drawable = null;
Context context;
Cursor cursor;
long albumId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));

public ImageLoader(ImageView imageView) {
      mReference = new WeakReference<ImageView>(imageView);
}

@Override
protected Bitmap doInBackground(Object... parameters) { ... your code }

@Override
protected Void onPostExecute(Bitmap bitmap) {
 if(mReference != null) {
    if(bitmap != null) {
     ImageView view = mReference.get();
     // note that this could still return null if the view or the reference has been 
     // garbage collected which it could be since it is a weak reference, so you should
     // always check the status in this case.

     //do what you want with the image view. 
    }
  } 
}

then in your adapter do something like this. 然后在您的适配器中执行以下操作。

public class SongAdapter extends CursorAdapter implements SectionIndexer{

...other code... 

@Override
public void bindView(View view, Context context, Cursor cursor) {
    TextView title1 = (TextView) view.findViewById(R.id.titlelist);
    TextView artist1 = (TextView) view.findViewById(R.id.artistlist);
    ImageView album1 = (ImageView) view.findViewById(R.id.iconlist);

    String title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
    String artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
    String album = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM));
   long albumId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));
      StringBuilder titleBuild = new StringBuilder();
      titleBuild.append(title);
      if(titleBuild.length() > 35)
      {
      titleBuild.setLength(32);
      title = titleBuild.toString()+"...";
      }
      else
      {
          title = titleBuild.toString();
      }
      StringBuilder artistBuild = new StringBuilder();
      artistBuild.append(artist);
      if(artistBuild.length() > 35)
      {
      artistBuild.setLength(32);
      artist = artistBuild.toString()+"...";
      }
      else
      {
      artist = artistBuild.toString();
      }



<---->
// new code
new ImageLoader(album1).execute();

// old code album1.setImageDrawable(ImageLoader.drawable);
title1.setText(title);
artist1.setText(artist);
}

}

I've used a similar technique in a grid view and it's cool because you can actually see each image view being populated. 我在网格视图中使用了类似的技术,这很酷,因为您实际上可以看到每个图像视图都在填充。

Hope that helps! 希望有帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM