2016-04-24 18 views
1

Ich lade die Album-Artworks in meiner Music-App. Weil ich sie nicht auf Main-Thread laden konnte, verwende ich Threads und sie werden durcheinander gebracht!Loading Bitmaps funktioniert nicht korrekt, beim Scrollen in RecyclerView

Manchmal wird das Bild nicht in der richtigen Größe geladen oder es wird als braunes Quadrat angezeigt. Diese Probleme treten auf, wenn ich schnell blättern kann. Wenn ich langsam scrolle, funktioniert es!

Die wichtigsten Methoden meiner Musics-Klasse:

public Bitmap getAlbumArtwork(long AlbumID, int Height, int Width) { 
    ParcelFileDescriptor pfd; 

    Bitmap bCover = null; 
    BitmapFactory.Options bOptions = new BitmapFactory.Options(); 
    bOptions.inJustDecodeBounds = true; 

    try { 
     Uri ArtworkUri = Uri.parse("content://media/external/audio/albumart"); 
     Uri uri = ContentUris.withAppendedId(ArtworkUri, AlbumID); 
     pfd = mContext.getContentResolver().openFileDescriptor(uri, "r"); 

     if (pfd != null) { 
      BitmapFactory.decodeFileDescriptor(pfd.getFileDescriptor(), null, bOptions); 

      bOptions.inSampleSize = calculateInSampleSize(bOptions, Width, Height); 

      bOptions.inJustDecodeBounds = false; 

      bCover = BitmapFactory.decodeFileDescriptor(pfd.getFileDescriptor(), null, bOptions); 

      pfd.close(); 
     } 
    } 
    catch (IOException ioe) { 
     BitmapFactory.decodeResource(mContext.getResources(), R.drawable.standardartwork, bOptions); 

     bOptions.inSampleSize = calculateInSampleSize(bOptions, Width, Height); 

     bOptions.inJustDecodeBounds = false; 

     bCover = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.standardartwork, bOptions); 
    } 

    return bCover; 
} 

public void setAlbumArtwork(final long AlbumID, final ImageView ArtworkView) { 
    Thread thArtwork = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      final Bitmap bArtwork = getAlbumArtwork(AlbumID, ArtworkView.getHeight()/2, ArtworkView.getWidth()/2); 

      handler.postDelayed(new Runnable() { 
       @Override 
       public void run() { 
        ArtworkView.setImageBitmap(bArtwork); 

        threadList.remove(Thread.currentThread()); 
       } 
      }, 50); 
     } 
    }); 

    threadList.add(thArtwork); 

    thArtwork.start(); 
} 

private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { 
    final int height = options.outHeight; 
    final int width = options.outWidth; 

    int size = 1; 

    if (height > reqHeight && width > reqWidth) { 
     final int halfHeight = height/2; 
     final int halfWidth = width/2; 

     while ((halfHeight/size) > reqHeight && (halfWidth/size) > reqWidth) { 
      size *= 2; 
     } 
    } 

    return size; 
} 

Und mein RecyclerViewAdapter:

public class SongRecyclerViewAdapter extends RecyclerView.Adapter<SongRecyclerViewAdapter.Holder> { 
    private Context mContext; 
    private Song[] sSongs; 

    private MusicStore musicStore; 

    public SongRecyclerViewAdapter(Context context, Song[] songs) { 
     mContext = context; 
     sSongs = songs; 

     musicStore = new MusicStore(mContext); 
    } 

    @Override 
    public Holder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_songview, parent, false); 

     Holder holder = new Holder(view); 

     return holder; 
    } 

    @Override 
    public void onBindViewHolder(Holder holder, int position) { 
     musicStore.setAlbumArtwork(sSongs[position].getAlbumID(), holder.imvSong); 

     holder.txvSongTitle.setText(sSongs[position].getTitle()); 
     holder.txvSongInfo.setText(sSongs[position].getArtists()); 
    } 

    @Override 
    public void onViewDetachedFromWindow(Holder holder) { 

    } 

    @Override 
    public int getItemCount() { 
     return sSongs != null ? sSongs.length : 0; 
    } 

    public class Holder extends RecyclerView.ViewHolder { 
     LinearLayout linearLayout; 
     ImageView imvSong; 
     TextView txvSongTitle; 
     TextView txvSongInfo; 

     public Holder(View layout) { 
      super(layout); 

      linearLayout = (LinearLayout) layout; 

      imvSong = (ImageView) layout.findViewById(R.id.imvSong); 
      txvSongTitle = (TextView) layout.findViewById(R.id.adap_txvSongtitle); 
      txvSongInfo = (TextView) layout.findViewById(R.id.adap_txvSongInfo); 
     } 
    } 
} 

ich für andere idead absolut offen bin die Bitmaps richtig zu laden!

Sie könnten es ausprobieren, wenn Sie wollen: https://play.google.com/store/apps/details?id=at.guger.musixs

Dank!

+0

Für eine Verwendung Picasso oder Glide, um tatsächlich die Bitmaps zu laden. Die Bibliothek kümmert sich um Caching, damit Sie nicht durch Ihr Gedächtnis gehen. – toidiu

+0

Woher bekomme ich sie und wie benutze ich sie? –

Antwort

0

http://square.github.io/picasso/

Das Setup und Dokumente sind ganz einfach. Sie können auch im Uri vorbeikommen und Picasso wird es lösen.

Beispiel

Picasso.with(this).load(uri).into(imageView); 

Wenn Sie auch Dinge wie Breite und Höhe, Platzhalter und vieles mehr angeben.

.resize(width, height).placeholder(placeholderImg) 
+0

Muss ich das in einen Thread eintragen oder ist das unabhängig von meinem Haupt Thread? –

+0

Picasso behandelt all das in einem separaten Thread :) – toidiu

Verwandte Themen