2016-06-18 36 views
0

Ich habe ein ListView und ein GridView sowohl was ich Probleme und OutOfMemory Fehler beim Scrollen, las ich im Internet über die Ausgabe und sah this Frage so habe ich erste Lösung von Sunil und implementiert sie in meinem Code. die Bilder für die GridView und ListView sind bei „/res/drawable/image1.png“ und so weiter, ich bestehen die CustomAdapter Klasse dieses int Array public static int[] mDrawableImg = {R.drawable.back, R.drawable.arrows, R.drawable.bomber, R.drawable.archers, R.drawable.knight}; und verwendet, um diesen:android listview OutOfMemory - ImageBitmaps

@Override 
public View getView(final int position, View convertView, ViewGroup parent) { 
    // TODO Auto-generated method stub 
    final Holder holder = new Holder(); 
    final View rowView = inflater.inflate(R.layout.program_list2, null); 
    holder.img = (ImageView) rowView.findViewById(R.id.imageView1); 
     holder.img.setImageResource(imageId[position]); 
    // holder.img.setImageBitmap(convertBitmap(String.valueOf(imageId[position]))); 
      return rowView; 
} 

Nun, wie Sie sehen, ich hinzugefügt eine Zeile Code, um das Bild von Bitmap mit einer Funktion namens convertBitmap zu laden, aber meine GridView ist leer, seine scrollbare Bedeutung gibt es Elemente, aber die Bilder sind nicht geladen.

convertBitmapFunktion:

public static Bitmap convertBitmap(String path) { 
    Bitmap bitmap = null; 
    BitmapFactory.Options bfOptions = new BitmapFactory.Options(); 
    bfOptions.inDither = false; 
    bfOptions.inTempStorage = new byte[32 * 1024]; 
    File file = new File(path); 
    FileInputStream fs = null; 
    try { 
     fs = new FileInputStream(file); 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } 
    try { 
     if (fs != null) { 
      bitmap = BitmapFactory.decodeFileDescriptor(fs.getFD(), null, bfOptions); 
     } 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } finally { 
     if (fs != null) { 
      try { 
       fs.close(); 
      } catch (IOException e) { 

       e.printStackTrace(); 
      } 
     } 
    } 
    return bitmap; 
} 

Was habe ich falsch gemacht, und es wird meine OutOfMemory Fehler lösen? Vielen Dank.

Antwort

1

Der Fehler, den Sie erhalten, ist absolut logisch. Schauen Sie sich diese Zeile in Ihrer getView() Methode:

final View rowView = inflater.inflate(R.layout.program_list2, null);

Was bedeutet das? Dies bedeutet, dass Sie jedes Mal eine neue Instanz des Elements erstellen, wenn Android Sie dazu auffordert, View. Das ist ziemlich verrückt, weil Sie einfach mehr Ansichten erstellen und erstellen, während Sie die ListView scrollen (so ist es ziemlich natürlich, dass Sie einen Speichermangelfehler bekommen. Und ich bin mir sicher, dass Ihr ListView scrolling laggy ist).

Und ich wette Android Studio warnt Sie dieses Problem, indem Sie diese Zeile in gelber Farbe.

Zum Glück können Sie es sehr leicht beheben. Aber lassen Sie mich Ihnen einige Dinge sagen. Sehen Sie sich die View an, die Sie in der getView()-Methode als Parameter erhalten. Siehst du es nicht? Ist die Variable, die Sie convertView aufgerufen haben. Und beachte, dass du es nicht benutzt. Was ist das View? Wird als Recycling-Ansicht bezeichnet (nicht zu verwechseln mit der Klasse RecyclerView). Ist eine Ansicht, die zuvor aufgeblasen wurde und nicht mehr verwendet wird, weil sie für den Benutzer nicht sichtbar ist. Und das, mein Freund, das ist der Schlüssel Ihres Problems und auch Ihrer Lösung: Anstatt jedes Mal eine neue Ansicht aufzublasen, recyceln Sie sie einfach. Ich verspreche dir, dass es sehr einfach ist. Jetzt ist Ihre getView methos sollte wie folgt aussehen:

@Override 
public View getView(final int position, View convertView, ViewGroup parent) { 
    if (convertView == null) 
     convertView = inflater.inflate(R.layout.program_list2, null); 

    //final Holder holder = new Holder(); 
    //holder.img = (ImageView) convertView.findViewById(R.id.imageView1); 
    //holder.img.setImageResource(imageId[position]); 


    ImageView img = (ImageView) convertView.findViewById(R.id.imageView1); 
    //Note you don't need the Holder 
    Bitmap imageBitmap = convertBitmap(imageId[position]); 
    if (imageBitmap != null) 
     img.setImageBitmap(imageBitmap); 
    else 
     img.setImageBitmap(null); 

    return convertView; 
} 

Und schauen Sie bitte auf Ihre Nutzung der ViewHolder Muster. Sie verwenden es falsch ...

+0

Sie geben die rowView zurück, aber es existiert nicht, was soll ich damit machen? – DAVIDBALAS1

+0

@ DAVIDBALAS1Oh, mein Fehler. Sehen Sie sich die bearbeitete Antwort an. Du solltest das selbe convertView verwenden –

+0

Danke, trotzdem ist das Scrollen leider immernoch ein bisschen stocky .. – DAVIDBALAS1