W adapterze gridview getView (pozycja == 0) był wywoływany zbyt wiele razy, aby zmierzyć układ, gdy setImageBitmap () w programie ładującym

mamGridView za wyświetlanie niektórych ikon.

PRZED przeczytaniem tegoWydajne wyświetlanie map bitowych z witryny dla programistów Androida dekodowałem bitmapę z lokalnej ścieżki bezpośrednio wgetView() adaptera, jak poniżej:

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

w ten sposób działa dobrze, nazwałem to [Tryb bezpośredni], log wyjściowygetView() metoda powinna być:

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

następnie próbuję zmienić kod na [Tryb ładowacza] wymieniony w artykuleWydajne wyświetlanie map bitowych, jak następuje:

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

wloadIcon() :

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

w odbiorniku Loadera:

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

Zasadniczo jest to samo, co kod treningowy, tak samo dobrze działa. Znalazłem jednak coś innego, w tym trybiegetView() metoda w adapterze została wywołana zbyt wiele razy, jednak te powtarzające się wywołanie tej metody zawsze z parametrem „position” == 0 oznacza, że ​​coś wywołuje getView(0, X, X) wielokrotnie.

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)

To nie jest dobre, ponieważ używam ładowarkigetView(). Sprawdziłem kod źródłowy i stwierdziłem, że są pierwotnie wywoływani przezimageView.setImageBitmap(result) w ładowarceonLoadComplete metoda i wImageView :

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

tutaj,requestLayout() jest metodą View i zawsze działa w trybie [Direct Mode] lub [Loader Mode], w View.class:

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

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

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

różnica jest jednak: w [Tryb bezpośredni],mParent.requestLayout() jest wywoływany raz, ale w [trybie ładowarki] za każdym razem, gdy dzwonięimageView.setImageBitmap(result);, themParent.requestLayout() zostanie wywołany również, to znaczymParent.isLayoutRequested() powrótfalse, imParent.requestLayout(); spowodujeGridView zmierzyć układ swojego dziecka, dzwoniącobtainView() do pierwszego dziecka, a potem do przyczynygetView(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);
    ...

Więc mojapytanie dlategomParent.isLayoutRequested() powrótfalse jeśli korzystam z [trybu ładowania]? czy jest to zwykły przypadek?

questionAnswers(4)

yourAnswerToTheQuestion