2016-11-14 3 views
11

recyclerview에 연락처 목록을 표시하고 있습니다. 연락처 프로필 이미지를 보여주고 있는데, 먼저 서버에서이 이미지를로드하고이 이미지를 외부 메모리에 저장하고 있습니다.게으른로드가 제대로 작동하지 않습니다.

그런 다음 외부 저장소에서 이미지를로드하십시오. 로드 된 이미지를 볼 수는 있지만 스크롤 할 때 두 번째 또는 두 번째 이미지가 표시 될 수 있습니다. 그러면 이미지가 사라지고 기본 이미지 아이콘을 볼 수 있습니다.

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

그리고로드하고 때이 일을 : 나는 우리가 이것을 위해 내가 SO로에서 솔루션을 가지고, 서버에서 이미지를로드 피카소 라이브러리와 같은 문제 검색 서버에서 이미지,하지만 외부 저장소에서 이미지를로드 할 때 여전히 문제가 존재합니다.

아무도 도와 드릴 수 있습니까?

+0

그것은 아마도 무관하지만,이 [자식 링크] 봐 (https://github.com/codepath/android_guides/wiki/Endless-Scrolling-with-AdapterViews-and-RecyclerView#implementing-with-이 recyclerview)'.post' 대신'.postDelayed'를 사용하십시오 –

+0

.postDelayed를 사용할 곳은 ?? @ Mr.Z – Sid

+0

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

답변

4

그런 다음 외부 저장소에서 이미지를로드합니다. 이미지 이로드 된 것을 볼 수 있지만 스크롤 할 때 두 번째 또는 두 번째 이미지가 표시 될 수 있습니다. 사라져서 기본 이미지 아이콘을 볼 수 있습니다.

이것은 피카소의 대상 콜백을 사용하기 때문입니다. 콜백은 목록을 스크롤 할 때 조금 늦게 호출됩니다. 대상을 제거하고 Picasa에 이미지 뷰를 사용하면 정상적으로 작동합니다. 또한 Picasso가 스스로를 위해 비트 맵을 캐시 할 필요가 없습니다.

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

그러나 나는 다른 활동에서 이미지를 보여주기 위해 저장된 이미지의 위치를 ​​알아야하고 피카소에 저장된 캐시 이미지의 경로를 얻을 수 없다는 것을 발견했습니다. 외부 저장 장치에 이미지를 저장하고 사용하려면이 방법을 사용하십시오. – Sid

+1

다른 활동에서 동일한 이미지를 표시 할 위치가 필요하지 않습니다. 단지 이미지 URL이 필요합니다. Picasa는 이미지 url을 키로 사용하여 이미지를 저장합니다. 그래서 다른 액티비티 나 조각에서 이미지가 필요할 때 이미 저장되어있는 경우 캐시에서 복원 할 수 있습니다. – Sam

0

내가 실수 할 수 있지만 문제는 당신이 레이아웃 위치하여 데이터 세트에서 가져온 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

0

당신이 만약 :이 되길 바랍니다 간단히 이미지를로드 한 다음 외부 저장소에 저장해야하는 이유 다른 용도로 저장 한 다음 저장해야하는 이유 ImageView에 표시 할 때 Picasso 또는 Universal Image Loader과 같은 제 3 자 API를 사용하는 것이 좋습니다. 로딩 및 또한 캐시 메모리 관리의 모든 유형을 수행하여 많은 디스플레이 fasality를 제공합니다. 이 이미지로드처럼 당신에게

+0

사용자가 오프라인이면 여전히 목록을 볼 수 있기 때문에 폴더에 이미지를 저장하고 있습니다. 그래서 사용자가 오프라인 상태 일 때 폴더에서 이미지를로드하려고합니다. – Sid

+0

하지만 다른 작업에서 이미지를 표시하기 위해 저장된 이미지의 위치를 ​​가져와야하고 피카소에 저장된 캐시 이미지의 경로를 가져올 수 없다는 것을 알았 기 때문에이 방법으로 외부 저장소에 이미지를 저장하고 사용했습니다. @sanat chandravanshi – Sid

0

운영을 도움이 될 것입니다

희망은 백그라운드 스레드에서 AsyncTask를 사용하여 수행해야합니다.

+0

recyclerview의 비동기 작업에서 외부 저장소의 이미지를로드하는 코드를 안내해 줄 수 있습니까? – Sid

1

이 코드를 Application 클래스에서 사용하면 전체 앱에서 설정을 적용 할 수 있습니다.

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

지금 당신은 당신이 빠른 로딩도 이미지 크기 크기를 조정할 수 있습니다 큰 이미지 다루고있는 .If 볼을로드 피카소에 URL을 전달합니다. 얼마나 많은 MB

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

외부 메모리에서 이미지를로드하고 싶습니다. 피카소를 사용하여로드 할 수 있습니까? @ NANDAN KUMAR SINGH – Sid

+0

예 !! , 이미지 uri를 전달하여 외부 메모리에서로드 할 수 있습니다. –

+0

예제를 보여 주시겠습니까? @ NANDAN KUMAR SINGH – Sid

0
  • 확인 모든 이미지. 예 : 이미지가 1MB 또는 500kb이면 이미지를 번으로 다운로드하는 데 더 많은 시간이 걸릴 것이며 다운로드 한 후에는 catche에 저장됩니다. 즉, 처음으로 이미지를 다운로드하는 데 약간의 시간이 걸립니다.

  • catche.it에서 나온 이미지는 초 단위의 모든 이미지를 표시합니다.

  • 더 빠르고 Glide - Memory 관리를 위해 Volley를 사용하십시오.

    Glide 
        .with(context) 
        .load(rowItem.getPosteduserpostimage()) 
        .asBitmap() 
        .diskCacheStrategy(DiskCacheStrategy.SOURCE) 
        .fitCenter() 
        .placeholder(R.drawable.load_image) 
        .error(R.drawable.cancel_image) 
        .into(holder.ivPostedImageNew); 
    
  • 얼마나 큰 크기를로드하는 bitmap.You 이미지를 축소 할 필요가 here 를 참조하십시오.

  • 그렇지 않으면 모든 이미지를 업로드 할 때 라이브러리를 사용하여 자르기를 수행했습니다. 큰 비트 맵으로 스케일을 처리합니다. 예 : 5mb 이미지는 180kb로 축소됩니다.

  • 확인이자를 때 사용자가 아닌 작물 이미지, 그냥 전체 부분을 선택하면 CropImage lib 는, 더 큰 크기 images.Even을 축소하는 것이 좋은 또한 180kb.Image 품질 5 메가 축소됩니다. 내부 중첩 된 스크롤 뷰를 사용하지 않는 또한

    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); 
    } 
    
    • 그리고 :

    은 또한 당신이 image.You는 점에서이 코드를 볼 수 있습니다 축소하기 위해 아래의 코드를 사용할 수 있습니다 작물없이 생각 recyclerview.