1

I have the following code in the method getView of my adapter (which populates a ListView)

public View getView(int position, View parent, ViewGroup root) {
    View view = LayoutInflater.from(getActivity()).inflate(R.layout.my_layout, null);
    ImageView imageView = view.findViewById(R.id.myImageView);
    String address = addresses[position];
    MyNetworkLibrary.loadAndSetImage(address, imageView);
    return view;
}

The cells of the ListView have an ImageView in which they load a remote image.

The method MyNetworkLibrary.loadAndSetImage download the remote image and, when it has received the response, sets it in my ImageView. The problem is that the method getView is often called more than once for each row of the ListView, than, though I use a cache, since the image is not into the cache my app performs more than one request for each row.

Is there a way for knowing when getView is called for the last time for a row? Or, do you think about a better solution?

Massimo
  • 3,436
  • 4
  • 40
  • 68
  • In your layout, what's the value you've set for the layout_width? – nKn Jan 24 '14 at 09:12
  • width = match_parent, height = wrap_content – Massimo Jan 24 '14 at 09:12
  • getView is called every time the row is to be displayed, so if the user scrolls up and down, there's no real "last call" to getView for that row."since the image is not into the cache " >> why are you not caching your images ? The opposite means a Network call for every call to getView which would be bad for performances ... – 2Dee Jan 24 '14 at 09:19
  • No, the problem is not that getView is called more than once while scrolling. It is called more than once when I populate the ListView for the first time (I think it does calculations for positioning views correctly). – Massimo Jan 24 '14 at 09:20
  • 1
    That is normal behavior, the first linked question in NKN's answer should help you understand why. There could be other reasons as well, depending on your Activity/Fragment layout. Anyway, a proper implementation of a ListView with items including images from internet should include some type of caching. If you don't want to write it yourself, consider using the excellent Picasso library : http://square.github.io/picasso/ – 2Dee Jan 24 '14 at 09:26
  • Commenting just to agree with @2Dee . Use the Picasso library. It's great, it's awesome it handles everything you need. And you can literally just replace that one line of your code with the Picasso line: `Picasso.with(context).load(address).into(imageView);` – Budius Jan 24 '14 at 09:37
  • I am already using the Volley library and I would like to avoid using other libraries (since I have already written a lot of code which use volley). However I am analyzing the links you proposed ;) – Massimo Jan 24 '14 at 09:38
  • 1
    You can use volley as well. com.android.volley.toolbox.ImageLoader has a constructor that takes a RequestQueue and a LruCache. – 2Dee Jan 24 '14 at 10:05

2 Answers2

1

The calling getView() more times than expected issue was tried to be clarified in this question. Since that's just my thought about it, I don't know it for sure, but I think the approach you propose in your question is not the right one - I mean, you shouldn't be needing to count how much times has been getView() called but instead of it handle the assignations efficiently.

As alternatives, you could load the images using a LazyList referencing each Image of the row within your getView() method. But there's another possible solution (and I think it's also more elegant), I proposed it in this another question. Hope it helps you.

Community
  • 1
  • 1
nKn
  • 13,691
  • 9
  • 45
  • 62
0

just try to use a lazy list which would simplify your work https://github.com/thest1/LazyList