Reputation: 85
In my android application, I am loading the images from the API's. but after the images are loaded in the Grid View, the scrolling is not smooth. I am using Asynchronous threads to fetch the images so that it does not block the UI.
Any suggestions now to improve the performance of scrolling.
Upvotes: 3
Views: 4991
Reputation: 434
Instead of taking efforts Use Universal Image loader library.And its performance is good. In onCreate method gridView.setAdapter(new ImageAdapter(this,ImagesArrayPath));
private static class ImageAdapter extends BaseAdapter {
private final String[] IMAGE_URLS ;
private LayoutInflater inflater;
private DisplayImageOptions options;
ImageAdapter(Context context,String source[]) {
inflater = LayoutInflater.from(context);
IMAGE_URLS=source;
options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.mipmap.ico_place_holder)
.showImageForEmptyUri(R.drawable.ic_empty)
.showImageOnFail(R.drawable.ic_error)
.cacheInMemory(true)
.cacheOnDisk(true)
.considerExifParams(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.build();
}
@Override
public int getCount() {
return IMAGE_URLS.length;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
View view = convertView;
if (view == null) {
view = inflater.inflate(R.layout.item_grid_image, parent, false);
holder = new ViewHolder();
assert view != null;
holder.imageView = (ImageView) view.findViewById(R.id.image);
holder.progressBar = (ProgressBar) view.findViewById(R.id.progress);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
ImageLoader.getInstance()
.displayImage(IMAGE_URLS[position], holder.imageView, options, new SimpleImageLoadingListener() {
@Override
public void onLoadingStarted(String imageUri, View view) {
holder.progressBar.setProgress(0);
holder.progressBar.setVisibility(View.VISIBLE);
}
@Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
holder.progressBar.setVisibility(View.GONE);
}
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
holder.progressBar.setVisibility(View.GONE);
}
}, new ImageLoadingProgressListener() {
@Override
public void onProgressUpdate(String imageUri, View view, int current, int total) {
holder.progressBar.setProgress(Math.round(100.0f * current / total));
}
});
return view;
}
}
static class ViewHolder {
ImageView imageView;
ProgressBar progressBar;
}
May this will help you. Enjoy Coding.
Upvotes: 0
Reputation: 85
Code for getView() method {{{
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final HashMap<String, String> song = songsList.get(position);
imageURL = song.get(VariablesList.TAG_ALBUM_IMAGE);
View v = null;
if (convertView != null)
v = convertView;
else
v = inflater.inflate(R.layout.gridlayout_item, parent, false);
final ImageView imageView = (ImageView) v.findViewById(R.id.icon_image);
final Thread startAlbum = new Thread() {
public void run() {
imageView.setImageBitmap(AlbumList
.LoadImagetoGridView(imageURL));
synchronized (this) {
this.notifyAll();
}
}
};
synchronized (startAlbum) {
startAlbum.start();
try {
startAlbum.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
imageView.setOnClickListener(new View.OnClickListener() {
// @Override
public void onClick(View v) {
albumUrl = new StringBuffer(resources.getString(R.string.songsListURL));
String albumIndex = song.get("id");
albumName = (song.get("name"));
imageURL = song.get(VariablesList.TAG_ALBUM_IMAGE);
SongsList albumList = new SongsList(imageURL, albumUrl,
albumName,albumIndex,resources);
Thread threadAlbumList = new Thread(albumList);
threadAlbumList.start();
synchronized (albumList) {
try {
albumList.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (!NewMediaPlayer.mediaPlayer.isPlaying()) {
HashMap<String, String> playingSong = NewMediaPlayer.selectedSongs
.get(0);
if (playingSong != null) {
String url = playingSong.get("songUrl");
String songName = playingSong.get("songName");
if (songName != null)
{
NewMediaPlayer.songTitleLabel.setText(albumName
+ " - " + songName);
NewMediaPlayer.songTitle.setText(albumName+"-"+songName);
}
NewMediaPlayer.playSong(url);
}
}
}
});
TextView itemAlbumName = (TextView) v.findViewById(R.id.icon_text);
itemAlbumName.setText(song.get("name"));
itemAlbumName.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
HashMap<String, String> song = songsList.get(position);
String songIndex = song.get("id");
String albumName = (song.get("name"));
Intent in = new Intent(context, SongListActivity.class);
in.putExtra("albumIndex", songIndex);
in.putExtra("albumName", albumName);
in.putExtra("AlbumImage", song.get(VariablesList.TAG_ALBUM_IMAGE));
context.startActivity(in);
}
});
return v;
}
}}}
Upvotes: 0
Reputation: 13705
Loading images in separate thread definitely helps, however there's another important performance issue to take care of here, and that's "view reusability", once you've set the image in your Adapter, make sure that you are actually reusing the views provided in the getView method of the adapter, and not creating/inflating a new Layout(GridElement) every time that method is called, this is usually what causes the scrolling to go slow once all the images have been loaded, there's several patterns available to approach this issue, you should read about ViewHolder, is the most common and easy to use pattern for this issue...
Hope this Helps...
Regards
Upvotes: 2