使用 Glide 将带有图像的 Viewholder 缓存到 RecyclerView 中

Caching viewholders with image into RecyclerView using Glide

大家好,我有一个关于 RecyclerView 的问题 我试过聊天之类的东西。 我有时在 recyclerview 的一行中有图片和文字,有些只有文字,有些只有图片。

一切正常,但不滚动且行超出内存。

当内存不足并且我想再次显示它时,行只显示进度条,滑动不加载。

我使用 glide 进入 ViewHolder 我没有对粘贴在该线程中的仅取景器中的图像做任何其他操作。

GlideApp.with(v).load(conv.getUrlFromServer()).diskCacheStrategy(DiskCacheStrategy.ALL).placeholder(R.mipmap.ic_launcher).centerCrop().listener(new RequestListener<Drawable>() {
                @Override
                public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                    circleProgresBar.setVisibility(View.GONE);
                    pictureMsg.setVisibility(View.VISIBLE);
                    return false;
                }

                @Override
                public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                    pictureMsg.setVisibility(View.VISIBLE);
                    circleProgresBar.setVisibility(View.GONE);
                    return false;
                }
            }).into(pictureMsg);

我的观众。XML

   <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">


    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/LineLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="0dp"
        android:layout_marginLeft="0dp"
        android:layout_marginRight="0dp"
        android:layout_marginTop="0dp"
        android:gravity="left">

        <android.support.v7.widget.CardView
            android:id="@+id/rowCard"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="@dimen/card_Bottom"
            android:layout_marginRight="@dimen/card_Right"
            android:layout_marginTop="@dimen/card_Top"
            card_view:cardCornerRadius="20dp"
            card_view:cardElevation="5dp">

            <android.support.constraint.ConstraintLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                tools:layout_editor_absoluteX="0dp"
                tools:layout_editor_absoluteY="0dp">

                <TextView
                    android:id="@+id/text"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginEnd="@dimen/text_End"
                    android:layout_marginStart="@dimen/textview_Start"
                    android:layout_marginTop="@dimen/textview_top"
                    android:gravity="left"
                    android:paddingRight="@dimen/textview_Right"
                    android:text="Kolo"
                    android:textColor="@color/black"
                    android:textSize="16sp"
                    card_view:layout_constraintBottom_toBottomOf="parent"
                    card_view:layout_constraintEnd_toEndOf="parent"
                    card_view:layout_constraintHorizontal_bias="0.0"
                    card_view:layout_constraintStart_toStartOf="parent"
                    card_view:layout_constraintTop_toTopOf="parent"
                    card_view:layout_constraintVertical_bias="0.0" />

                <FrameLayout
                    android:id="@+id/frameLayout"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    card_view:layout_constraintBottom_toBottomOf="parent"
                    card_view:layout_constraintEnd_toEndOf="parent"
                    card_view:layout_constraintHorizontal_bias="0.5"
                    card_view:layout_constraintStart_toStartOf="parent"
                    card_view:layout_constraintTop_toBottomOf="@+id/text"
                    card_view:layout_constraintVertical_bias="0.5">

                    <ImageView
                        android:id="@+id/pictureMsg"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginEnd="@dimen/text_End"
                        android:layout_marginStart="@dimen/textview_Start"
                        android:adjustViewBounds="false"
                        android:minHeight="0dp"
                        android:visibility="visible" />

                    <ProgressBar
                        android:id="@+id/circleProgresBar"
                        style="?android:attr/progressBarStyle"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"
                        android:visibility="gone" />
                </FrameLayout>

            </android.support.constraint.ConstraintLayout>


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


    </RelativeLayout>

</LinearLayout>

我试过了

    mRecyclerView.setHasFixedSize(true);
    mRecyclerView.setDrawingCacheEnabled(true);
    mRecyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);

但是在增加缓存数量时不成功,这在逻辑上有助于减少滚动,但这不是解决方案。而且它会占用大量内存。

这就是您解释我的问题所需要的一切。我粘贴屏幕以便更好地解释。

这是启动画面之后 向上滚动记忆的下降。 然后回到底部 它正在永久加载(滑行在后台什么都不做)

抱歉图形:D

感谢任何建议。

===================================添加信息====== =======================

这是我的 onBindMethod 对我来说是 setDataOnView 因为已经实现了 MyGeneriViewholder

@Override
    public void setDataOnView(int position, final RealmModel data) {
        RealmModelMessage conv = (RealmModelMessage) data;
        if (!conv.isStatus()) {
            mRow.setAlpha(0.5f);
        } else {
            mRow.setAlpha(1f);
        }
        RelativeLayout.LayoutParams llpCard;
        if (conv.getId_from() != mMyId) {
            mText.setGravity(Gravity.LEFT);
            mRow.setGravity(Gravity.LEFT);
         //   mText.setPadding(0, 0, mTextMargin_Right, 0);

            llpCard = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
            llpCard.setMargins(0, mCardMargin_Top, mCardMargin_Right, mCardMargin_Bottom); // llp.setMargins(left, top, right, bottom)
            mCardView.setLayoutParams(llpCard);
            mCardView.setPadding(mTextMargin_Start, mTextMargin_Top, mTextMargin_End, mTextMargin_Bottom); // llp.setMargins(left, top, right, bottom);
            mCardView.setCardBackgroundColor(Color.argb(225,0,238,238));

            if (!String.valueOf(conv.getUrlFromServer()).equals("")){
                pictureMsg.setVisibility(View.VISIBLE);
                GlideApp.with(v).load(conv.getUrlFromServer()).diskCacheStrategy(DiskCacheStrategy.AUTOMATIC).placeholder(R.mipmap.ic_launcher).fitCenter().listener(new RequestListener<Drawable>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                        circleProgresBar.setVisibility(View.GONE);
                  //      Toast.makeText(v.getContext(), "Chyba obrázku", Toast.LENGTH_SHORT).show();
                        pictureMsg.setBackground(v.getContext().getResources().getDrawable(R.mipmap.ic_launcher));
                        pictureMsg.setVisibility(View.VISIBLE);
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                        pictureMsg.setVisibility(View.VISIBLE);
                        circleProgresBar.setVisibility(View.GONE);
                        return false;
                    }
                }).into(pictureMsg);} else {
                pictureMsg.setVisibility(View.GONE);
            }

        } else {
            mText.setGravity(Gravity.RIGHT);
            mRow.setGravity(Gravity.RIGHT);

            llpCard = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
            llpCard.setMargins(mCardMargin_Right, mCardMargin_Top, 0, mCardMargin_Bottom); // llp.setMargins(left, top, right, bottom)
            mCardView.setLayoutParams(llpCard);
            mCardView.setPadding(0, mTextMargin_Top, mTextMargin_Start, mTextMargin_Bottom); // llp.setMargins(left, top, right, bottom)
            mCardView.setCardBackgroundColor(Color.argb(225,238,238,0));

            if (!String.valueOf(conv.getUrlFromServer()).equals("")){
                circleProgresBar.setVisibility(View.VISIBLE);
               // pictureMsg.setVisibility(View.VISIBLE);
              //GlideApp.with(v).load(conv.getUrlFromServer()).diskCacheStrategy(DiskCacheStrategy.AUTOMATIC).placeholder(R.mipmap.ic_launcher).centerCrop().into(pictureMsg);
               GlideApp.with(v).load(conv.getUrlFromServer()).diskCacheStrategy(DiskCacheStrategy.ALL).placeholder(R.mipmap.ic_launcher).centerCrop().listener(new RequestListener<Drawable>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                        circleProgresBar.setVisibility(View.GONE);
                        Toast.makeText(v.getContext(), "Chyba obrázku", Toast.LENGTH_SHORT).show();
                        pictureMsg.setVisibility(View.VISIBLE);
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                        pictureMsg.setVisibility(View.VISIBLE);
                        circleProgresBar.setVisibility(View.GONE);
                        return false;
                    }
                }).into(pictureMsg);

                /*        Drawable drawable=pictureMsg.getDrawable();
                double width =pictureMsg.getDrawable().getIntrinsicHeight();
                double heigh =pictureMsg.getDrawable().getIntrinsicWidth();
                double widthInScreen= v.getContext().getResources().getDimension(R.dimen.minWidth_Image150dp);
                double constant= widthInScreen/width;
                double newWidth= width*constant;
                double newHeigh= heigh*constant;
                FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams((int) newWidth,(int) newHeigh);
                pictureMsg.setLayoutParams(layoutParams);
                */
            } else {
                pictureMsg.setVisibility(View.GONE);
            }

        }

        mText.setText(conv.getText());

}

我用 .override(int) 解决了我的问题

像()之间的这个尺寸就是宽度和高度。

GlideApp.with(v).load(conv.getUrlFromServer()).diskCacheStrategy(DiskCacheStrategy.AUTOMATIC).override((int) v.getContext().getResources().getDimension(R.dimen.minWidth_Image150dp), v.getContext().getResources().getDimension(R.dimen.minWidth_Image150dp)).placeholder(R.mipmap.ic_launcher).centerCrop().listener(new RequestListener<Drawable>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                        circleProgresBar.setVisibility(View.GONE);
                        Toast.makeText(v.getContext(), "Chyba obrázku", Toast.LENGTH_SHORT).show();
                        pictureMsg.setVisibility(View.VISIBLE);
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                        pictureMsg.setVisibility(View.VISIBLE);
                        circleProgresBar.setVisibility(View.GONE);
                        return false;
                    }
                }).into(pictureMsg);

不知道这个有什么用。