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?