Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lazy Loading not working properly

I am showing a list of contacts in a recyclerview. I am showing contact profile images, first I am loading these images from server and then storing these images in an external memory.

Then Loading the images from external storage. I can see the images loaded, but as I scroll I can see some images for a second or two then they get disappear and I can see the default image icon.

public class ContactAdapter extends RecyclerView.Adapter<ContactAdapter.ContactHolder> {


    private List<Contact> contactList;
    File myDir1;
    private Activity mContext;

    private Boolean fileExists;
    private File file;
    private static final int MY_PERMISSIONS_REQUEST_CALL= 20;

    public ContactAdapter(Activity context, List<Contact> contactList) {
        this.contactList = contactList;
        this.mContext = context;
    }

    @Override
    public ContactHolder onCreateViewHolder(ViewGroup viewGroup, int i) {

        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_layout,null);
        ContactHolder mh = new ContactHolder(v);

        return mh;
    }

    @Override
    public void onBindViewHolder(final ContactHolder contactHolder, int i) {

        final Contact contact = contactList.get(i);
        //  Log.e("Imagename",""+"http://xesoftwares.co.in/contactsapi/profile_images/85368a5bbd6cffba8a3aa202a80563a2.jpg");//+feedItem.getThumbnail());

        Target target = new Target() {

            @Override
            public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {

                // your code here ...

                bitmap = Bitmap.createScaledBitmap(bitmap,(int)(bitmap.getWidth()*0.8), (int)(bitmap.getHeight()*0.8), true);

                contactHolder.thumbnail.setImageBitmap(bitmap);

                Log.e("ProfileImage", contact.getmProfileImage());

                SaveImages(bitmap, contact.getmProfileImage());

            }

            @Override
            public void onBitmapFailed(Drawable errorDrawable) {
                contactHolder.thumbnail.setImageDrawable(errorDrawable);
                // do error handling as required
            }

            @Override
            public void onPrepareLoad(Drawable placeHolderDrawable) {
                contactHolder.thumbnail.setImageDrawable(placeHolderDrawable);
            }
        };

        contactHolder.thumbnail.setTag(target);

        String url = ServiceUrl.getBaseUrl() + ServiceUrl.getImageUserUrl() + contact.getmProfileImage();

        Log.e("url",url);

        if(contact.getmProfileImage().equals(""))

        {

            file = new File("");

            fileExists = file.exists();

            contactHolder.thumbnail.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.ic_account_circle_black_48dp));
        }
        else {

            file = new File(Environment.getExternalStorageDirectory() + "/ContactProfileImages/" + contact.getmProfileImage());

            fileExists = file.exists();
        }

        if(fileExists)
        {

            Log.e("fileExists",file.getAbsolutePath());

            BitmapFactory.Options bmOptions = new BitmapFactory.Options();
            Bitmap bitmap = BitmapFactory.decodeFile(file.getPath(), bmOptions);

            contactHolder.thumbnail.setImageBitmap(bitmap);

        }

        else {

            Log.e("Picasso",file.getAbsolutePath());

            Picasso.with(mContext).load(url)
                    .error(R.drawable.ic_account_circle_black_24dp)
                    .placeholder(R.drawable.ic_account_circle_black_24dp)
                    .into(target);
        }

        contactHolder.title.setText(contact.getmUserName());
        //feedListRowHolder.genre.setText(Html.fromHtml(feedItem.getGenre()));

    }

    @Override
    public int getItemCount() {
        return (null != contactList ? contactList.size() : 0);
    }

    public void SaveImages(Bitmap bitmap,String profileName)
    {

        try {
            String root = Environment.getExternalStorageDirectory().getPath();
            File myDir = new File(root +"/ContactProfileImages");

            if (!myDir.exists()) {
                myDir.mkdirs();
            }

            // String name = new Date().toString();=
            String name = profileName;
            File myDir1 = new File(myDir, name);
            if(!myDir1.exists()) {
                FileOutputStream out = new FileOutputStream(myDir1);
                bitmap.compress(Bitmap.CompressFormat.PNG,100,out);

                out.flush();
                out.close();
            }


        } catch(Exception e){
            // some action
        }

        //myDir1= imageFilePath1.getprofile();

    }


    public class ContactHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        protected CircleImageView thumbnail;
        protected TextView title;

        public ContactHolder(View view) {
            super(view);
            this.thumbnail = (CircleImageView) view.findViewById(R.id.thumbnail);
            this.title = (TextView) view.findViewById(R.id.title);
            view.setOnClickListener(this);

        }

        @Override
        public void onClick(View v) {

            final Contact contact = contactList.get(getAdapterPosition());

            final Dialog dialog = new Dialog(mContext);
            dialog.setCanceledOnTouchOutside(true);
            dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
            dialog.setContentView(R.layout.custom);
            final Window window = dialog.getWindow();

            WindowManager.LayoutParams wlp =window.getAttributes();
            wlp.gravity = Gravity.CENTER_HORIZONTAL|Gravity.TOP;
            wlp.y=320;
            window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            window.setAttributes(wlp);

            // set the custom dialog components - text, image and button
            TextView txtusername = (TextView) dialog.findViewById(R.id.txtusername);
            TextView txtmobile = (TextView) dialog.findViewById(R.id.txtmobile);
            TextView txtemail = (TextView) dialog.findViewById(R.id.txtemail);

            txtusername.setText(contact.getmUserName());
            txtemail.setText(contact.getmEmailId());
            txtmobile.setText(contact.getmMobileNo());

            SquareImageView image = (SquareImageView) dialog.findViewById(R.id.image);
            ImageView image1 = (ImageView) dialog.findViewById(R.id.image1);
            ImageView image2 = (ImageView) dialog.findViewById(R.id.image2);
            ImageView image3 = (ImageView) dialog.findViewById(R.id.image3);

            if(contact.getmProfileImage().equals(""))

            {
                image.setImageDrawable(ContextCompat.getDrawable(mContext,R.drawable.profile_icon));
            }
            else {
                File file = new File(Environment.getExternalStorageDirectory() + "/ContactProfileImages/" + contact.getmProfileImage());
                BitmapFactory.Options bmOptions = new BitmapFactory.Options();
                Bitmap bitmap = BitmapFactory.decodeFile(file.getPath(), bmOptions);

                image.setImageBitmap(bitmap);
            }

            image1.setImageResource(R.drawable.ic_call_black_24dp);
            image2.setImageResource(R.drawable.ic_textsms_black_24dp);
            image3.setImageResource(R.drawable.ic_email_black_24dp);

            image2.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {

                    Uri sms_uri = Uri.parse("smsto:" + contact.getmMobileNo());
                    Intent sms_intent = new Intent(Intent.ACTION_SENDTO, sms_uri);
                    mContext.startActivity(sms_intent);
                    dialog.dismiss();

                }
            });

            image1.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {

                        Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + contact.getmMobileNo()));
                        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
                        mContext.startActivity(intent);
                        dialog.dismiss();
                }
            });

            image3.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Intent email = new Intent(Intent.ACTION_SEND);
                    email.putExtra(Intent.EXTRA_EMAIL, new String[]{contact.getmEmailId()});
                    email.setType("message/rfc822");
                    mContext.startActivity(Intent.createChooser(email, "Choose an Email client :"));

                }
            });

            Button dialogButton = (Button) dialog.findViewById(R.id.dialogButtonOK);
            // if button is clicked, view all information custom dialog

            dialogButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {

                    ((MainActivity)mContext).finish();

                    Intent intent = new Intent(mContext,DetailViewActivity.class);
                    intent.putExtra("contact",contact);
                    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
                    intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
                    mContext.startActivity(intent);

                    dialog.dismiss();


                }
            });
            dialog.show();

        }
    }
 }

EDIT : I searched for the same issue with picasso library, when we load images from server, for this I got the solution from SO as :

   recyclerView.setHasFixedSize(true);
    recyclerView.setItemViewCacheSize(20);
    recyclerView.setDrawingCacheEnabled(true);
    recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);

And this worked when I am loading the images from server, but when I am loading the images from the external storage still the problem exists.

Can anyone help with this please? Thank you..

like image 342
Sid Avatar asked Nov 14 '16 08:11

Sid


2 Answers

Then Loading the images from external storage. I can see the images loaded, but as I scroll I can see some images for a second or two then they get disappear and I can see the default image icon.

This is becuase you are using Target callback in picasso. And callbacks are called little bit late when you are scrolling the list. Just remove the target and use the imageview into Picasso, it should work fine. Also you don't need to cache bitmaps on your own as Picasso does it for you.

public void onBindViewHolder(final ContactHolder contactHolder, int i) {
    final Contact contact = contactList.get(i);
    //  Log.e("Imagename",""+"http://xesoftwares.co.in/contactsapi/profile_images/85368a5bbd6cffba8a3aa202a80563a2.jpg");//+feedItem.getThumbnail());

    String url = ServiceUrl.getBaseUrl() + ServiceUrl.getImageUserUrl() + contact.getmProfileImage();
    Log.e("url",url);

    if(contact.getmProfileImage().equals("")) {
        file = new File("");
        fileExists = file.exists();
        contactHolder.thumbnail.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.ic_account_circle_black_48dp));
    } else {
        file = new File(Environment.getExternalStorageDirectory() + "/ContactProfileImages/" + contact.getmProfileImage());
        fileExists = file.exists();
    }

    Log.e("Picasso",file.getAbsolutePath());

    Picasso.with(mContext).load(url)
        .error(R.drawable.ic_account_circle_black_24dp)
        .placeholder(R.drawable.ic_account_circle_black_24dp)
        .into(contactHolder.thumbnail);

    contactHolder.title.setText(contact.getmUserName());
    //feedListRowHolder.genre.setText(Html.fromHtml(feedItem.getGenre()));
}
like image 168
Sam Avatar answered Oct 05 '22 07:10

Sam


use this code in your Application class to apply setting in whole app.

final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
// Use 1/8th of the available memory for this memory cache.
final int cacheSize = maxMemory / 8;
Picasso.Builder builder = new Picasso.Builder(getApplicationContext());
builder.memoryCache(new LruCache(cacheSize));
Picasso built = builder.build();
built.setIndicatorsEnabled(true);// it will show indicator where it downloaded from
built.setLoggingEnabled(false);
Picasso.setSingletonInstance(built);

now pass the url to Picasso to load it to view .If you are dealing with large image you can resize image size also for faster loading.

Picasso
    .with(mContext)
    .load(url)
    .error(R.drawable.on_error)
    .placeholder(R.drawable.place_holder)
    //.resize(custom_width,custom_height)  put custom_height to 0 if you want to maintain aspect ratio
    .into(your_view);
like image 33
Nandan Kumar Singh Avatar answered Oct 05 '22 06:10

Nandan Kumar Singh