В адаптере gridview getView (position == 0) вызывался слишком много раз, чтобы измерить компоновку, когда setImageBitmap () в загрузчике
у меня естьGridView
для показа некоторых значков.
ДО того, как я прочитал этоЭффективное отображение растровых изображений с сайта разработчика Android, я декодировал растровое изображение с локального пути прямо вgetView()
адаптера, вот так:
public View getView(int position, View convertView, ViewGroup parent) {
...
ImageView icon = ...... (from getTag() of convertView)
icon.setImageBitmap(BitmapUtil.decode(iconPath));
...
}
в любом случае этот способ работает нормально, я назвал его [Direct Mode], выходной журнал дляgetView()
Метод должен быть:
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)
...
затем я пытаюсь изменить код на [Режим загрузчика], упомянутый в статьеЭффективное отображение растровых изображенийследующим образом:
public View getView(int position, View convertView, ViewGroup parent) {
...
ImageView icon = ...... (from getTag() of convertView)
loadIcon(icon, iconPath);
...
}
вloadIcon()
:
...
final CacheImageLoader loader = new CacheImageLoader(getActivity(), imageView, imageUrl, savePath);
final AsyncDrawable asyncDrawable = new AsyncDrawable(getResources(), placeHolderBitmap, loader);
imageView.setImageDrawable(asyncDrawable);
в слушателе Loader:
@Override
public void onLoadComplete(Loader<Bitmap> arg0, Bitmap arg1) {
...
ImageView imageView = imageViewReference.get();
if (result != null && imageView != null) {
imageView.setImageBitmap(result);
}
}
По сути, это то же самое, что и обучающий код, на самом деле, этот способ также работает нормально. Тем не менее, я нашел что-то другое, в этом режимеgetView()
метод в адаптере вызывался слишком много раз, однако повторный вызов этого метода всегда с & quot; position & quot; параметр == 0, это означает, что что-то вызывает getView(0, X, X)
несколько раз.
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)
Это не хорошо, потому что я использую загрузчик вgetView()
, Я проверил исходный код и обнаружил, что они первоначально вызваныimageView.setImageBitmap(result)
в загрузчикахonLoadComplete
метод, и в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();
}
}
Вот,requestLayout()
является методом View и всегда выполняется в [Direct Mode] или [Loader Mode] в View.class:
public void requestLayout() {
mPrivateFlags |= FORCE_LAYOUT;
mPrivateFlags |= INVALIDATED;
if (mLayoutParams != null) {
mLayoutParams.onResolveLayoutDirection(getResolvedLayoutDirection());
}
if (mParent != null && !mParent.isLayoutRequested()) {
mParent.requestLayout();
}
}
однако разница в следующем: в [прямом режиме]mParent.requestLayout()
вызывается один раз, но в [Режим загрузчика], каждый раз, когда я звонюimageView.setImageBitmap(result);
,mParent.requestLayout()
будет также вызываться, это означает,mParent.isLayoutRequested()
вернутьfalse
, а такжеmParent.requestLayout();
вызоветGridView
измерить расположение ребенка, позвонив по телефонуobtainView()
сначала ребенок, а затем вызвать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);
...
Так что мойquestion вот почемуmParent.isLayoutRequested()
вернутьfalse
если я использую [режим загрузчика]? или это просто нормальный случай?