En el adaptador de gridview, se invocó getView (posición == 0) demasiadas veces para medir el diseño cuando setImageBitmap () en un cargador

tengo unGridView por mostrar algunos iconos.

Antes de haber leído estoVisualización eficiente de mapas de bits desde el sitio del desarrollador de Android, estaba descodificando el mapa de bits de la ruta local directamente engetView() de adaptador, como este:

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

De esta forma, funciona bien de todos modos, lo llamé [Modo directo], el registro de salida paragetView() El método debe ser:

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)
...

entonces estoy tratando de cambiar el código a [Modo cargador] mencionado en el artículoVisualización eficiente de mapas de bits, de la siguiente manera:

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

enloadIcon() :

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

en el oyente del cargador:

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

Básicamente, es igual que el código de entrenamiento, en realidad, de esta manera también funciona bien. Sin embargo, encontré algo diferente, en este modo elgetView() El método en el adaptador se invocó demasiadas veces, sin embargo, estas llamadas repetidas a este método siempre tienen el parámetro "posición" == 0, significa algo invocar getView(0, X, X) repetidamente.

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)

No es bueno porque estoy usando un cargador engetView(). He comprobado el código fuente y encontré que originalmente fueron llamados porimageView.setImageBitmap(result) en el cargadoronLoadComplete método, y enImageView :

 /**
 * 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();
    }
}

aquí,requestLayout() es el método de View y siempre se ejecuta en [Modo directo] o [Modo de cargador], en View.class:

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

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

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

sin embargo la diferencia es: en [Modo directo], elmParent.requestLayout() se invoca una vez, pero en [Modo cargador], cada vez que llamoimageView.setImageBitmap(result);, lamParent.requestLayout() será invocado también, significamParent.isLayoutRequested() regresofalseymParent.requestLayout(); causará elGridView medir el diseño de su niño llamandoobtainView() al primer niño y luego causagetView(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);
    ...

Así que mipregunta es porquemParent.isLayoutRequested() regresofalse si estoy usando [modo cargador]? o es solo un caso normal?

Respuestas a la pregunta(4)

Su respuesta a la pregunta