I want to load images from a server, AFTER loading the data in a list view. I know that a lot of topics existing for this problem but I haven't found the solution...
So this is my code :
//asyncTackClass for loadingpictures
public class LoadImagesThread extends AsyncTask<Bundle, Void, Bitmap> {
private ImageView view;
private Bitmap bm;
private Context context;
private final WeakReference<ImageView> imageViewReference;
private final String BUNDLE_URL = "url";
private final String BUNDLE_NAME = "name";
private final String BUNDLE_BM = "bm";
public LoadImagesThread(Context context, ImageView view) {
this.context=context;
imageViewReference = new WeakReference<ImageView>(view);
}
@Override
protected Bitmap doInBackground(Bundle... b) {
Bitmap bm =null;
if (StorageHelper.getBitmap(b[0].getString(BUNDLE_NAME)) != null) { // Check the sdcard
bm = StorageHelper.getBitmap(b[0].getString(BUNDLE_NAME));
Log.w("LoadImagesThread", "Get image from sdcard : "+b[0].getString(BUNDLE_NAME));
} else { // Check the server
bm = ServiceHelper.getBitmapFromURL(b[0].getString(BUNDLE_URL));
StorageHelper.saveBitmap(bm, b[0].getString(BUNDLE_NAME)); // Save image on sdcard
Log.w("LoadImagesThread", "Get image from server : "+b[0].getString(BUNDLE_NAME));
}
return bm;
}
@Override
protected void onPostExecute(final Bitmap bm) {
super.onPostExecute(bm);
if (bm != null){ //if bitmap exists...
view = imageViewReference.get();
// Fade out
Animation fadeOutAnimation = AnimationUtils.loadAnimation(context, R.anim.fadeoutimage);
fadeOutAnimation.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation animation) {
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationEnd(Animation animation) {
// Fade in
view.setImageBitmap(bm);
Animation fadeInAnimation = AnimationUtils.loadAnimation(context, R.anim.fadeinimage);
view.startAnimation(fadeInAnimation);
}
});
// Launch the fadeout
view.startAnimation(fadeOutAnimation);
}else{ //if not picture, display the default ressource
view.setImageResource(R.drawable.productcarre);
}
}
}
The code is used to display a Bitmap in a ImageView
And this is the adapter:
public class ListViewShoplistStoresAdapter extends BaseAdapter {
private ArrayList<Shop> shopList;
private Activity activity;
private HashMap<Integer, ImageView> views;
private final String BUNDLE_URL = "url";
private final String BUNDLE_NAME = "name";
private final String BUNDLE_POS = "pos";
private final String BUNDLE_ID = "id";
public ListViewShoplistStoresAdapter(Activity activity, ArrayList<Shop> shopList) {
super();
this.activity = activity;
this.shopList = shopList;
this.views = new HashMap<Integer, ImageView>();
}
public int getCount() {
return shopList.size();
}
public Object getItem(int position) {
return shopList.get(position);
}
public long getItemId(int position) {
return shopList.get(position).getId();
}
private class ViewHolder {
public TextView store;
public TextView name;
public ImageView ImageStore;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder view;
LayoutInflater inflator = activity.getLayoutInflater();
if(convertView == null) {
view = new ViewHolder();
convertView = inflator.inflate(R.layout.listviewshops, null);
view.store = (TextView) convertView.findViewById(R.id.store);
view.name = (TextView) convertView.findViewById(R.id.name);
view.ImageStore = (ImageView) convertView.findViewById(R.id.imgstore);
convertView.setTag(view);
}else {
view = (ViewHolder) convertView.getTag();
}
Typeface regular=Typeface.createFromAsset(activity.getAssets(), "fonts/RobotoRegular.ttf");
view.store.setTypeface(regular);
Typeface light=Typeface.createFromAsset(activity.getAssets(), "fonts/RobotoLight.ttf");
view.store.setTypeface(light);
Brand brand = StorageHelper.getBrand(activity, shopList.get(position).getBrandId());
if (brand == null) {
Log.e("SetShopInAdapter","Brand null");
Toast.makeText(activity, "Impossible d'afficher la liste de magasins", Toast.LENGTH_LONG).show();
} else {
view.store.setText(brand.getName());
view.name.setText(shopList.get(position).getName());
view.ImageStore.setImageResource(R.drawable.productcarre);
}
Bundle b = new Bundle();
//url of the pict
b.putString(BUNDLE_URL, ServiceHelper.getImageUrl("brand", brand.getName()));
// name of image
b.putString(BUNDLE_NAME, ServiceHelper.getCleanImageName(brand.getName()));
//position in the listView
b.putInt(BUNDLE_POS, position);
//id of the current object
b.putInt(BUNDLE_ID, brand.getId());
//put info in the map in order to display in the onPostExecute
if(views.get(position)==null){
views.put(position, view.ImageStore);
// launch thread
new LoadImagesThread(activity.getApplicationContext(), view.ImageStore).execute(b);
}
return convertView;
}
}
So, when I used a GridView, there were no problems, but when I use a ListView the image is changed only in the first item !
Example: I want to display product images for "car", "house" and "apple" items. The code will launch the thread and all images (car then house and finally apple) will be displayed in the first item (the car item)... And the house and the apple while not have images !!
Do you know what I should do ?
Thanks
There is a lot about this here on SO.. asynchrnous loading like that is called "Lazy Loading"
https://github.com/thest1/LazyList
for full implementation of such a process with list
For loading images in general i recomend this :
https://github.com/nostra13/Android-Universal-Image-Loader
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With