Im Gridview-Adapter wurde getView (position == 0) zu oft aufgerufen, um das Layout zu messen, wenn setImageBitmap () in einem Loader verwendet wurde

Ich habe einGridView zum Anzeigen einiger Symbole.

Bevor ich das gelesen hatteBitmaps effizient anzeigen Von der Android-Entwicklerseite dekodierte ich eine Bitmap vom lokalen Pfad direkt ingetView() Adapter, wie folgt:

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

auf diese weise funktioniert es trotzdem, ich nannte es [direct mode], das ausgabeprotokoll fürgetView() Methode sollte sein:

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 versuche ich, den Code in [Loader Mode] zu ändern, der im Artikel erwähnt wirdBitmaps effizient anzeigen, wie folgt :

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

imloadIcon() :

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

im Loader Listener:

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

Grundsätzlich ist es dasselbe wie der Trainingscode, tatsächlich funktioniert dieser Weg auch gut. Allerdings habe ich etwas anderes gefunden, in diesem Modus dasgetView() Die Methode im Adapter wurde zu oft aufgerufen, diese wiederholen jedoch den Aufruf dieser Methode immer mit dem Parameter "position" == 0, was bedeutet, dass etwas g aufgerufen wirdetView(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 einen Lader benutzegetView(). Ich habe den Quellcode überprüft und festgestellt, dass sie ursprünglich von aufgerufen wurdenimageView.setImageBitmap(result) im LaderonLoadComplete Methode und inImageView :

 /**
 * 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 die Methode von View und wird in View.class immer entweder im [Direct Mode] oder im [Loader Mode] ausgeführt:

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

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

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

Der Unterschied besteht jedoch darin, dass im [Direktmodus] diemParent.requestLayout() wird einmal aufgerufen, aber bei jedem Anruf im [Loader-Modus]imageView.setImageBitmap(result);, dasmParent.requestLayout() wird auch aufgerufen, es bedeutetmParent.isLayoutRequested() Rückkehrfalse, undmParent.requestLayout(); wird das verursachenGridView Messen Sie das Layout Ihres Kindes, indem Sie anrufenobtainView() zuerst scherzen und dann verursachengetView(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 meinFrage ist: warummParent.isLayoutRequested() Rückkehrfalse Wenn ich [Lademodus] verwende? oder ist es nur ein normaler Fall?

Antworten auf die Frage(4)

Ihre Antwort auf die Frage