Sto usando UIL per caricare le immagini in un listview.Come forzare una cancellazione della cache usando Universal Image Loader Android?
Quando premo a lungo un'immagine nella lista, mostro una finestra di dialogo per modificare quella foto, sostituendola con una nuova usando la fotocamera.
Se faccio una nuova foto, quando la finestra di dialogo viene chiusa la mia listview mostra ancora la vecchia immagine (poiché è memorizzata nella cache). Se chiudo e riavvia la mia applicazione quando vado al mio listview, la nuova immagine è correttamente lì.
Ecco come ho creato UIL:
// Get singletone instance of ImageLoader
imageLoader = ImageLoader.getInstance();
//set display options for image loader
DisplayImageOptions displayOptions = new DisplayImageOptions.Builder()
.cacheInMemory()
.displayer(new FadeInBitmapDisplayer(500)) //fade in images
.resetViewBeforeLoading()
.build();
//set image loader options
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this).defaultDisplayImageOptions(displayOptions).build();
// Initialize ImageLoader with configuration.
imageLoader.init(config);
Se rimuovo .cacheInMemory()
tutto funziona però. Mi sto solo chiedendo se posso cancellare la cache solo aprendo la mia finestra di dialogo. Ho provato ad accedere a ImageView selezionato e chiamare myImageView.invalidate()
quando si apre la finestra di dialogo senza successo.
Le immagini vengono caricate da file:
// Load and display image asynchronously
imageLoader.displayImage(file_prefix + image_path, image);
Qualche suggerimento?
Edit: codice per creare un menu contestuale quando si preme a lungo un'immagine, ho cercato di cancellare la cache c'è:
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
//get info about item selected
AdapterView.AdapterContextMenuInfo info;
try {
// Casts the incoming data object into the type for AdapterView objects.
info = (AdapterView.AdapterContextMenuInfo) menuInfo;
} catch (ClassCastException e) {
// If the menu object can't be cast, logs an error.
Log.e("no info", "bad menuInfo", e);
return;
}
Cursor cursor = (Cursor) getListAdapter().getItem(info.position);
if (cursor == null) {
// For some reason the requested item isn't available, do nothing
return;
}
//remove selected image from cache (if it is an image)
imageUrl = cursor.getString(cursor.getColumnIndex("image_path"));
if (!imageUrl.equalsIgnoreCase("")) {
MemoryCacheUtil.removeFromCache(imageUrl, imageLoader.getMemoryCache());
}
Log.i("imageUrl", imageUrl);
//get defect row ID and text content to pass it to defect activity
defect_row_id = cursor.getLong(cursor.getColumnIndex("_id"));
defect_txt = cursor.getString(cursor.getColumnIndex("defect"));
MenuInflater inflater = getMenuInflater();
Log.i("cursor", DatabaseUtils.dumpCursorToString(cursor));
//set project identifier in context menu header, mapping cursor sequence of values
menu.setHeaderTitle(getString(R.string.select_an_option));
inflater.inflate(R.menu.menu_defect_row, menu);
}
Quando una voce di menu (modificare o eliminare) è selezionato
@Override
public boolean onContextItemSelected(MenuItem item) {
//AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId()) {
case R.id.edit:
//open defect activity with the specified image and defect pre-loaded
Intent editDefectIntent = new Intent(this, DefectActivity.class);
editDefectIntent.putExtra("defect_row_id", defect_row_id);
editDefectIntent.putExtra("imageUrl", imageUrl);
startActivity(editDefectIntent);
return true;
case R.id.delete:
askDeleteConfirm();
return true;
default:
return false;
}
}//onContextItemSelected
Edit: il codice per visualizzare l'elenco delle immagini
@Override
public void onResume() {
super.onResume();
//open connection to db
db = new DBAdapter(this);
db.open();
Log.i("DefectListActivity -> onResume", "called");
// get all defects for this unit
defectList = db.getAllDefectsByUnit(unit_id);
// create an array adapter and let it to display our row
defects = new SimpleCursorAdapter(this, R.layout.defect_row, defectList, new String[] { "defect", "image_path" }, new int[] { R.id.defect, R.id.image }, 0);
//set custom view using ViewBinder
SimpleCursorAdapter.ViewBinder binder = new SimpleCursorAdapter.ViewBinder() {
@Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
int placeholder_id = getResources().getIdentifier("placeholder", "drawable", getPackageName());
//get column name
String name = cursor.getColumnName(columnIndex);
//for the thumbnail column,if we have an image replace the placeholder
if ("image_path".equals(name)) {
ImageView image = (ImageView) view.findViewById(R.id.image);
//Bitmap thumbnail;
String image_path = cursor.getString(columnIndex);
Log.i("image_path ->", image_path);
if (!image_path.equalsIgnoreCase("")) {
// Load and display image asynchronously
imageLoader.displayImage(file_prefix + image_path, image);
} else {
image.setImageResource(placeholder_id);
}
return true;
}
//for the defect column, just add the text to the view
if ("defect".equals(name)) {
String defect_text = cursor.getString(columnIndex);
TextView defect_holder = (TextView) view.findViewById(R.id.defect);
defect_holder.setText(defect_text);
return true;
}
return false;
}
};
defects.setViewBinder(binder);
setListAdapter(defects);
}//onResume
Ho provato, non funziona. Sto aprendo un menu di scelta rapida, quindi una finestra di dialogo. Ho aggiunto queste righe al mio 'onCreateContextMenu' ma non fa nulla. Ho anche provato a passare l'URL dell'immagine alla finestra di dialogo e svuotare la cache da lì ottenendo l'imageLoader singleton, sempre lo stesso. – Mirko
Chiamate '' 'imageLoader.displayImage (file_prefix + image_path, image);' '' dopo aver sostituito l'immagine con una nuova usando la fotocamera? – NOSTRA
effettivamente PRIMA, quando si apre la finestra di dialogo – Mirko