checking if android list item (Drawable) is still visible - android

Let's assume i got a list of ImageView and TextView with LinearLayout.
Now i'm using simple ArrayAdapter extension that gets Strig[][] as items which is an array of double strings (each entry contains String[2] where the first string is a uri to the image and the second one is the text. i override getView to display the image and text , recyling views, of course :-).
However since image loading, even from resources may be slow, i'm doing it in an async task, that means that i have a default image loaded and i use: startLoading (it's my method) that stakes the ImageView and the Uri and once the image is ready it places it in the image view.
However sometimes, since it's a list if the image is not loaded yet and I'm in the middle of the process it's worth while stopping the loading, and that's in case that the line i'm loading image for is no longer visible.
Since the views are recycled i can't check if ImageView is visible since it may be visible but with a different Drawable... is there a way for me to know at some point that my line in invalidated and not visible ? is there a simple way or shell i need to start using flags and tag pattern and stuff like that to discover that my line is no longer valid ?

What I do is based on how the ListView manages it's views.
As there is a limited set of Views really used by the ListView and that might be passed to our Adapter through the convertView argument of the getView() method, I implemented the following:
I have a LinkedList class member where I store the Uris to be loaded. These Uris are consumed in an AsyncTask member to retrieve the pics.
Before returning the item view in getView(), my Adapter places the Urin of the item pic in the View.setTag(Object).
When I reuse a convertView, before reusing it's content I get the Uri it was previously linked to using View.getTag() and remove the corresponding element from the pending Uris LinkedList.

Related

Download images in async task and show them in ListView

I've a list of URLs, each corresponding to an image.
I need to display these images in a ListView.
Currently, my approach is pass this List<String> containing URLs to a CustomAdapter (extending BaseAdapater).
Each row item in the ListView will be inflated with an ImageView.
Then in the getView() method, if currentImageView == null, then I'll start an AsyncTask, which will download the bitmap for that imageList.get(position).
Then in the postExecute(), I'll set currentImageView.setBitmap(downloadedBitmap).
In this manner,from inside the adapter, I'll call AsyncTask one-by-one for each image.
If you think, there is something wrong in this approach then please let me know. Also, please suggest the correct approach.
One pitfall with approach I've found in when AsyncTask for a certain list element is in progress & user scrolls down then back up, the same async task will be called again.
How can I prevent this?
When your views get recycled, the currentImageView will not be null and it will keep displaying the same images. I would suggest using Universal Image Loader. It takes care of all of that for you, with TONS of extra features like caching and what not.
Try this library
Then in getView method, simply add this code
UrlImageViewHelper.setUrlDrawable(holder.image, model.getimageURL(), R.drawable.placeholder);
parameter one is your ImageView, second parameter is Image URL, and the last is placeholder image.

ListView Recycling and Withholding Drawing of Elements Until They're Completely Loaded

Two questions:
a) is there any way to stop views from getting "thrown out" when you scroll? I'm fetching images from the web using the YouTubeAPI (YouTubeThumbnailView) and it takes some time to fetch these - when scrolling the images are loaded in a couple seconds after scrolling has stopped.
and b) can I withhold elements of the listview until they are completely loaded? I'd prefer the elements to render when their thumbnails have loaded.
It seems like you're going about this the wrong way. You should be fetching the images and storing them in some sort of cache (there are numerous topics on this, so I'll leave that part as an exercise) and then notifying when the data has loaded and updating the thumbnail if it's still on screen. It shouldn't matter whether the View was "thrown out"; on the next time you try to View that particular thumbnail it should already be in the cache and should be able to be loaded near-instantly.
As for the second question, you could initially set the visibility of the View that you return in your Adapter's getView() to INVISIBLE, then when you display the thumbnail, set the thumbnail and then set the View to VISIBLE.

loading images in autocompletetextview suggestions using custom cursor adapter

I am working on an app which requires an autocompletetextview for suggesting contacts in dropdown view. I am using a custom cursor adapter. My layout for one drop down item has imageview on the left (for showing image of the contact if available, else a default image).
I have used Asynctask to load images from the contacts. In my bindView method, I have following snippet to load images from the Async task.
contactImage = new conactImage(viewHolder, cursor);
contactImage.execute(new String[] {userId});
and in the Asynctask's onPostExecute method, I set the image bitmap.
mViewHolder.cImage.setImageBitmap(imageResultBitmap);
mViewHolder is the viewholder passed as argument in the previous snippet.
The problem I am facing is a bad UX. Suppose I entered two characters in the autocompletetextview. The images show up in a second. When I scroll, the images don't change unless I wait another 2 3 seconds to get the correct image loaded. And when I scroll fast, the views flicker a lot because of the random image bitmap changes.
I understand it is a view recycling thing, but this gets annoying. Please suggest any other possible way to do the same.
on scrolling
Thanks!

How to create custom ListView like this?

I want to create a Custom listview like this the below image. I am creating a chat app, in that app have to pass text, images and video etc. see below image.
In that, when a user send/receive image in chat, if he wants to see that by clicking on the button beside that image, how to move to another activity with that image path (or) url, for showing full image, and when user clickngi on image have to show a Quick view. same way if that is video, i have to get that path (or) url to play video properly.
How to differenciate the list item depends on the item type.
If you want to show different rows for audio, image and text messages, you need to have 3 row layouts, then you will decide which row needs to be returned from your getView() of your CustomAdapter. There are two methods getViewTypeCount() and getItemViewType() of Adapter which will help your recycling the row to show up in ListView.
You will first tell that how many layouts in your ListView will be using getViewTypeCount() which tells the adapter how many row types will be there, next check what kind of data is present at that position in your data model and you return the view type from getItemViewType(), so getView() will receive the relevant recycled view (if there is any).
Here is my blog post about using 9 patch images, it demonstrate sender and receiver type of views, same can be applied for image and audio based on the item in your data model at that specific position.
You can
implement ScrollView and add views into it.
create adapter that contains all of the possible views and then decide which view to hide or to show
you can create adapter and dynamically add view into each row (in this case it's too slow).
My choise is #2 - create row view with all possible views and then decide what to hide, in this case you can save time because you won't have to inflate you views each time and you can use even ViewHolder pattern.

Change ImageView content within a GridView in Android

I am new to Android and Java. I am building an app that allows users to push a button which launches an image chooser where they can select from images on the sd card. The app loads with a grid view with 2 cells. One cell has an image view that has a default image. The other is the button. Once, the image is chosen, the image view needs to be displayed in the Image View of the Grid View.
I am using a string path that is being decoded from the images uri to create a bitmap. I then am calling imageView.setImageBitmap(bitmap). This is doing nothing. I have tried updating the image resource with a different image in the drawable folders and still nothing. I added a seperate image view just under the grid in my activity, and that image is updating fine which leads me to believe that this has to do with the grid view (this is my first grid view).
Any help is very much appreciated.
Thank you.
GridView is maybe not the right choice if you've only got two cells. You will probably have an easier time with a simple LinearLayout that has the two items you're dealing with.
But, here's how you do it with a GridView:
Create your adapter by extending BaseAdapter. The most important method is getView(), but it's where you should be doing the least amount of work.
When the GridView goes to redraw itself, it'll go through for each visible position and call getView() for each one. You'll be supplied a View. If the view is null, inflate a new one from your XML resources, populate it, and return it. If the view is NOT null, populate the existing one with the appropriate data. The widget is being efficient by recycling views.
The trick you need is that when you want the image to change, you need to call notifyDataSetChanged() on your adapter in order to trigger the redraw (which is when you'll populate the new image in the view for the appropriate cell).
That's the two-minute version. At Google I/O a year or two back, they did a talk on The World of ListView and posted it on YouTube. It was a good talk and pretty much everything there applies to GridView as well.

Categories

Resources