0

私が欲しいものグライドでスムーズに外部ストレージから画像を読み込むには?

自分で自分のギャラリーアプリケーションを欲しいです。 そのために、電話のすべてのイメージをGridLayoutManagerによってRecyclerViewにロードしたいと思っています。

仕事

私はパスを持つ外部ストレージからすべての画像を得た何。 アプリは最初に表示されます。私は私のRecyclerView下にスクロールすると

immagesは、下のスクリーンショットのように歪むことになる動作しません何

enter image description here

私はまた、logcatで、このエラーを得た:

Process: com.spicysoftware.gallery, PID: 12209 
                      java.lang.RuntimeException: Canvas: trying to draw too large(115650308bytes) bitmap. 
                       at android.view.DisplayListCanvas.throwIfCannotDraw(DisplayListCanvas.java) 
                       at android.graphics.Canvas.drawBitmap(Canvas.java) 
                       at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java) 
                       at android.widget.ImageView.onDraw(ImageView.java) 
                       at android.view.View.draw(View.java) 
                       at android.view.View.updateDisplayListIfDirty(View.java) 
                       at android.view.View.draw(View.java) 
                       at android.view.ViewGroup.drawChild(ViewGroup.java) 
                       at android.view.ViewGroup.dispatchDraw(ViewGroup.java) 
                       at android.view.View.updateDisplayListIfDirty(View.java) 
                       at android.view.View.draw(View.java) 
                       at android.view.ViewGroup.drawChild(ViewGroup.java) 
                       at android.view.ViewGroup.dispatchDraw(ViewGroup.java) 
                       at android.view.View.draw(View.java) 
                       at android.view.View.updateDisplayListIfDirty(View.java) 
                       at android.view.View.draw(View.java) 
                       at android.view.ViewGroup.drawChild(ViewGroup.java) 
                       at android.support.v7.widget.RecyclerView.drawChild(RecyclerView.java:4477) 
                       at android.view.ViewGroup.dispatchDraw(ViewGroup.java) 
                       at android.view.View.draw(View.java) 
                       at android.support.v7.widget.RecyclerView.draw(RecyclerView.java:3869) 
                       at android.view.View.updateDisplayListIfDirty(View.java) 
                       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java) 
                       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java) 
                       at android.view.View.updateDisplayListIfDirty(View.java) 
                       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java) 
                       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java) 
                       at android.view.View.updateDisplayListIfDirty(View.java) 
                       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java) 
                       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java) 
                       at android.view.View.updateDisplayListIfDirty(View.java) 
                       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java) 
                       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java) 
                       at android.view.View.updateDisplayListIfDirty(View.java) 
                       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java) 
                       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java) 
                       at android.view.View.updateDisplayListIfDirty(View.java) 
                       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java) 
                       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java) 
                       at android.view.View.updateDisplayListIfDirty(View.java) 
                       at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java) 
                       at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java) 
                       at android.view.View.updateDisplayListIfDirty(View.java) 
                       at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java) 
                       at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java) 
                       at android.view.ThreadedRenderer.draw(ThreadedRenderer.java) 
                       at android.view.ViewRootImpl.draw(ViewRootImpl.java) 
                       at android.view.ViewRootImpl.performDraw(ViewRootImpl.java) 
                       at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java) 
                       at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java) 
                       at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java) 
                       at android.view.Choreographer$CallbackRecord.run(Choreographer.java) 
                       at android.view.Choreographer.doCallbacks(Choreographer.java) 
                       at android.view.Choreographer.doFrame(Choreographer.java) 
                       at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java) 
                       at android.os.Handler.handleCallback(Handler.java) 
                       at android.os.Handler.dispatchMessage(Handler.java) 
                       at android.os.Looper.loop(Looper.java) 
                       at android.app.ActivityThread.main(ActivityThread.java) 
                       at java.lang.reflect.Method.invoke(Native Method) 
                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java) 
                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java) 

これは私が

ます。public void loadAllImages(画像を読み込む方法です){

String[] mProjection = {MediaStore.Images.Media.DATE_TAKEN,MediaStore.Images.Media.DATA}; 
Cursor cursorImagesExternal = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,mProjection,null,null,MediaStore.Images.Media.DATE_ADDED); 
List<ItemObject> allItems = new ArrayList<ItemObject>(); 
int countImages = 0; 

while(cursorImagesExternal.moveToNext()) { 
    long date = cursorImagesExternal.getLong(0); 
    String fileLoc = cursorImagesExternal.getString(1); 
    allItems.add(new ItemObject(fileLoc)); 
    countImages ++; 
} 

Log.v("Image Count: ", ""+countImages); 

List<ItemObject> rowListItem = allItems; 
lLayout = new GridLayoutManager(MainActivity.this, 4); 

RecyclerView rView = (RecyclerView)findViewById(R.id.recycler_view); 
rView.setHasFixedSize(true); 
rView.setLayoutManager(lLayout); 

RecyclerViewAdapter rcAdapter = new RecyclerViewAdapter(MainActivity.this, rowListItem); 
rView.setAdapter(rcAdapter); 

} 

これは、アダプタ

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewHolders> { 

    private List<ItemObject> itemList; 
    private Context context; 

    public RecyclerViewAdapter(Context context, List<ItemObject> itemList) { 
     this.itemList = itemList; 
     this.context = context; 
    } 

    @Override 
    public RecyclerViewHolders onCreateViewHolder(ViewGroup parent, int viewType) { 

     View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_view_list, null); 
     RecyclerViewHolders rcv = new RecyclerViewHolders(layoutView); 
     return rcv; 
    } 

    @Override 
    public void onBindViewHolder(final RecyclerViewHolders holder, int position) { 
     //holder.countryName.setText(itemList.get(position).getName()); 

     Glide.with(context).asBitmap() 
       .load(itemList.get(position).getName()) 
       .thumbnail(0.5f) 
       .into(holder.countryPhoto); 


    } 

    @Override 
    public int getItemCount() { 
     return this.itemList.size(); 
    } 
} 

card_view_list.xml

<android.support.v7.widget.CardView 
    xmlns:card_view="http://schemas.android.com/apk/res-auto" 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/card_view" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_weight="4" 
    card_view:cardUseCompatPadding="true" 
    android:layout_marginBottom="16dp"> 

    <RelativeLayout 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content"> 

     <ImageView 
      android:id="@+id/country_photo" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:contentDescription="@string/action_settings" 
      android:src="@drawable/ic_remove_red_eye_black_24dp" 
      android:scaleType="centerCrop" /> 

    </RelativeLayout> 

</android.support.v7.widget.CardView> 

私の質問

スムーズにGridViewコントロールにイメージをロードするためのより良い方法はありますか?

もしそうでない場合は、私のコードで何が問題になっていますか?

+0

あなたも 'card_view_list.xml'を投稿することができますか? –

+0

もちろん。すでに完了しました! – MSeiz5

+0

テストのために、ImageView country_photoからlayout_widthとlayout_heightを92dpに固定しました。今、それは遅れたり何もしなくても働いています。 – MSeiz5

答えて

1

0.2fや0.1fのようなサムネイルフロートを下げる必要があるかもしれません。

また、MediaStore.Images.Thumbnailsなどの方法で試したり、別の方法で投影してサムネイルを表示することもできます。すべての画像にサムネイルがあることを保証するものではありません。あなたもそれを制御する必要があります。

ビットマップでハングアップするコールバックを使用したくない場合は、グライドリクエストで.asBitmap()を削除できます。

あなたはレイアウトのparamsを取得するために

View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_view_list, parent, false); 

代わり

View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_view_list, null); 

のように膨らませることができます。

CursorLoadersには、画像を非同期として読み込むようにしてください。だからUIは苦労しないだろう。

幸運

エムレ

+0

あなたの答えは解決策としてマークしました。トリックは、imageViewに固定サイズを与えることでした! – MSeiz5

+1

よかったです。 :)ありがとう –

0
int defaultImagePath = R.drawable.default_thumb; 
int errorImagePath = R.drawable.damaged_image; 
holder.countryPhoto.setImageResource(defaultImagePath); 

String uri = itemList.get(position).getName(); 
loadImageWithGlide(mContext, holder.countryPhoto, uri, defaultImagePath, 
         errorImagePath); 



public static void loadImageWithGlide(final Context context, ImageView theImageViewToLoadImage, 
              String theLoadImagePath, int theDefaultImagePath, int tehErrorImagePath) { 
     if (context == null) return; 

     //placeHolderUrl=R.drawable.ic_user; 
     //errorImageUrl=R.drawable.ic_error; 
     Glide.with(context) //passing context 
       .load(theLoadImagePath) //passing your url to load image. 
       .placeholder(theDefaultImagePath) //this would be your default image (like default profile or logo etc). it would be loaded at initial time and it will replace with your loaded image once glide successfully load image using url. 
       .error(tehErrorImagePath)//in case of any glide exception or not able to download then this image will be appear . if you won't mention this error() then nothing to worry placeHolder image would be remain as it is. 
       .diskCacheStrategy(DiskCacheStrategy.ALL) //using to load into cache then second time it will load fast. 
       //.animate(R.anim.fade_in) // when image (url) will be loaded by glide then this face in animation help to replace url image in the place of placeHolder (default) image. 
       //.fitCenter()//this method help to fit image into center of your ImageView 
       .into(theImageViewToLoadImage); //pass imageView reference to appear the image. 

     /* Normal way to Load Image with Glide. 
       Glide.with(theContext) 
       .load(theImagePath) 
       .diskCacheStrategy(DiskCacheStrategy.ALL) 
       .into(theImageView);*/ 
    } 
関連する問題