Android List View - android

So basically I have a function which is something like that :
public static Bitmap getBitmapFromURL(String src)
, which return decrypted Bitmap.I need to be able to use that Bitmap into a Lazy loading ListView.
Example :
So I have a ListView.I'm downloading encrypted images and use that getBitmapFromURL function to return them as Bitmap,and after that I want to be able to reload the ListView with the new images which getBitmapFromURL returns to me.I want to find a way to save them in cache so when there is like 50 loaded jpg's in ListView I want to be able to delete the first loaded and keep only these which are visible while scrolling the ListView.And do exactly the same thing when I have another 50 loaded images.Any Suggestions how I can do this?

This is the well-known lazyList :
http://open-pim.com/tmp/LazyList.zip
I have created the gridView with spinner I will upload it tomorrow and make it available (: Maybe create a tutorial ... I am off now I will keep you in mind

Related

ImageView always return blank when set programmatically

i still new to Android and want to know if there is a proper way to load image from an Input Stream.
If i load the image directly from Database the image will return the image just fine without any problem.
here my code to set ImageView Bitmap from Database :
varIDCardImageBinary = rs.getBinaryStream("IDCardImage");
classMyData.setDataInputStream(varIDCardImageBinary,"IDCardImage"); // Save Binary to a variable inside my Class
varimgIDCardView.setImageBitmap(BitmapFactory.decodeStream(classMyData.getInputStream("IDCardImage")));
Code above is working fine, And as you can see. I actually call the image AFTER i save the image into a variable.
I also put the function if the variable in my class is not empty, the ImageView Bitmap will be set from the variable without needed to call from Database again. Here is my code to call the image :
varIDCardImageBinary = classMyData.getInputStream("IDCardImage");
varimgIDCardView.setImageResource(0);
varimgIDCardView.setImageBitmap(BitmapFactory.decodeStream(varIDCardImageBinary));
And for some reason the ImageView is still BLANK, I have also tried code below to see if the Variable is empty or not :
Toast.makeText(DocumentAccountActivity.this, "Loaded From Class " + varIDCardImageBinary.toString(), Toast.LENGTH_SHORT).show();
But the result is not empty at all. Even so the ImageView still return blank. Is there anything wrong with how i set the Bitmap ? and What is the proper way to call it ?
EDITED :
I also have tried using Glide just like primo suggesting, but the result still the same.
here my code :
varIDCardImageBinary = classMyData.getInputStream("IDCardImage");
Glide.with(DocumentAccountActivity.this)
.asBitmap().load(varIDCardImageBinary).into(varimgIDCardView);
Just in case you wondering, If i call the image from Database directly. it workes just fine. But i don't want my client to load all data from database every moment they open the activity.

How to change textviews & imageviews of another activity in Android

I have an activity which can take a few seconds to load its content (mainly pictures) from the cloud. Let's say this content is pictures & description from a person. The user can go to pictures & description from another person by clicking on the next button. I'd like to avoid the loading time When this button is clicked.
To do this I have two activities : firstPersonActivity for the first person content, and secondPersonActivity for the second person content.
What I try to do is to load the content of the secondPersonActivity when the user is in the firstPersonActivity, so that the secondPersonActivity can be displayed "directly" (= without needing to load content from the cloud when the next button is clicked in the firstPersonActivity).
But I do not succeed in doing this, I don't know how to modify the views of the secondPersonActivity layout from the firstPersonActivity class.
I tested the following code in my firstPersonActivity but it doesn't work (there is no connexion to the cloud, it's just a test to better understand how it works). R.id.first_image_second_person is the id of my imageview in the secondPersonLayout (= the layout used in the secondPersonActivity).
ImageView firstImageSecondPerson = (ImageView) findViewById(R.id.first_image_second_person);
firstImageSecondPerson.setImageResource(R.drawable.mypicture);
When I click on the next button to go from the firstPersonActivity to the secondPersonActivity, my firstImageSecondPerson imageview is not filled.
Do you see what's wrong ?
Is there a better way to avoid the loading time when the user click on the next button ?
It is not possible to change activity if activity instance is not created. In my opinion to do what You need I would go to single activity with hidden content of second person ( VIEW.INVISIBLE ) and show/hide it when it is needed.
But if second activity must be there, then create some structure for saving bitmaps in memory. In Your code sample You get picture from drawable so we are not talking about some delays, but if images are downloaded from some server then You can create some class which will have those bitmaps created from url and instance of this class can be used on any activity.
So for example Your class for caching pictures would have some method for creating bitmaps like -How to load an ImageView by URL in Android?. And those bitmaps should be saved in some Array or HashMap to have access to it, for example ( pseudo code ):
//some structure for cashing pictures in app
class PictureCache {
static PictureCache instance;
final HashMap<Integer, Bitmap> bitmaps;
//singleton
static PictureCache getInstance(){
if (instance==null)
instance = new PictureCache();
return instance;
}
public PictureCache(){
bitmaps = new HashMap<>;
}
private Bitmap loadBitmap(String url);//#1
public addPicture(Integer personId, String href){
//add to hashMap
bitmaps.put(personId, loadBitmap(href));
}
public Bitmap getPicture(Integer personId){
return bitmaps.get(personId);
}
}
#1 - method from How to load an ImageView by URL in Android?
Using it in first activity:
PictureCache.getInstance().addPicture(12,"http://url.to.bitmap");
Using it in second activity:
Bitmap pic = PictureCache.getInstance().getPicture(12);
Important note - above code was written here and was not tested, it shows solution concept.
Important second note - using such approach with bitmaps in memory can cause to much memory usage
You cannot access the views of SecondActivity before its creation. If you called this activity once only then you are able to access its views by making them static.
One more Solution for this is..
Access the whole data at once and save it in static arraylist with the help of getter-setters. Then on SecondActivity set data from that arraylist.
Hope this will work.
I don't think you can access the view before creating the activity.
You can try to use Glide for caching your images and minimizing loading time.
Try this
Picasso.with(getContext()).load(R.drawable.generatedId).into(imageView);
or
imageView.setImageDrawable(ActivityCompat.getDrawable(getContext(),
R.drawable.generatedID));`

Android smooth ListView scrolling while loading contact photos

I am using this method to load contacts photo, in my extended CursorAdapter (With LoaderManager):
private Bitmap loadContactPhoto(Uri contactUri) {
ContentResolver cr = getActivity().getContentResolver();
InputStream stream = Contacts.openContactPhotoInputStream(cr, contactUri);
return BitmapFactory.decodeStream(stream);
}
My contacts ListView using QuickContactBadge at each item, and the ListView does not scroll smooth, even if the contacts have no images.
Can I load the images in AsyncTask or make the loading faster?
Use this generally used method to heavily optimize your listviews via recycling:
Youtube
You should tailor the above method to work with the general method, ie only use the code you gave only so many times.
However, if you've already tailored the general optimization method to your needs as is and it's still quite slow, you SHOULD use an AsyncTask. The following link should get you set up- just use a placeholder image until the task is done, then save the image with the view object so you don't have to get the image again when the user re-scrolls through.
Making ListView Scrolling Smooth

Lazy-loading images in ListView on Android

I implemented the lazy-loading images in my ListView.
I use a AsyncTask to download the image from the internet and bind it to the ImageView in the UIThread.
It's working except that when I scroll the ListView vary fast, the downloaded images sometimes are binded into the wrong items in the list.
I guess the problem is from the reuse of convertView in the BaseAdapter.
Any ideas to solve it?
Many thanks.
EDIT:
I post the answer as following:
public void setBitmap(int position, Bitmap image) {
View itemView = mListView.getChildAt(position - mListView.getFirstVisiblePosition());
if (itemView != null) {
ImageView itemImageView = (ImageView) itemView.findViewById(R.id.item_imageview);
itemImageView.setImageBitmap(image);
}
}
There are two problems that will arise during lazy loading of images in a ListView.
The old images are still shown until the new ones are loaded. This is easy just set the ImageView to an image is loading view or set it to invisible before starting the image download.
The second problem is harder to solve. Imagine you are scrolling very fast through your list. Now your views may be recycled before the old AsyncTask has finished loading the image. You now have two tasks running that in the onPostExecute method will set an image to the imageview. Now for a short time the wrong image will be shown until the second Task finishes, or even worse for some network related reason they don't finish in the order they started and you have the wrong image overwrite the correct image. To solve this you have to check what image should be displayed after the task finished. In the View class are two methods for things exact like this one:
setTag and getTag You can bind any object to the imageview that comes into your mind. In most of the cases I use setTag to bind the URL of the image as a String to the imageview before I start a task. Now I can cast getTag to a String after the task finished and compare the URL that should be displayed with the URL that I downloaded and only set the image if necessary.
Create a function called void setBitmap(Bitmap bitmap, int position) or similar in your adapter. Let your AsyncTask call this method when a new bitmap is available. This method may then call notifyDataSetChanged() on the UI-Thread itself to ensure the views get refreshed. Holding references to views in an adapter (even by holding them in an AsyncTask) is dangerous!

Improve ListView efficiency when loading images from SD into the ListView

I am using a custom adapter for my ListView as per the efficient adapter sample by Romain Guy.
In the getView() method of my adapter I am assigning an ImageView a jpg image stored on SD using the following code :
File f=new File(MovieThumbs.get(position));
if(f.length() > 0) {
holder.thumb.setImageBitmap(BitmapFactory.decodeFile(MovieThumbs.get(position)));
}
When flicking through a list of some 200 items using this method the app suffers from bad stuttering as it tries dealing with the images.
Is there a more efficient solution for this?
Rather than loading the images from within the list adapter on demand how about kicking off a thread from the onCreate of your activity to load images? As each image loads you can fire a callback to the activity to display the image in the list. The callback method would be something along the lines of:
void onImageDownloadComplete(int pos, BitMap bm) {
ListView lv = getListView();
View listItem = lv.getChildAt(pos);
ImageView img = (ImageView)listItem.getChildAt(indexOfIcon);
img.setImageBitmap(bm);
}
Images need to be processed in background thread. Recycled views need to be taken into account. I try to address all these issues in my sample code, it works fine now, you may take a look Lazy load of images in ListView

Categories

Resources