में setImageBitmap() सेट करते समय getView (position == 0) को लेआउट को मापने के लिए कई बार बुलाया गया था, मेरे पास कुछ आइकन दिखाने के लिए GridView
है।ग्रिडव्यू एडाप्टर में, लोडव्यू
से पहले मैं Android डेवलपर साइट से इस Displaying Bitmaps Efficiently पढ़ा था, मैं एडाप्टर के getView()
में सीधे स्थानीय पथ से बिटमैप डिकोडिंग किया गया था, इस तरह:
public View getView(int position, View convertView, ViewGroup parent) {
...
ImageView icon = ...... (from getTag() of convertView)
icon.setImageBitmap(BitmapUtil.decode(iconPath));
...
}
इस तरह से ठीक काम करता है वैसे भी, मैं इसे [प्रत्यक्ष मोड कहा जाता ], 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)
...
तो मैं निम्नलिखित के रूप में, लेख Displaying Bitmaps Efficiently में उल्लेख किया [लोडर मोड] के लिए कोड बदलने की कोशिश कर रहा हूँ:
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);
लोडर के श्रोता में
:
@Override
public void onLoadComplete(Loader<Bitmap> arg0, Bitmap arg1) {
...
ImageView imageView = imageViewReference.get();
if (result != null && imageView != null) {
imageView.setImageBitmap(result);
}
}
असल में, यह प्रशिक्षण कोड के रूप में ही है, वास्तव में, इस तरह से काम करता है ठीक भी है। हालांकि, मुझे कुछ अलग मिला, इस मोड में getView()
एडाप्टर में विधि को कई बार बुलाया गया था, हालांकि, इन पद्धतियों को हमेशा "स्थिति" पैरामीटर == 0 के साथ दोहराया जाता है, इसका मतलब है कि कुछ बार बार etView(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()
में एक लोडर उपयोग कर रहा हूँ नहीं है। मैं स्रोत कोड की जाँच की है और पाया है कि वे मूल रूप से लोडर के onLoadComplete
विधि में imageView.setImageBitmap(result)
द्वारा कहा जाता है और 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.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();
पहले बच्चे को obtainView()
फोन करके GridView
उपाय है अपने बच्चे के लेआउट का कारण और उसके बाद का कारण होगा 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);
...
तो, मेरा प्रश्न है: क्यों mParent.isLayoutRequested()
वापसी false
यदि मैं [लोडर मोड] का उपयोग कर रहा हूं? या यह सिर्फ एक सामान्य मामला है?
जहां तक मुझे पता है कि यह सामान्य है, एंड्रॉइड किसी भी समय आपके एडाप्टर की किसी भी विधि को कॉल कर सकता है और जितनी बार पसंद करता है। यह संस्करण से संस्करण में भी भिन्न होता है। इसके बारे में कभी भी कुछ न मानें। 'GridView'' ListView' के समान है, इसलिए इस महान बात को देखें http://www.youtube.com/watch?v=wDBM6wVEO70। जब तक आपको कुछ क्रैश या स्मृति कम त्रुटि न हो, तब तक इसके बारे में चिंता न करें और इसे अपनी विधियों को कॉल न करें। और हाँ [लोडर मोड] में एंड्रॉइड बाद में GUI को रीफ्रेश करेगा जब भी ऑनलोड लोड() कहा जाता है। –
"सेटिंग्स> डेवलपर विकल्प> लेआउट अपडेट दिखाएं" की जांच करें और अपना ऐप लॉन्च करें। यदि आपके सभी लोडर समाप्त होने पर जीयूआई बस जाता है तो आप जाने के लिए अच्छे हैं। –
क्या आपको इसके आसपास कोई रास्ता मिला? मुझे यह भी मिलता है। – Matthias