我有listview
,其中显示了一些images
。为了避免UI
阻止,我试图在thumbnails
中使用asyncTask
延迟加载adapter
,因为这似乎是我在SO上找到的最佳解决方案。
此listView
还有一个onItemclick
和一个onItemLongClick
听众。
出于某种原因,我的应用程序变得非常慢,尤其是在执行onlongclick
操作后。我发现不寻常的唯一事情是我的ListView
在循环中调用getView
方法,从不停止。
适配器的
public class FotoGridAdapter extends ArrayAdapter {
private Context context;
private int layoutResourceId;
private ArrayList<WorkorderPicture> workorderPictures = new ArrayList<WorkorderPicture>();
public FotoGridAdapter(Context context, int layoutResourceId, List<WorkorderPicture> pictures) {
super(context, layoutResourceId, pictures);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.workorderPictures = new ArrayList<>(pictures);
}
@Override
@Nullable
public WorkorderPicture getItem(int position) {
return workorderPictures.get(position);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder;
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new ViewHolder();
holder.imageTitle = row.findViewById(R.id.text);
holder.image = row.findViewById(R.id.image);
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
WorkorderPicture workorderPicture = workorderPictures.get(position);
if (workorderPicture != null) {
String text = workorderPicture.getTITLE();
if (workorderPicture.getPHOTODATE() != null) {
text += " - ";
text += new SimpleDateFormat("dd/MM/yyyy", Locale.getDefault()).format(workorderPicture.getPHOTODATE());
}
holder.imageTitle.setText(text);
String format = AttachmentUtils.getExtensionFromFileName(workorderPicture.getFILE_NAME_WITH_EXTENSION());
if (format == null)
format = "default";
switch (format.toLowerCase()) {
case "image/jpeg":
case "image/png":
if (workorderPicture.getPHOTOSTREAM() != null) {
new ImageGridHandler(context, holder.image, workorderPicture.getPHOTOSTREAM(), workorderPicture.getPHOTOSTREAM().length).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
// holder.image.setImageBitmap(sbm);
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
holder.image.setImageDrawable(getContext().getDrawable(R.drawable.ic_image));
} else {
holder.image.setImageDrawable(getContext().getResources().getDrawable(R.drawable.ic_image));
}
}
break;
case "application/pdf":
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
holder.image.setImageDrawable(getContext().getDrawable(R.drawable.ic_pdf));
} else {
holder.image.setImageDrawable(getContext().getResources().getDrawable(R.drawable.ic_pdf));
}
break;
default:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
holder.image.setImageDrawable(getContext().getDrawable(R.drawable.ic_empty_image));
} else {
holder.image.setImageDrawable(getContext().getResources().getDrawable(R.drawable.ic_empty_image));
}
break;
}
}
return row;
}
static class ViewHolder {
TextView imageTitle;
ImageView image;
}
class ImageGridHandler extends AsyncTask<String, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
private Context context;
private byte[] photoStream;
private int length;
public ImageGridHandler(Context context, ImageView img, byte[] photoStream, int length) {
imageViewReference = new WeakReference<>(img);
this.context = context;
this.photoStream = photoStream;
this.length = length;
}
@Override
protected Bitmap doInBackground(String... params) {
Bitmap bm = BitmapFactory.decodeByteArray(photoStream, 0, length);
return ThumbnailUtils.extractThumbnail(bm, 80, 100);
}
@Override
protected void onPostExecute(Bitmap result) {
final ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(result);
FotoGridAdapter.this.notifyDataSetChanged();
}
this.cancel(true);
}
}
}
监听
gridView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener()
{
@Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view,
final int position, long l) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext(), R.style.myAlertDialogTheme)
.setNegativeButton("Annulla", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
})
.setPositiveButton("Elimina", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
final String wpID = openedIntervention.getWorkorderPictures().get(position).getID();
realm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.where(WorkorderPicture.class).equalTo("ID", wpID).findFirst().setDELETED(true);
}
}, new Realm.Transaction.OnSuccess() {
@Override
public void onSuccess() {
openedIntervention.setWorkorderPictures(realm.where(WorkorderPicture.class)
.equalTo("WORKORDER_ID", openedIntervention.getWorkorder()
.getID())
.equalTo("DELETED", false)
.findAll());
loadData();
}
}, new Realm.Transaction.OnError() {
@Override
public void onError(Throwable error) {
}
});
}
}).setTitle(app_name)
.setMessage("Eliminare l'allegato selezionato?");
builder.show();
return true;
}
});
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, final int position,
long id) {
//code to show a preview
}});
另一个信息可能是我使用Realm
,但我的图片与之无关,所以我认为不重要
答案 0 :(得分:2)
AsyncTask
是异步的,每次完成任务后,您都会通知适配器导致数据更改事件,所以
@Override
protected void onPostExecute(Bitmap result) {
final ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(result);
// FotoGridAdapter.this.notifyDataSetChanged();
// ^^^^^^^^^^^^^^^^ remove this
// not required in case of change in imageview
}
this.cancel(true);
}