Im gridview-adapter, getView(position == 0) aufgerufen wurde zu oft zu Messen layout, wenn setImageBitmap() in a loader

Ich habe eine GridView für das zeigen von einigen Symbolen.

BEVOR ich gelesen hatte das Anzeige Von Bitmaps Effizient aus dem Android-developer-Website, war ich Decodierung bitmap aus lokalen Pfad direkt in getView() adapter, wie diesen :

public View getView(int position, View convertView, ViewGroup parent) {
      ...
      ImageView icon = ...... (from getTag() of convertView)
      icon.setImageBitmap(BitmapUtil.decode(iconPath));
      ...
}

dieser Weg funktioniert gut, wie auch immer, ich nannte es [Direct Mode] die log-Ausgabe für getView() Methode :

getView(0)   //measure kid's layout.
getView(0)
getView(1)
getView(2)
...
getView(n)       //when scrolling gridview.
getView(n+1)
...
getView(n+3)    //scrolling again.
getView(n+4)
...

dann bin ich versucht den code zu ändern, um [Loader-Modus] im Artikel erwähnt Anzeige Von Bitmaps Effizient, wie folgt :

public View getView(int position, View convertView, ViewGroup parent) {
      ...
      ImageView icon = ...... (from getTag() of convertView)
      loadIcon(icon, iconPath);
      ...
}

in loadIcon() :

...
final CacheImageLoader loader = new CacheImageLoader(getActivity(), imageView, imageUrl, savePath);
final AsyncDrawable asyncDrawable = new AsyncDrawable(getResources(), placeHolderBitmap, loader);
imageView.setImageDrawable(asyncDrawable);

Loader in den Hörer :

@Override
public void onLoadComplete(Loader<Bitmap> arg0, Bitmap arg1) {
    ...
    ImageView imageView = imageViewReference.get();
    if (result != null && imageView != null) {
        imageView.setImageBitmap(result);
    }
}

Im Grunde ist es dasselbe wie die Ausbildung-code, tatsächlich, auf diese Weise funktioniert auch gut. Allerdings fand ich etwas anderes, in diesem Modus die getView() Methode in-adapter aufgerufen wurde zu viele Male, aber diese wiederholten Aufruf dieser Methode immer mit "position" - parameter == 0, bedeutet es etwas invoke getView(0, X, X) wiederholt.

getView(0)     //measure kid's layout.
getView(0)
getView(1)
getView(2)
...    
getView(0)     //loader completed then imageView.setImageBitmap(result); 
getView(0)     //same as above
getView(0)
getView(0)
...
getView(n)     //when scrolling gridview.
getView(n+1)
getView(n+2)
getView(0)     //loader completed then imageView.setImageBitmap(result); 
getView(0)     //same as above
getView(0)
...
getView(n+3)   //scrolling again.
getView(n+4)
getView(0)     //loader completed then imageView.setImageBitmap(result); 
getView(0)     //same as above
getView(0)

Es ist nicht gut, weil ich bin mit einem loader in getView(). Ich habe den source-code und fand Sie ursprünglich genannt imageView.setImageBitmap(result) im loader onLoadComplete Methode, und in ImageView :

 /**
 * Sets a drawable as the content of this ImageView.
 * 
 * @param drawable The drawable to set
 */
public void setImageDrawable(Drawable drawable) {
        ...

        int oldWidth = mDrawableWidth;
        int oldHeight = mDrawableHeight;

        updateDrawable(drawable);

        if (oldWidth != mDrawableWidth || oldHeight != mDrawableHeight) {
            requestLayout();
        }
        invalidate();
    }
}

hier, requestLayout() ist View Methode und führt immer entweder [Direct-Modus] oder [- Loader-Modus], in View.class :

public void requestLayout() {
    mPrivateFlags |= FORCE_LAYOUT;
    mPrivateFlags |= INVALIDATED;

    if (mLayoutParams != null) {
        mLayoutParams.onResolveLayoutDirection(getResolvedLayoutDirection());
    }

    if (mParent != null && !mParent.isLayoutRequested()) {
        mParent.requestLayout();
    }
}

aber der Unterschied ist: in [Direct-Modus], die mParent.requestLayout() wird einmal aufgerufen, aber in [Loader-Modus], jedes mal, wenn ich rufe imageView.setImageBitmap(result);, die mParent.requestLayout() aufgerufen wird, es bedeutet mParent.isLayoutRequested() zurück false, und mParent.requestLayout(); verursachen die GridView Messen Ihre kid ' s layout durch den Aufruf obtainView() zum ersten Kind und dann verursachen getView(0, X, X) :

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    ...
    mItemCount = mAdapter == null ? 0 : mAdapter.getCount();
    final int count = mItemCount;
    if (count > 0) {
        final View child = obtainView(0, mIsScrap);
    ...

So, meine Frage ist: warum mParent.isLayoutRequested() zurück false wenn ich mit [loader-Modus]? oder ist es nur ein normaler Fall ?

  • Soweit ich weiß ist es normal, Android kann jede Methode aufrufen des Adapters jederzeit und so oft Sie es mag. Es auch variiert von version zu version. Nie davon ausgehen, nichts über es. GridView ist ähnlich ListView so überprüfen Sie heraus dieses große reden youtube.com/watch?v=wDBM6wVEO70. Es sei denn, Sie sind immer einige Absturz oder memory low Fehler, Mach dir keine Gedanken und lass Sie rufen Ihre Methoden. Und ja, in [- loader-Modus] android wird aktualisiert-GUI später, wenn onLoadFinish() aufgerufen wird.
  • Überprüfen Sie "Einstellungen>die Entwickler-Optionen" > "Show Layout Updates" und starten Sie Ihre app. Wenn GUI ist entschieden, wenn Ihr alle die Lader fertig sind, dann sind Sie gut zu gehen.
  • Hast du eine Möglichkeit, um dieses? Bekomme ich diese auch.
  • möglich, Duplikat der benutzerdefinierte listview-adapter getView-Methode wird mehrfach aufgerufen, und in keine kohärente bestellen
InformationsquelleAutor raywang | 2012-09-24
Schreibe einen Kommentar