كيف يمكنني منع الصور في ListView Android هذه من التحول عندما أنقر على عناصر الشاشة الأخرى؟
-
28-09-2019 - |
سؤال
لقد قمت بعمل منشور آخر في وقت سابق حول هذا الموضوع ، لكنني قمت منذ ذلك الحين بتغيير الكود الخاص بي حول الاقتراحات ولكن هناك المشكلة نفسها. تستمر صوري في التحول إذا قمت بالنقر فوق عناصر أخرى على الشاشة.
هذا هو الرمز الذي أسميه بهذا:
Thumbnailer جديد (image_main ، image_table) .execute (Image) ؛
Image_main هو ImageView و Image_table هو الجدول الذي يحمله.
private class Thumbnailer extends AsyncTask<String, Void, Bitmap> {
private ImageView imageView;
private TableLayout imageTable;
public Thumbnailer(ImageView imageView, TableLayout imageTable) {
this.imageView = imageView;
this.imageTable = imageTable;
}
@Override
protected void onPostExecute(Bitmap result) {
imageView.setImageBitmap(result);
imageView.setVisibility(View.VISIBLE);
imageTable.setVisibility(View.VISIBLE);
}
@Override
protected void onProgressUpdate(Void... progress) {
}
@Override
protected Bitmap doInBackground(String... params) {
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeFile(params[0], o);
final int REQUIRED_SIZE=70;
//Find the correct scale value. It should be the power of 2.
int width_tmp=o.outWidth, height_tmp=o.outHeight;
int scale=1;
while(true){
if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)
break;
width_tmp/=2;
height_tmp/=2;
scale++;
}
//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize=scale;
return BitmapFactory.decodeFile(params[0], o2);
}
}
المحلول
يبدو أنك تتعرض للعض عن طريق إعادة التدوير. وهذا هو ، عندما تقوم بالتمرير لقائمة في Android ، فإنه لا ينشئ صفًا جديدًا ويعيد استخدام صف متخلف عن الشاشة. في هذه الحالة ، يمكن أن يؤدي ذلك إلى محاولة عدة مهام لتحميل صورة إلى صورة واحدة. تحتاج فعليًا إلى أن تكون قادرًا بطريقة أو بأخرى على معرفة طلب التحميل الذي هو الأحدث لصفًا واحدًا وإلغاء نتائجها السابقة/تجاهل نتائجها ، أو مجرد استخدام مكتبة تعالج هذا الأمر (مثل droid-fu
).
يمكنك أيضًا إيقاف تشغيل إعادة تدوير العرض في محولك (هذا هو الجزء الذي يستخدم convertView
حجة في getView
الطريقة) ، ولكن كن على علم بأن هذا سيجعل قائمة التمرير بطيئة ومتوترة ، وخاصة على الأجهزة القديمة.
نصائح أخرى
واجهت مشكلة مماثلة. أود تحميل الصور في ListView عبر Asynctask (والتي قد تجلب الصورة عبر HTTP) ، ويبدو أنه يحمل الصورة الخاطئة للقسمة الثانية قبل تحميل الصورة الصحيحة. كان الأمر كما لو أن Android كان يعيد استخدام الصف قبل انتهاء طلب HTTP ، وكانت المخططات المتزامنة نوعًا من التصادم.
أكدت التعليقات أعلاه أن هذا ما كان يحدث.
لقد قمت بإصلاحه عن طريق وضع مسار الصورة في علامة ImageView قبل بدء تشغيل Asynctask ، ثم التحقق من تلك العلامة بعد انتهاء Asynctask ولكن قبل استدعاء SetImageBitMap.
أضف هذه الخطوط:
final String somethingUnique = "put the image path or some other identifier here";
image_main.setTag(somethingUnique);
قبل هذا الخط:
new Thumbnailer(image_main, image_table).execute(image);
الآن ، في onpostexecute ، تحقق من العلامة:
// if this does not match, then the view has probably been reused
if (((String)imageView.getTag()).equals(somethingUnique)) {
imageView.setImageBitmap(result);
}
هذه منشور مدونة مطور Android يوفر مشروع مرجعي لهذا. فقط قم بتغيير رمز تنزيل صورة HTTP في المشروع الخاص بك doInBackground
الشفرة.