My ListView jumps/freezes while scrolling up ( Scrolling down has no problem ) when I add images in, this doesn't happen when my keyboard is up.
I don't own the DownloadImageWithURLTask class, I cannot remember where I got it from.
public class chatAdapter extends ArrayAdapter<chatModel> {
private Context context;
public String userName = null;
public ImageView hold = null;
private static class ViewHolder{
TextView userName;
TextView userMessage;
ImageView userImage;
}
public chatAdapter(Context c, List<chatModel> items){
super(c, 0, items);
this.context = c;
}
class DownloadImageWithURLTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public DownloadImageWithURLTask(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String pathToFile = urls[0];
Bitmap bitmap = null;
try {
InputStream in = new java.net.URL(pathToFile).openStream();
bitmap = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return bitmap;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
final chatModel chatModel = getItem(position);
final ViewHolder viewHolder;
if (convertView == null){
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.activity_chat_box, parent, false);
TextView userName = (TextView)convertView.findViewById(R.id.usern);
TextView userMessage = (TextView)convertView.findViewById(R.id.msg);
final ImageView userImage = (ImageView)convertView.findViewById(R.id.imageView8);
userName.setText(chatModel.userName);
userMessage.setText(chatModel.chatMessage);
final String userAvatarURL = "http://downtowndons.eu/Downtown/Avatar/" + chatModel.userName;
DownloadImageWithURLTask downloadTask = new DownloadImageWithURLTask(userImage);
downloadTask.execute(userAvatarURL);
} else {
viewHolder = (ViewHolder)convertView.getTag();
}
convertView.setAnimation(AnimationUtils.loadAnimation(context, R.anim.abc_slide_in_bottom));
return convertView;
}
}
If your using AsyncTask to load Image in imageView.While scrolling rapidly in listview you may had chance to get OutofMemory exception.In order to solve those type of exceptions you need to handle Memory cache mechanism for handling images.By default there are plenty of image loading libraries available in android.One of the easiest library is Universal Image Loader.
Use Universal image loader for downloading images asynchronously.
http://github.com/nostra13/Android-Universal-Image-Loader
The Library itself has a sample code to download image.you may refer it.. After downloading library add library with your project and insert the below code at necessary place
Write this code in adapter constructor
ImageLoader imageloader = ImageLoader.getInstance();
imageloader.init(ImageLoaderConfiguration.createDefault(context));
DisplayImageOptions options; = new DisplayImageOptions.Builder()
.showImageForEmptyUri(R.drawable.ic_empty)
.showImageOnFail(R.drawable.ic_error)
.resetViewBeforeLoading(true).cacheOnDisk(true)
.imageScaleType(ImageScaleType.EXACTLY)
.bitmapConfig(Bitmap.Config.RGB_565).considerExifParams(true)
.cacheInMemory(true)
.displayer(new FadeInBitmapDisplayer(300)).build();
Replace this code in getView instead of yours code.
if(convertView==null){
// ... other stuff
viewHolder.userName=(TextView)convertView.findViewById(R.id.usern);
viewHolder.userMessage=(TextView)convertView.findViewById(R.id.msg);
viewHolder.userImage= (ImageView)convertView.findViewById(R.id.imageView8);
}else{
viewHolder=(ViewHolder)convertView.getTag();
}
viewHolder.userName.setText(chatModel.userName);
viewHolder.userMessage.setText(chatModel.chatMessage);
final String userAvatarURL="http://downtowndons.eu/Downtown/Avatar/"+chatModel.userName;
imageloader.displayImage(userAvatarURL, viewHolder.userImage);
To fetch images from the net, try using one of these two libraries mentioned in this answer: https://stackoverflow.com/a/22862991/1018109
I'd strongly suggest following all answers and comments on this question: Lazy load of images in ListView
The ListView Freezes because it's trying to Re-Download the images again.
One on the best practices in this case is to cache image into memory using Android LruCache or Disk using DiskLruCache for efficiency..
Check this link out, it will help you a lot..
http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html#disk-cache
Initially, your problem is fetching and loading images on scroll. Also you don't store earlier downloaded images in cache.
To solve your downloading images problem use any image caching library
Universal Image Loader
Lazy List Loader
Volley Image Loader
Glide
Picasso
Go with any of them and your problem will be solved! I have mentioned example of each library with listview. Check it out!
I'm relatively new to this, but I'm lost with your code. It doesn't look like you're actually doing anything with your viewholder pattern. Your viewholder should be a quick way of getting your two textviews and one imageview every time they get updated, which is what speeds up scrolling for listview. However, you created it but didn't actually do anything with it. So the pattern should be something like:
if(convertView==null){
// ... other stuff
viewHolder.userName=(TextView)convertView.findViewById(R.id.usern);
viewHolder.userMessage=(TextView)convertView.findViewById(R.id.msg);
viewHolder.userImage=(ImageView)convertView.findViewById(R.id.imageView8);
}else{
viewHolder=(ViewHolder)convertView.getTag();
}
viewHolder.userName.setText(chatModel.userName);
viewHolder.userMessage.setText(chatModel.chatMessage);
final String userAvatarURL="http://downtowndons.eu/Downtown/Avatar/"+chatModel.userName;
DownloadImageWithURLTask downloadTask=new DownloadImageWithURLTask(viewHolder.userImage);
downloadTask.execute(userAvatarURL);
Related
I have a List Adapter which inflates a list. On the method getView() i make an AscyncTask to get an image from internet. However, i figured out that the method getView() is called for numerous reasons, not only to inflate the list.
My question is: how to know when the method is called to inflate the list? I don't want to make a AsyncTask every time the method is called.
Here is my code:
public class ListItem extends ArrayAdapter<Carro> {
private final Activity context;
private final List<Carro> carros;
public ListItem(Activity context, List<Carro> carros) {
super(context, R.layout.list_item, carros);
this.context = context;
this.carros = carros;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View rowView = inflater.inflate(R.layout.list_item, null, true);
TextView modelo = (TextView) rowView.findViewById(R.id.modelo);
modelo.setText(carros.get(position).getModelo());
GetFoto getFoto = new GetFoto(rowView);
getFoto.execute(position);
return rowView;
}
private class GetFoto extends AsyncTask<Integer, Void, Void> {
Drawable fotoDraw;
View rowView;
int position;
public GetFoto(View view) {
this.rowView = view;
}
#Override
protected Void doInBackground(Integer... params) {
position = params[0];
HTTPHandler handler = new HTTPHandler();
fotoDraw = handler.makeServiceCallImage(carros.get(position).getFoto());
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
ImageView imagem = (ImageView) rowView.findViewById(R.id.imagem);
imagem.setImageDrawable(fotoDraw);
}
}
}
The method getView() will be called every time the view appears on the screen during the scrolling process. The number of getView() method calls can be greater than the number of elements if the ListView height is set to wrap_content.
Use some libraries like Picasso or Glide for downloading images. These libraries will cache the downloaded images that prevents unnecessary requests.
It will look like this:
Glide.with(context)
.load(imageUrl)
.into(imageView);
Or you can read this article https://developer.android.com/topic/performance/graphics/cache-bitmap.html
I recommend using RecyclerView instead of ListView. It recycling the views which prevents multiple inflation
Like Alex Nik said: use picasso or glide for picture loads.
And stop using ListViews, they are kind of deprecated, yet still supported. Use RecyclerView, it is better and easier to use.
So far I've been using a simple ArrayAdapter to display some items in a ListView. Now I also want to display images alongside the text in the ListView. I have an AsyncTask called DownloadImageTask to download images. The downloading is working perfectly, but I don't know how to display an image in the ListView and how to use the DownloadImageTask to download the images in the ListView.
This is the DownloadImageTask I use to download images into an ImageView:
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
I have also defined an ImageView alongside the ListView to download the images into the layout.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000">
<ImageView
android:id="#+id/image1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ListView
android:id="#android:id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
I call the DownloadImageTask like this:
new DownloadImageTask((ImageView) findViewById(R.id.image1)).execute(url);
How can I use the DownloadImageTask to download images and display them in the ListView alongside the text?
To achieve what you want to do you have to create a custom Adapter. To download the images I suggest you use a library like Picasso. Picasso takes care of pretty much everything when downloading the images and it really can't get any easier to use it, you just need to call this to download an image into an ImageView:
Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
It already caches images and can also transform images in many ways. Picasso is a very powerful yet easy to use library.
1) Implementing a custom Adapter
First we need to create a layout for each row in the ListView, in your case since you want to display an image and a text it needs to contain a TextView and an ImageView:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/imageView"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_margin="10dp"/>
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/imageView"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:textAlignment="gravity"
android:gravity="center"/>
</RelativeLayout>
Now we need to create a container class - called view model - to hold the data which belongs in each row of the ListView. In your case this view model contains the text you want to display and the url to the image:
private class ExampleViewModel {
private String text;
private String imageUrl;
private ExampleViewModel(String text, String imageUrl) {
this.text = text;
this.imageUrl = imageUrl;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
}
ListViews use view recycling. We can speed up the performance of the ListView by using a pattern called "view holder". Basically we save a reference to the Views inside each row and attach it to the row itself. That way we need to call the expensive findViewById() only once. This view holder class - I like to call them rows - also contain a method called bind() to bind the data from the view model to the Views in each row. We need a reference to the TextView and ImageView but we also need a Context for Picasso. I also like to define the layout associated with this row as a public constant in the row.
private class ExampleRow {
// This is a reference to the layout we defined above
public static final int LAYOUT = R.layout.list_item;
private final Context context;
private final TextView textView;
private final ImageView imageView;
private ExampleRow(Context context, View convertView) {
this.context = context;
this.imageView = (ImageView) convertView.findViewById(R.id.imageView);
this.textView = (TextView) convertview.findViewById(R.id.textView);
}
public void bind(ExampleViewModel exampleViewModel) {
this.textView.setText(exampleViewModel.getText());
Picasso.with(this.context).load(exampleViewModel.getImageUrl()).into(this.imageView);
}
}
Finally we need a custom Adapter to make this work, it's really nothing special. The only interesting part is in getView(). I will comment important parts if necessary:
public class ExampleAdapter extends BaseAdapter {
private final List<ExampleViewModel> viewModels;
private final Context context;
private final LayoutInflater inflater;
public ExampleAdapter(Context context) {
this.context = context;
this.inflater = LayoutInflater.from(context);
this.viewModels = new ArrayList<ExampleViewModel>();
}
public ExampleAdapter(Context context, List<ExampleViewModel> viewModels) {
this.context = context;
this.inflater = LayoutInflater.from(context);
this.viewModels = viewModels;
}
public List<ExampleViewModel> viewmodels() {
return this.viewModels;
}
#Override
public int getCount() {
return this.viewModels.size();
}
#Override
public ExampleViewModel getItem(int position) {
return this.viewModels.get(position);
}
#Override
public long getItemId(int position) {
// We only need to implement this if we have multiple rows with a different layout. All your rows use the same layout so we can just return 0.
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// We get the view model for this position
final ExampleViewModel viewModel = getItem(position);
ExampleRow row;
// If the convertView is null we need to create it
if(convertView == null) {
convertView = this.inflater.inflate(ExampleRow.LAYOUT, parent, false);
// In that case we also need to create a new row and attach it to the newly created View
row = new ExampleRow(this.context, convertView);
convertView.setTag(row);
}
// After that we get the row associated with this View and bind the view model to it
row = (ExampleRow) convertView.getTag();
row.bind(viewModel);
return convertView;
}
}
And that's everything you need. It's pretty much a best practice implementation of an Adapter. It uses the view holder pattern for extra performance and works perfectly with the view recycling of the ListView. It's fast, concise and easy and leaves little room for errors made by the developer which would otherwise slow the ListView down. You have perfect separation between what data you want to display (that's all in the ExampleViewModel) and how it is displayed (that's in the ExampleRow). The adapter itself doesn't know about either - as it should be!
2) How to use it
To use the code above we first need to create the view models which hold the data we want to display:
ExampleViewModel firstRow = new ExampleViewModel("First Row". "http://http://upload.wikimedia.org/wikipedia/commons/6/6f/Freiburger_Alpen.JPG");
ExampleViewModel secondRow = new ExampleViewModel("Second Row". "http://blog.caranddriver.com/wp-content/uploads/2013/05/lamborghini_egoista_three_quarter_front_view.jpg");
ExampleViewModel thirdRow = new ExampleViewModel("Third Row". "http://4.bp.blogspot.com/-vXnf7GjcXmg/UfJZE9rWc2I/AAAAAAAAGRc/x2CIlHM9IAA/s1600/aphoto49721.jpg");
We need to add all those rows into a List:
List<ExampleViewModel> viewModels = new ArrayList<ExampleViewModel>();
viewModels.add(firstRow);
viewModels.add(secondRow);
viewModels.add(thirdRow);
And after that we need to create an instance of the ExampleAdapter and pass the List of view models in the constructor. Finally we just need to set the Adapter to the ListView:
ExampleAdapter adapter = new ExampleAdapter(context, viewModels);
listView.setAdapter(adapter);
You can modify the items displayed in the ListView later on with the viewmodels() method of the ExampleAdapter! You just need to remember to always call notifyDataSetChanged() on the Adapter after modifying the view models:
adapter.viewmodels().remove(0); // Remove first view model
adapter.viewmodels().add(someNewViewModel); // Add some new view model
// Always remember to call this method after modifying the viewmodels.
// This will apply the changes to the ListView.
// If you forget to call this you will get an exception
adapter.notifyDataSetChanged();
I hope I could help you and if you have any further questions feel free to ask!
You could use an external library like Picasso or Universal Image Loader, they will give you a lot of options. Since they manage cache, you will be able to load images from urls or whatever one time and show them in several places.
You could try:
I'm not sure, but maybe you could use your DownloadClass inside the getView() method of your list's adapter in the next way:
new DownloadImageTask((ImageView) findViewById(R.id.image1)){
#Override
protected void onPostExecute(Bitmap bm) {
//set imageview src with your bitmap }}.execute(url);
}
}.execute(archivo,"investigacion");
I have a ListView binded with custom adapter and its working fine :
private class Placeslist extends ArrayAdapter<ArrayList<String>> {
private ArrayList<ArrayList<String>> items;
public Placeslist(Context context, int textViewResourceId,
ArrayList<ArrayList<String>> items) {
super(context, textViewResourceId, items);
this.items = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.locationgpsrow, null);
}
ArrayList<String> o = items.get(position);
if (o != null) {
// Binding here
TextView tv1 = (TextView) v.findViewById(R.id.txt1);
tv1.setText(o.get(0));
ImageView imView = (ImageView) v.findViewById(R.id.imageView1);
//o.get(1) // Image url e.g. http://www.some-website/image.jpg
}
return v;
}
}
I have an image source url in one of my array elements and i need to download the image and set it to ImageView in the listview item custom layout. And, I have code for that too !!
ImageView imView = (ImageView) findViewById(R.id.imageView1);
HttpURLConnection conn = (HttpURLConnection) myFileUrl.openConnection();
conn.setDoInput(true);
conn.connect();
is = conn.getInputStream();
bmImg = BitmapFactory.decodeStream(is);
is.close();
imView.setImageBitmap(Bitmap.createScaledBitmap(bmImg, width,
height, true));
I can use it in my above getView() to set imageView source. But what i want is to let the list view bind to adapter without loading images(because it'll be heavy process). And then after listView is loaded then to initiate binding all the ImageViews in rows respectively. Is their a way to achieve this or any thing that can separate the image downloading process from listView binding ?
You have to use below lib to load image on run time :-
Universal loader lib
Picasso
Urlhelper
You can go for 3rd party libraries like universalimageloader and others for it.
Otherwise, if you want to handle it on your own, just create an asyncTask to download an image from url and set it to the imageView onPostExecute callBack. You can pass the parameters(ImageView img, String Url) to this AsyncTask's Constructor, download the image in DoinBackground() and finally set it to the img onPostExecute();
You can trigger this asyncTask from the getView() method from the Adapter, may be doing this on UI thread may be required.
I have used Picasso Image library which takes care of caching and downloading easily. Have a look here:
http://square.github.io/picasso/
Universal Image Loader also does this well, with a bit more options for configuration:
https://github.com/nostra13/Android-Universal-Image-Loader
You might want to look at using a library like this as it will save data, and not do as much network operations.
Use SmartImageView to load the url to images. http://loopj.com/android-smart-image-view/
Your need to read about Lazy Loading of listview where the images are loaded asynchronously. You can use any of the libraries available out there.
A good complete tutorial about listview and lazy loading :
http://www.androidhive.info/2012/02/android-custom-listview-with-image-and-text/
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a number of "contact" objects each with an imageURL String associated with them. All the ways I've seen of putting images into a ListView involve manually putting images into a "drawable" folder and calling resources. Manually entering the images in would defeat the purpose of this. I've provided my getView method and the commented out line is the one I'm confused about.
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = inflater.inflate(R.layout.single_row, parent, false);
TextView name = (TextView) row.findViewById(R.id.topLine);
TextView phone = (TextView) row.findViewById(R.id.secondLine);
ImageView icon = (ImageView) row.findViewById(R.id.icon);
name.setText(contactArray.get(position).getName());
phone.setText((CharSequence) contactArray.get(position).getPhone().getWorkPhone());
//icon.setImage from contactArray.get(position).getImageURL(); ????
return row;
}
While using listView you should load image asynchronously, otherwise your view will be freezes and case an ANR. Following is a complete code example which would load image asynchronously.
Create this class inside your custom adapter.
class ImageDownloader extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public ImageDownloader(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String url = urls[0];
Bitmap mIcon = null;
try {
InputStream in = new java.net.URL(url).openStream();
mIcon = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
}
return mIcon;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
Now you can load the image very easily like following.
new ImageDownloader(imageView).execute("Image URL will go here");
Don't forget to add following permission into your project's Manifest.xml file
<uses-permission android:name="android.permission.INTERNET" />
Load Image from URL like this.
URL url = new URL(contactArray.get(position).getImageURL());
Bitmap bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
icon.setImageBitmap(bmp);
Perhaps if you are looking for more comprehensive way and you have very large data set. I would recomend you to use Android-Universal-Image-Loader library.
I'm trying to add images in a ListView which has an ArrayAdapter. Fyi, the toList() is a conversion from iterator to a list of the given DBObject.
I override the View getView() and set a textview and an image.
private static class EventAdapter extends ArrayAdapter<DBObject> {
public EventAdapter(Context context, int resource, Iterable<DBObject> events) {
super(context, resource, toList(events));
}
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
LayoutInflater vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.adapter_event_list, null);
DBObject event = getItem(position);
if (event != null) {
//Get the logo if any
if( ((DBObject)event.get("events")).containsField("logo") ){
String logoURL = ((DBObject)((DBObject)event.get("events")).get("logo")).get("0").toString();
ImageView eventLogo = (ImageView) v.findViewById(R.id.eventLogoList);
new setLogo().execute(logoURL, eventLogo);
}
TextView title= (TextView) v.findViewById(R.id.eventTitleList);
title.setText( ((DBObject)event.get("events")).get("title").toString() );
}
return v;
}
protected static <T> List<T> toList( Iterable<T> objects ) {
final ArrayList<T> list = new ArrayList<T>();
for( T t : objects ) list.add(t);
return list;
}
//setLogo() method here. See below
}
The text in the textview is fine. However the images are getting messed up. They seem to load in wrong places in the list. The route of the code is: 1)Get from the DB (async) 2)populate the ListView 3) while populating load each image(second async).
Here is the setLogo() AsyncTask which is inside the EventAdapter above:
private class setLogo extends AsyncTask<Object,Void,Bitmap>{
ImageView eventLogo = null;
#Override
protected Bitmap doInBackground(Object...params) {
try{
Bitmap eventImage = downloadBitmap((String) params[0]);
eventLogo = (ImageView) params[1];
return eventImage;
}
catch(Exception e){
e.printStackTrace();
return null;
}
}
#Override
protected void onPostExecute(Bitmap eventImage) {
if(eventImage!=null && eventLogo!=null){
eventLogo.setImageBitmap(eventImage);
}
}
}
I did so (using an Async) which I believe is the correct way to load images from urls. I saw this post on multithreading and from which I borrowed the downloadBitmap() method.
As explained above the images are loaded in wrong places of the ListView. What can be a robust way to load them?
Also the idea to pass the v.findViewById(R.id.eventLogoList) inside the AsyncTask is that the program will distinguish each adapter's ImageView but it seems it doesn't.
Update
After following the problem that is causing this mix I found this SO question.
I altered my code in order to check if the if is causing the problem.
//Get the logo if any
if( ((DBObject)event.get("events")).containsField("logo") ){
String logoURL = ((DBObject)((DBObject)event.get("events")).get("logo")).get("0").toString();
ImageView eventLogo = (ImageView) row.findViewById(R.id.eventLogoList);
//new setLogo().execute(logoURL, eventLogo);
TextView title= (TextView) row.findViewById(R.id.eventTitleList);
title.setText( "Shit happens" );
}
Let's say I have 40 items. The Shit happens is set on the fields that a logo field exists. If I scroll down/up the order changes and the text gets messed up. It is because the stack created inside the loop is small than the maximum of the list..I guess... I am still struggling.
PS: I found this easy library to load images asynchronously instead of DYI stuff.
Update 2
I added an else with a static url. Because of the time it take to the image to load they are still misplaced.
I would really go for a good library like Picasso.
It will handle all the hard part for you and it's very well written.
http://square.github.io/picasso/