延迟加载无法正常工作

延迟加载无法正常工作

问题描述:

我在回收站中显示联系人列表。我正在显示联系人配置文件图像,首先我从服务器加载这些图像,然后将这些图像存储在外部存储器中。延迟加载无法正常工作

然后从外部存储装载图像。我可以看到加载的图像,但当我滚动时,我可以看到一些图像一两秒钟,然后消失,我可以看到默认图像图标。

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(); 

     } 
    } 
} 

编辑:我搜索了与毕加索库同样的问题,当我们从服务器加载图像,为了这个,我得到了解决,从这样:

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

这时候我加载工作来自服务器的图像,但是当我从外部存储装载图像时仍存在问题。

任何人都可以帮忙吗?谢谢。

+0

这也许无关,但看看这个[git的链接](https://github.com/codepath/android_guides/wiki/Endless-Scrolling-with-AdapterViews-and-RecyclerView#implementing-with- recyclerview),而不是'.post'使用'.postDelayed' –

+0

在哪里使用.postDelayed? @ Mr.Z – Sid

+0

@Sid:查看http://androidexample.com/Download_Images_From_Web_And_Lazy_Load_In_ListView_-_Android_Example/index.php?view=article_discription&aid=112 – avinash

然后从外部存储装载图像。我可以看到加载的图像 ,但当我滚动时,我可以看到一些图像一秒或两秒,然后 它们消失,我可以看到默认图像图标。

这是因为您在毕加索使用Target回调。当你滚动列表时,回调被称为迟了一点。只要删除目标,并使用imageview到毕加索,它应该工作得很好。你也不需要像毕加索为你自己缓存位图一样。

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())); 
} 
+0

,但我需要获取存储的图像的位置以显示另一个活动中的图像,并且我发现我们无法获取由picasso存储的缓存图像的路径,所以我按照这种方式将图像保存在外部存储器中并使用它。 – Sid

+1

你不需要位置在另一个活动中显示相同的图像,你只需要图像url。毕加索以图片网址为关键词存储图片。所以当你需要一些其他活动或片段中的图像时,如果它已经存储,它可以从缓存中恢复 – Sam

我可就错了,但你的问题可能是由您使用Contact您通过布局位置从数据集中得到的,但因为你在onBitmapLoaded回调asynchroniously使用引起的,该位置可能已经在那个时刻改变了。因此,所有你需要的是使用适配器位置如下:

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

    // your code here ... 

    Contact c = contactList.get(contactHolder.getAdapterPosition()); 

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

    contactHolder.thumbnail.setImageBitmap(bitmap); 

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

    SaveImages(bitmap, c.getmProfileImage()); 
} 

我不知道,这将是有帮助的,但是我们可以尝试,我希望这将是:)

+0

尝试过,但问题仍然没有.. :-(@ rom4ek – Sid

如果您想要简单地加载图像,然后为什么你需要存储在外部storage.if你必须存储为任何其他目的然后存储它,但是当你在ImageView中显示它,然后请使用任何第三方API如PicassoUniversal Image Loader它懒惰加载和它所有类型的缓存内存管理也提供了许多显示的方式。

希望这将帮助你像加载图像

+0

我将图像保存在文件夹中,因为如果用户离线,他仍然应该看到列表,所以我想在用户离线时从文件夹加载图像。 – Sid

+0

但我需要获取存储图像的位置以在另一个活动中显示图像,并且我发现我们无法获取由picasso存储的缓存图像的路径,所以我按照此方式将图像保存在外部存储中并使用它。@sanat chandravanshi – Sid

的操作应该在后台线程使用AsyncTask进行。

+0

你能指导我使用代码从异地任务中加载外部存储器中的图像吗? – Sid

在您的应用程序类中使用此代码来应用整个应用程序中的设置。

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); 

现在的URL传递给毕加索加载它来查看。如果你正在处理大的图像还可以调整图像大小更快的加载。

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); 
+0

我想从外部存储器加载图像,我可以使用picasso加载吗?@NANDAN KUMAR SINGH – Sid

+0

是的! ,你可以通过传递图像的uri来从外部存储器加载。 –

+0

你可以给我看一个例子吗?@NANDAN KUMAR SINGH – Sid

  • 检查每一个图像是多么MB例如:如果 图像为1mb或500kb,则需要更多时间才能下载 背景中的图像,下载后将存储在catche中。这意味着第一次只需要一段时间下载图像。

  • 第二次来自catche的图像。它将以秒为单位显示所有的 图像。

  • 使用排球 - 用于更快和滑翔 - 用于内存管理。

    Glide 
        .with(context) 
        .load(rowItem.getPosteduserpostimage()) 
        .asBitmap() 
        .diskCacheStrategy(DiskCacheStrategy.SOURCE) 
        .fitCenter() 
        .placeholder(R.drawable.load_image) 
        .error(R.drawable.cancel_image) 
        .into(holder.ivPostedImageNew); 
    
  • 参考 here 如何装载大尺寸bitmap.You需要缩小图像。

  • 否则,当我上传每个图像时,我使用 库进行裁剪。它会照顾缩小大位图。 例如: 5mb 图像将缩小到180 kb。

  • 入住这CropImage lib 缩减尺寸较大images.Even如果用户不裁剪图像,只 裁剪时选择整个部分,将5 MB缩小到 180kb.Image质量也不错。

我想如果没有作物也可以使用下面的代码,以缩小image.You可以看到这个代码在:

private void startCropImage() { 

    Intent intent = new Intent(this, CropImage.class); 

    intent.putExtra(CropImage.IMAGE_PATH, mFileTemp.getPath()); 
    intent.putExtra(CropImage.SCALE, true); 
    intent.putExtra(CropImage.ASPECT_X, 0); //3 for aspect ratio 
    intent.putExtra(CropImage.ASPECT_Y, 0); //2 for aspect ratio 

    startActivityForResult(intent, REQUEST_CODE_CROP_IMAGE); 
} 
  • 而且也不里面使用嵌套的滚动视图recyclerview。