विचार यह है कि किसी आइटम पर क्लिक करने के बाद आइटमों की एक सूची होनी चाहिए, एक प्रगतिबार धीरे-धीरे भर जाएगा क्योंकि कार्य पूरा हो जाएगा। उदाहरण के लिए, प्रत्येक के द्वारा एक डाउनलोड बटन के साथ, फ़ाइलों की एक सूची तस्वीर। जब डाउनलोड बटन क्लिक किया जाता है, तो फ़ाइल पृष्ठभूमि में डाउनलोड की जाती है और एक प्रगति पट्टी भर जाती है यह दर्शाती है कि फाइल को पूरा करने के करीब कितना करीब है।एक सूची दृश्य/ऑनक्लिक पर प्रोग्रेसबार जोड़ना एक बार कहा जाता है
इसे पूरा करने के लिए, मैं एक AsyncTask बना देता हूं जो कभी-कभी अधिसूचनाओं को सूचित करने के लिए एडाप्टर पर डेटाटाट को सूचित करता है। हालांकि यह एक बटन क्लिक करने के बाद काम करता है, जब तक AsyncTask पूरा नहीं हो जाता है, मैं ListView में अन्य बटन क्लिक करने में असमर्थ हूं। क्या कोई मुझे बता सकता है कि मैं क्या गलत कर रहा हूं?
मैं इसे आइस क्रीम सैंडविच पर एमुलेटर (x86) पर चला रहा हूं।
:class DownloadItem {
public String name; // Name of the file being downloaded
public Integer progress; // How much is downloaded so far
public Integer length; // Size of the file
}
मैं तो एक ArrayAdapter कि ListView के लिए DownloadItem की एक सूची adapts है:
मैं एक डाउनलोड की प्रगति (नीचे दिए गए कोड संक्षिप्तता के लिए सरल है) का प्रतिनिधित्व करने के लिए एक DownloadItem है
अभी तक, बहुत अच्छा - यह सूची को उचित रूप से प्रस्तुत करता है।
class DownloadActivity extends Activity {
//...
public void onDownloadButtonClick(View view) {
DownloadItem item = (DownloadInfo)view.getTag();
DownloadArrayAdapter adapter = (DownloadArrayAdapter) view.getAdapter();
new DownloadTask(adapter, item).execute();
//new DownloadTask(adapter, item).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)
}
}
मैं भी बस पर अमल के रूप में executeOnExecutor के साथ इस की कोशिश की है, लेकिन कोई भाग्य के साथ: मेरे गतिविधि में, मैं onClickListener है। डाउनलोड टास्क है:
class DownloadTask extends AsyncTask<Void, Integer, Void> {
ArrayAdapter<?> mAdapter;
DownloadItem mItem;
public DownloadTask(ArrayAdapter<?> adapter, DownloadItem item) {
mItem = item;
}
//Dummy implementation
@Override
public Void doInBackground(Void ... params) {
for(int i=0; i<mItem.length; ++i) {
Thread.sleep(10); publishProgress(i);
}
return null;
}
@Override
public void onProgressUpdate(Integer ... values) {
mItem.progress = values[0];
mAdapter.notifyDataSetChanged();
}
}
यह काम करता है - लगभग। जब मैं ऐसा करता हूं, तो एक बटन पर क्लिक करने के बाद, प्रोग्रेसबार सामान्य के रूप में अपडेट होता है - लेकिन जब तक AsyncTask रिटर्न नहीं होता तब तक मैं ListView में अन्य बटन क्लिक नहीं कर सकता। यही है, onDownloadButtonClick कभी नहीं कहा जाता है। अगर मैं onProgressUpdate फ़ंक्शन से mAdapter.notifyDataSetChanged() कॉल को हटा देता हूं, तो कई कार्यों को एक साथ अपडेट किया जाता है, लेकिन निश्चित रूप से, सूची को अमान्य नहीं किया गया है और इसलिए मुझे परिवर्तन देखने के लिए चारों ओर स्क्रॉल करना होगा।
मैं क्या गलत कर रहा हूं, और मैं इसे कैसे ठीक कर सकता हूं?
संपादित करें: मैंने इसके साथ कुछ और खेला, और ऐसा लगता है कि कॉलिंग अधिसूचना की आवृत्तिडेटाट चेंज प्रभावित करती है कि ऑनक्लिक कहलाया जा रहा है या बस खो रहा है या नहीं। उपर्युक्त कोड के साथ, बेतरतीब ढंग से क्लिक करके मैं कभी-कभी शुरू करने के लिए दूसरी डाउनलोड बार प्राप्त कर सकता हूं। अगर मैं थ्रेड बढ़ाता हूं। 2000 की तरह कुछ बड़ा सो जाओ, सूची मूल रूप से अपेक्षित रूप में काम करती है।
तो नया सवाल - प्रोग्रेसबार को आसानी से अपडेट करने के लिए कैसे प्राप्त किया जा सकता है जबकि क्लिक करने से क्लिक करें?
संपादित करें # 2:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if(row == null) {
// Inflate
Log.d(TAG, "Starting XML inflation");
LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.download_list_item, parent, false);
Log.d(TAG, "Finished XML inflation");
}
final DownloadItem item = mItems.get(position);
ProgressBar downloadProgressBar = (ProgressBar) row.findViewById(R.id.downloadProgressBar);
Button downloadButton = (Button) row.findViewById(R.id.downloadButton);
downloadButton.setTag(item);
downloadProgressBar.setMax(item.length);
downloadProgressBar.setProgress(item.progress);
downloadButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new DownloadTask(DownloadArrayAdapter.this, item).execute();
}
});
return row;
}
यह आप सूची दृश्य का उपयोग लगता है? यदि ऐसा है, और यदि आपके पास समय है, तो मुझे लगता है कि यह देखना उचित है: [Google I/O 2010 - सूची दृश्य] (http://www.youtube.com/watch?v=wDBM6wVEO70)। एक सुझाव: आप 'थ्रेड.sleep (800)' (उदाहरण के लिए) का उपयोग कर सकते हैं, '10' आवश्यक नहीं है। –
आप क्लिक श्रोता कहाँ सेट करते हैं? आप इसे डमी कोड में याद करते हैं। – reTs
@reTS: मैंने इसे XML में सेट किया है, एंड्रॉइड के साथ: बटन के लिए ऑनक्लिक पैरामीटर। हैंडलर निश्चित रूप से कहा जा रहा है - वैसे भी, वैसे भी। हालांकि प्रश्न में मेरा संपादन देखें। – mindvirus