2010-09-22 11 views
6

मैंने अपने ListView में आलसी लोडिंग छवियों को लागू किया। मैं इंटरनेट से छवि डाउनलोड करने के लिए AsyncTask का उपयोग करता हूं और इसे UIThread में ImageView से जोड़ता हूं।एंड्रॉइड पर लिस्ट व्यू में आलसी लोडिंग छवियां

यह काम कर रहा है सिवाय इसके कि जब मैं ListView स्क्रॉल करता हूं तो तेज़ी से बदलता है, डाउनलोड की गई छवियां कभी-कभी सूची में गलत आइटमों में बाध्य होती हैं।

मुझे लगता है कि समस्या में convertView के पुन: उपयोग से है। इसे हल करने के लिए कोई विचार?

बहुत धन्यवाद।

संपादित करें: मैं निम्नलिखित के रूप में उत्तर पोस्ट:

public void setBitmap(int position, Bitmap image) { 
    View itemView = mListView.getChildAt(position - mListView.getFirstVisiblePosition()); 
    if (itemView != null) { 
     ImageView itemImageView = (ImageView) itemView.findViewById(R.id.item_imageview); 
     itemImageView.setImageBitmap(image); 
    } 
} 
+0

मैं यहाँ उदाहरण की कोशिश की http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html यह काम करता है, लेकिन अभी भी गलत छवि बाध्य करने का मौका मिला। चाल की घटना की तुलना की तुलना की तुलना जेनुज़ के जवाब के समान ही होती है। लेकिन यह ImageView के उदाहरण को पकड़ने के लिए कमजोर संदर्भ का उपयोग करता है। गहरी खोदने की जरूरत है। कोई विचार? – shiami

उत्तर

2

एक समारोह void setBitmap(Bitmap bitmap, int position) या अपने अनुकूलक में इसी तरह कहा जाता है बनाएँ। जब आपका नया बिटमैप उपलब्ध होता है तो अपने AsyncTask को इस विधि को कॉल करने दें। यह विधि यूआई-थ्रेड पर notifyDataSetChanged() पर कॉल कर सकती है ताकि यह सुनिश्चित किया जा सके कि विचार ताज़ा हो जाएं। एक एडाप्टर में विचारों के संदर्भ में संदर्भ (यहां तक ​​कि उन्हें एक AsyncTask में रखकर) खतरनाक है!

+0

यह समस्या नहीं है कि शियामी है। वह उन विचारों का पुन: उपयोग कर रहा है जिनके पास एक छवि सेट है और क्योंकि सही छवि एसिंक कार्य में सेट की गई है, पुरानी छवि तब तक दिखाई जाती है जब तक नई छवि लोड नहीं होती है। – Janusz

+1

हां, यह है। मैंने एक बार एक परियोजना पर काम किया जहां वास्तव में यह व्यवहार हुआ, और setTag() या getTag() का उपयोग करना सिर्फ एक बदसूरत कामकाज था। समाधान बिटमैप को getView() विधि में सीधे सेट करना था, जिसे स्वयंडेटाडेटांग() को सूचित करके ट्रिगर किया गया था। बेशक इससे सभी दृश्यों का ताज़ा हो जाएगा जो दिखाई दे रहे हैं, जो एक उल्लेखनीय स्टटर का कारण बन सकता है। केवल एक दृश्य को रीफ्रेश करने के लिए, यह समाधान बेहतर हो सकता है: http: // stackoverflow।कॉम/प्रश्न/3724874/एंड्रॉइड-अपडेट-सिंगल-आइटम-इन-लिस्ट – mreichelt

+0

टिप के लिए धन्यवाद। लेकिन मुझे दी गई स्थिति के अनुसार मेरी डाउनलोड की गई छवि को बाध्य करने के लिए सही उदाहरण कहां मिल सकता है? – shiami

7

दो समस्याएं हैं जो ListView में छवियों की आलसी लोडिंग के दौरान उत्पन्न होती हैं।

  1. पुरानी छवियों को तब तक दिखाया जाता है जब तक कि नए लोड नहीं होते हैं। इमेजव्यू को बस एक छवि में सेट करना लोड करना आसान है या छवि डाउनलोड शुरू करने से पहले इसे अदृश्य में सेट करें।
  2. दूसरी समस्या हल करने के लिए मुश्किल है। कल्पना कीजिए कि आप अपनी सूची के माध्यम से बहुत तेजी से स्क्रॉल कर रहे हैं। पुराने AsyncTask ने छवि लोड करना समाप्त करने से पहले अब आपके विचारों को पुनर्नवीनीकरण किया जा सकता है। अब आपके पास दो कार्य चल रहे हैं कि onPostExecute विधि में छवि दृश्य में एक छवि सेट की जाएगी। अब थोड़े समय के लिए गलत छवि तब तक दिखाई देगी जब तक कि दूसरा कार्य खत्म नहीं होता है, या कुछ नेटवर्क से संबंधित कारणों के लिए भी बदतर होता है, वे शुरू किए गए क्रम में पूरा नहीं करते हैं और आपके पास गलत छवि सही छवि को ओवरराइट करती है। इसे हल करने के लिए आपको यह जांचना होगा कि कार्य समाप्त होने के बाद कौन सी छवि प्रदर्शित की जानी चाहिए।

    setTag और getTag आप imageView कि आपके दिमाग में आता है करने के लिए किसी भी वस्तु के लिए बाध्य कर सकते हैं: View कक्षा में चीजों के लिए दो तरीकों इस तरह सटीक हैं। अधिकांश मामलों में मैं कार्य शुरू करने से पहले छवि के URL को स्ट्रिंग के रूप में छवि के URL को बाध्य करने के लिए setTag का उपयोग करता हूं। कार्य समाप्त होने के बाद अब मैं GetTag को स्ट्रिंग में डाल सकता हूं और उस यूआरएल की तुलना कर सकता हूं जिसे डाउनलोड किए गए यूआरएल के साथ प्रदर्शित किया जाना चाहिए और यदि आवश्यक हो तो केवल छवि सेट करें।

+0

धन्यवाद! आपके द्वारा वर्णित पहली समस्या मेरे लिए समाधान नहीं है। क्योंकि स्क्रॉलिंग तेजी से भिन्न होने पर 'ImageView' कई बार बाध्य की जाएगी। इसलिए ImageView को एक लोडिंग छवि या अदृश्य सेट करना काम नहीं कर रहा है। – shiami

+0

GetTag विधि प्रतीत होता है कि 'ImageView' तुरंत बाध्य नहीं होगा क्योंकि स्क्रॉलिंग के बाद टैग बदल दिया गया है। यह धीरे-धीरे दूर और पीछे स्क्रॉल करने के बाद ही अपडेट किया जाता है। क्या कोई कदम है जो मैं गलत तरीके से कर रहा हूं? – shiami

+0

मुझे समझ में नहीं आता कि GetTag के साथ आपका क्या मतलब है ImageView को तुरंत बाध्य नहीं करेगा, इसलिए मैं यह नहीं बता सकता कि आप कुछ गलत कर रहे हैं या नहीं। – Janusz

संबंधित मुद्दे