Adapter behaviour when loading image from URL ion library - java

I m facing a problem when I want to load images from an adapter using the ion library.
In fact, I have items with a string corresponding to the url of the iconic image that I want to load for each item on my gridview.
The problem is due to the adapter view management (reusing existing view if I m not wrong), and I dont know how to bypass this...
For example, if I load 10 elements with an image, the first time it works. Then, when I scroll to bottom, and then I scroll to top, the image changes (due to the reuse of the existing view...)
Can you help me ?
This is my adapter code :
public class ProtocoleAdapter extends BaseAdapter {
private Context context;
private List<ProtocoleItem> mListe;
public ProtocoleAdapter(Context context, List<ProtocoleItem> liste) {
this.context = context;
this.mListe = liste;
}
private class ViewHolder {
TextView txtTitre;
ImageView img;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = mInflater
.inflate(R.layout.grid_item, null);
holder = new ViewHolder();
holder.txtTitre = (TextView) convertView
.findViewById(R.id.grid_item_label);
holder.img = (ImageView) convertView
.findViewById(R.id.grid_item_image);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final ProtocoleItem rowItem = mListe.get(position);
boolean isLoaded = false;
try {
Bitmap bitmap = Ion.with(context)
.load(rowItem.getImage())
.asBitmap()
.get();
isLoaded = true;
holder.img.setImageBitmap(bitmap);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
if (!isLoaded) {
if (position % 5 == 0) {
holder.img.setBackgroundColor(0xff176799);
} else {
if (position % 4 == 0) {
holder.img.setBackgroundColor(0xff2F87B0);
} else {
if (position % 3 == 0) {
holder.img.setBackgroundColor(0xff42A4BB);
} else {
if (position % 2 == 0) {
holder.img.setBackgroundColor(0xff5BC0C4);
} else {
holder.img.setBackgroundColor(0xff78D6C7);
}
}
}
}
}
holder.txtTitre.setText(rowItem.getTitre());
return convertView;
}
Thanks for all !
Have a good day

Get the latest version of Ion and use the following.
Ion.with(holder.img)
.load(rowItem.getImage());
This method will load asynchronously.
Your current usage is blocking the UI thread. Ion should properly handle convertView recycling, so that is not an issue.

This is lazy loading problem, go with Universal image loader: https://github.com/nostra13/Android-Universal-Image-Loader
https://github.com/nostra13/Android-Universal-Image-Loader/blob/master/sample/src/com/nostra13/example/universalimageloader/ImagePagerActivity.java

Related

Duplicates the Image in ListView when downloading

When the image has been downloaded, some of the images duplicates in the listview rows, even though some of the row has no ImageID, The adapter view duplicates the downloaded images, when i suddenly scroll the listview
My code in getView
public View getView(final int position, View convertView, ViewGroup parent) {
int anotherPosition = position;
if (inflater == null) {
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
final Holder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_item, null);
holder = new Holder();
holder.title = (TextView) convertView.findViewById(R.id.description);
holder.exp = (TextView) convertView.findViewById(R.id.expiration);
holder.someImages = (ImageView) convertView.findViewById(R.id.listview_image);
holder.isFavouriteImage = (ImageView) convertView.findViewById(R.id.isFavourite);
convertView.setTag(holder);
convertView.setTag(R.id.listview_image, holder.someImages);
convertView.setTag(R.id.description, holder.title);
convertView.setTag(R.id.expiration, holder.exp);
convertView.setTag(R.id.isFavourite, holder.isFavouriteImage);
} else {
holder = (Holder) convertView.getTag();
}
RowItemLoyalty rowItemLoyalty = data.get(position);
if(rowItemLoyalty != null) {
holder.someImages.setTag(position);
holder.someImages.setImageBitmap(null);
holder.title.setText(data.get(position).getDescription());
holder.exp.setText(data.get(position).getDateEnd());
Log.d("TrueOrFalse", String.valueOf(holder.someImages));
if(holder.someImages != null ) {
if (data.get(position).getImageId() != 0) {
data.get(position).setBitmap(email, password, data.get(position).getImageId(), data.get(position).getBitmap(), new RowItemLoyalty.RetrieveBitmapListener() {
#Override
public void onSuccess(Bitmap bitmap) {
Log.d("ImageID123", String.valueOf(data.get(position).getImageId()));
holder.someImages.setImageBitmap(null);
if (data.get(position).getBitmap() != null) {
Log.d("True", "True");
holder.someImages.setImageBitmap(bitmap);
}
}
});
}
} else if(holder.someImages == null ) {
Drawable placeholder = ContextCompat.getDrawable(context, R.drawable.placeholderwhite);
holder.someImages.setImageDrawable(placeholder);
Log.d("PlaceHolder2", String.valueOf(placeholder));
}
//----------- placeholder for imageview list -----------
//holder.someImages.setImageBitmap(null);
if (data.get(position).getBitmap() != null && holder.someImages != null) {
holder.someImages.setImageBitmap(data.get(position).getBitmap());
Log.d("PlaceHolder", "Implemented");
Log.d("PlaceHolder", String.valueOf(data.get(position)));
} else if (data.get(position).getBitmap() == null) {
Drawable placeholder = ContextCompat.getDrawable(context, R.drawable.placeholderwhite);
holder.someImages.setImageDrawable(placeholder);
Log.d("PlaceHolder2", String.valueOf(placeholder));
}
//------------ for favourite logo-------------
if (data.get(position).getIsFavorite() == false) {
Drawable placeholderIsNotFavourite = ContextCompat.getDrawable(context, R.drawable.ic_favourite_icon);
holder.isFavouriteImage.setImageDrawable(placeholderIsNotFavourite);
} else if (data.get(position).getIsFavorite() == true) {
Drawable favourited = ContextCompat.getDrawable(context, R.drawable.favourite_two);
holder.isFavouriteImage.setImageDrawable(favourited);
}
}
return convertView;
}
My Holder class
public static class Holder {
TextView title;
TextView exp;
TextView tokensFor;
ImageView promotionImages;
ImageView isFavouriteImage;
}
There are some useful libraries you can use to loading images like Glide
Also you can see this Picasso v/s Imageloader v/s Fresco vs Glide
Try using Universal Image Loader Universal Image Loader
to set image on ImageView
Remove checking convertView == null condition, like this:
convertView = inflater.inflate(R.layout.list_item, null);
holder = new Holder();
holder.title = (TextView) convertView.findViewById(R.id.description);
holder.exp = (TextView) convertView.findViewById(R.id.expiration);
holder.someImages = (ImageView) convertView.findViewById(R.id.listview_image);
holder.isFavouriteImage = (ImageView) convertView.findViewById(R.id.isFavourite);

GridView: The application may be doing too much work on its main thread.Skipped x frames error when using various images

Hey in this program I have set a GridView according to the text it has but when running the app the app lags alot on the emulator as well as on the device. And the error
"The application may be doing too much work on its main thread." is given
I guess thats what causing the problem here.
Here is my ImageAdapter file
public class ImageAdapter extends BaseAdapter {
static class ViewHolder {
ImageView imageView;
TextView textView;
}
private Context context;
String mobile;
private final String[] mobileValues;
int[] imagesArr = new int[]{R.drawable.badminton, R.drawable.cricket, R.drawable.basketball, R.drawable.carrom,
R.drawable.handball, R.drawable.humanfoosball, R.drawable.kabaddi, R.drawable.khokho, R.drawable.chess,
R.drawable.longjump, R.drawable.streetsoccer, R.drawable.shotput, R.drawable.volleyball, R.drawable.tugofwar,
R.drawable.tabletennis, R.drawable.handball, R.drawable.rellayrace};
public ImageAdapter(Context context, String[] mobileValues) {
this.context = context;
this.mobileValues = mobileValues;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
View row = convertView;
if (row == null) {
holder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//row = new View(context);
// get layout from grid_itemxml.xml
row = inflater.inflate(R.layout.grid_item, null);
// set value into textview
holder.textView = (TextView) row.findViewById(R.id.grid_item_label);
holder.textView.setText(mobileValues[position]);
// set image based on selected text
holder.imageView = (ImageView) row.findViewById(R.id.grid_item_image);
mobile = mobileValues[position];
if (mobile.equals("Badminton")) {
holder.imageView.setImageResource(imagesArr[0]);
}
if (mobile.equals("Cricket")) {
holder.imageView.setImageResource(imagesArr[1]);
}
if (mobile.equals("Basketball")) {
holder.imageView.setImageResource(imagesArr[2]);
}
if (mobile.equals("Carrom")) {
holder.imageView.setImageResource(imagesArr[3]);
}
if (mobile.equals("Handball")) {
holder.imageView.setImageResource(imagesArr[4]);
}
if (mobile.equals("Human Foosball")) {
holder.imageView.setImageResource(imagesArr[5]);
}
if (mobile.equals("Kabaddi")) {
holder.imageView.setImageResource(imagesArr[6]);
}
if (mobile.equals("Khokho")) {
holder.imageView.setImageResource(imagesArr[7]);
}
if (mobile.equals("Chess")) {
holder.imageView.setImageResource(imagesArr[8]);
}
if (mobile.equals("Longjump")) {
holder.imageView.setImageResource(imagesArr[9]);
}
if (mobile.equals("Streetsoccer")) {
holder.imageView.setImageResource(imagesArr[10]);
}
if (mobile.equals("Shotput")) {
holder.imageView.setImageResource(imagesArr[11]);
}
if (mobile.equals("Volleyball")) {
holder.imageView.setImageResource(imagesArr[12]);
}
if (mobile.equals("Tugofwar")) {
holder.imageView.setImageResource(imagesArr[13]);
}
if (mobile.equals("Table Tennis")) {
holder.imageView.setImageResource(imagesArr[14]);
}
if (mobile.equals("Relayrace")) {
holder.imageView.setImageResource(imagesArr[15]);
}
} else {
holder = (ViewHolder) row.getTag();
}
return row;
}
#Override
public int getCount() {
return mobileValues.length;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
The images inside your project are taking too much time to load the images, though the android memory resources are limited to app.There are couple of solution that you can try
Keep image size low (downside will be bad quality on bigger screens).
Compress image to required screen resolution size at run time.
The easy way is use image loading libraries. Try this link for details
e.g
Picasso.with(context).load(R.drawable.drawableName).fit().centerCrop().into(imageViewFit)

Loading images in a gridView from server android

I am trying to show a lot of images from my server. There is no conventional link since i am using AMazon s3 services. Here is my code to download the images. Since i need to reduce image size, is this better way of achiving smooth scroll or do i need to do something else
public class PinsListAdapter extends BaseAdapter
{
private Activity mContext;
private ArrayList<PingModel> pings = new ArrayList<PingModel>();
private LayoutInflater inflater;
public PinsListAdapter(Activity context, ArrayList<PingModel> pings)
{
super();
this.mContext = context;
this.pings = pings;
inflater = (LayoutInflater) this.mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount()
{
return pings.size();
}
#Override
public Object getItem(int arg0)
{
return null;
}
#Override
public long getItemId(int arg0)
{
return 0;
}
private static class ViewHolder
{
public ImageView vidImgIndicator;
public ImageView pinImg;
public ImageView progress;
}
#Override
public View getView(int position, View convertView, final ViewGroup parent)
{
final PingModel ping = pings.get(position);
ViewHolder holder = null;
if (convertView == null)
{
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.adapter_pin_row, parent, false);
holder.pinImg = (ImageView) convertView.findViewById(R.id.pinImg);
holder.progress = (ImageView) convertView.findViewById(R.id.progress);
holder.vidImgIndicator = (ImageView) convertView.findViewById(R.id.vidImgIndicator);
Animation anim = AnimationUtils.loadAnimation(mContext, R.anim.rotating_img);
holder.progress.setAnimation(anim);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
final ViewHolder mainHolder = holder;
holder.vidImgIndicator.setVisibility(View.GONE);
final String url = ping.getLocalMediaUrl(mContext);
if (url != null) /* Image is already placed */
{
if (ping.mediaAttachmentType == PingModel.PING_MEDIA_ATTACHMENT_TYPE_PHOTO)
{
if(ping.thumbnail == null)
{
ping.thumbnail = ImageUtils.getBitmapFromFile(url, 80);
}
}
else if (ping.mediaAttachmentType == PingModel.PING_MEDIA_ATTACHMENT_TYPE_VIDEO)
{
if(ping.thumbnail == null)
{
//ping.thumbnail = ThumbnailUtils.createVideoThumbnail(url, MediaStore.Images.Thumbnails.MINI_KIND );
}
if (ping.thumbnail != null)
mainHolder.vidImgIndicator.setVisibility(View.VISIBLE);
}
mainHolder.pinImg.setImageBitmap(ping.thumbnail);
}
else
{
holder.pinImg.setImageDrawable(null);
if (ping.isMediaBeingDownloaded == false)
{
AppManager.getInstance().executor.execute(new Runnable()
{
public void run()
{
ping.isMediaBeingDownloaded = true;
ApiManager.getInstance().pingManager.downloadMediaOfPingFromServer(ping);
ping.isMediaBeingDownloaded = false;
if (ping.mediaAttachmentType == PingModel.PING_MEDIA_ATTACHMENT_TYPE_PHOTO)
{
ping.thumbnail = ImageUtils.getBitmapFromFile(url, 80);
}
else if (ping.mediaAttachmentType == PingModel.PING_MEDIA_ATTACHMENT_TYPE_VIDEO)
{
ping.thumbnail = ThumbnailUtils.createVideoThumbnail(url, MediaStore.Images.Thumbnails.MINI_KIND);
}
mContext.runOnUiThread(new Runnable()
{
#Override
public void run()
{
notifyDataSetChanged();
}
});
}
});
}
}
return convertView;
}
}
Please note the executers. Is this correct and logical way of doing it or am i doing it totally wrong and i need to make any other cache type thing?
image downloading, caching, storing in a scrolling list is a very very complex situation that I advise nobody to do themselves.
Instead you should do what most apps do, use a 3rd party library specialised for the job I'll point you to 3 of the current "best" ones, pick which ever you prefer.
Picasso - https://github.com/square/picasso
Glide - https://github.com/bumptech/glide
Fresco - https://github.com/facebook/fresco
You must always load images on a background thread even the thumbnails, unless they are already in memory.
You can use Picasso and implement your own RequestHandler which downloads the image from S3, it will give you more performance and flexibility.

Something really wrong with adapter

I've got next adapter:
public class CityAdapter extends ArrayAdapter<String> {
public CityAdapter(Context context, int resource) {
super(context, resource, Cities.TITLES);
}
public int getCount() {
return Cities.ARRAY.length;
}
#SuppressLint("InflateParams")
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.city_list_row, null);
}
TextView title = (TextView) v.findViewById(R.id.cityTitle);
title.setText(Cities.ARRAY[position].getName());
if (position==4) {
title.setTextColor(Color.parseColor("#ff0000"));
}
return v;
}
}
Please take a closer look at this line:
if (position==4)
I don't know how, but that statement works for position 0 too.
Seems really impossible. What is wrong? Also if I change my code like this:
if (position==4) {
title.setText("hey!!!");
title.setTextColor(Color.parseColor("#ff0000"));
}
I will get this:
Add an else case for your color settings like this
if (position==4) {
title.setTextColor(Color.parseColor("#ff0000"));
}
else {
title.setTextColor(Color.parseColor("#ffffff"));
}
You are not implementing the else part.
ViewHolder holder;
if (v == null) {
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.city_list_row, null);
holder.title = (TextView) v.findViewById(R.id.cityTitle);
v.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
And then you need to create a class
class ViewHolder {
TextView title;
}
Also you need else part of this.
if (position==4) {
title.setText("hey!!!");
title.setTextColor(Color.parseColor("#ff0000"));
}else{
title.setText("heyfffgg!!!");
title.setTextColor(Color.parseColor("#ff0000"));
}

Text Views in Grid Views disapearing on grid view scroll

I am having issues with androids grid view. When I scroll, some text views disappear. I have a conditional statement that checks a value in the database and hides the text views based on that. But that conditional statement is only meant to be for the views in the grid that meet the criteria. However, when scrolling all views seem to change.
Here is my custom array adapter (I have also attached an image to show what I mean):
![public class ArrayAdapterHandler extends ArrayAdapter<Day> {
public Context context;
int layoutResourceId;
ArrayList<Day> days = new ArrayList<Day>();
public ArrayAdapterHandler(Context context, int dayId,
ArrayList<Day> days) {
super(context, dayId, days);
this.layoutResourceId = dayId;
this.context = context;
this.days = days;
}
/*private view holder class*/
private class ViewHolder {
TextView day_text;
TextView situps_text;
TextView crunches_text;
TextView legRaises_text;
TextView plank_text;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
Day day = days.get(position);
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.day_row, null);
if (position % 2 == 0) {
convertView.setBackgroundColor(0x30BFFF1E);
} else {
convertView.setBackgroundColor(0x30CCCCCC);
}
holder = new ViewHolder();
holder.day_text = (TextView) convertView.findViewById(R.id.day_text);
holder.situps_text = (TextView) convertView.findViewById(R.id.situps_text);
holder.crunches_text = (TextView) convertView.findViewById(R.id.crunches_text);
holder.legRaises_text = (TextView) convertView.findViewById(R.id.legRaise_text);
holder.plank_text = (TextView) convertView.findViewById(R.id.plank_text);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.day_text.setText(String.valueOf(day.getDay()));
if (day.isCompleted() == 1 || day.isRestDay() == 1) {
// Hide all the activity values which are 0 anyway.
holder.situps_text.setVisibility(4);
holder.legRaises_text.setVisibility(4);
holder.plank_text.setVisibility(4);
}
if (day.isRestDay() == 1) {
holder.crunches_text.setText("REST DAY");
} else if(day.isCompleted() == 1) {
holder.crunches_text.setText("COMPLETED!");
} else {
holder.situps_text.setText(String.valueOf(day.getSitups()) + " situps");
holder.crunches_text.setText(String.valueOf(day.getCrunches()) + " crunches");
holder.legRaises_text.setText(String.valueOf(day.getLegRaises()) + " leg raises");
holder.plank_text.setText(String.valueOf(day.getPlanks()) + "sec planks");
}
return convertView;
}
}
![Scrolling issue image]: http://i.stack.imgur.com/zB3uL.png
Thankyou.

Categories