使用 Glide 的卡片视图中的多个图像仅显示最后加载的项目

问题描述

我正在使用 Glide(也尝试使用具有相同行为的 Picasso)将图像 url 列表加载到应该在相机视图中显示的卡片中。一切都像魅力一样工作,但如果我尝试加载更多然后大约 8-12 张图像,则只会显示一些最后创建的卡片视图。之前创建的视图被完全删除显示为没有卡片布局的压扁图像。控制台日志中没有加载错误或更多信息。

现在是故事的关键。当我从 cardview 中排除图像或使用本地 drawable 作为图像内容时,即使加载了 Glide,所有卡片都按预期显示

我考虑了缓存问题并添加android:largeHeap="true" 但没有成功。此外,我对所有卡片都使用了一个缩略图。同样的场景。

这是我用来从 pois 列表创建 cardview 的函数

       for (PlacesModel placesModel : mPlacesModelList) {

           if ((placesModel.getdistance() / 1000f) < showdist) {

              View view = layoutInflator.inflate(R.layout.ar_view,null);
              view.setTag(placesModel.getPlaceId());
              view.setVisibility(View.INVISIBLE);
              ImageView img = view.findViewById(R.id.card_view_image);

              view.setScaleY(setSize(placesModel.getdistance()) / 8.0f);
              view.setScaleX(setSize(placesModel.getdistance()) / 8.0f);

              TextView text = view.findViewById(R.id.t);
              TextView desc = view.findViewById(R.id.d);

              text.setMinWidth(200);
              text.setText(placesModel.getPlaceName());

              desc.setText(Config.cdist(placesModel.getdistance()));

              text.setTextSize(TypedValue.COMPLEX_UNIT_SP,setSize(placesModel.getdistance()) / 3.0f);
              desc.setTextSize(TypedValue.COMPLEX_UNIT_SP,(setSize(placesModel.getdistance()) - 1) / 2.0f);

              Glide.with(getApplicationContext())
                      .load(placesModel.getimageThumbnail())
                      .thumbnail(0.1f)
                      .diskCacheStrategy(diskCacheStrategy.ALL)
                      .error(R.drawable.no_image)
                      .listener(new RequestListener<Drawable>() {
                         @Override
                         public boolean onLoadFailed(@Nullable GlideException e,Object model,Target<Drawable> target,boolean isFirstResource) {
                            view.setVisibility(View.GONE);
                            return false;
                         }
                         @Override
                         public boolean onResourceReady(Drawable resource,DataSource dataSource,boolean isFirstResource) {
                            view.setLayoutParams(new LinearLayout.LayoutParams(
                                    LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT));
                            view.setVisibility(View.GONE);
                            return false;
                         }
                      })
                      .into(img);

              infl.addView(view);
              }
           }
        }

这是相应的布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/marker"
android:clickable="true"
android:focusable="true"
android:onClick="cardViewClicked"
android:layout_width="wrap_content"
android:layout_height="wrap_content">

<androidx.cardview.widget.CardView
    android:id="@+id/mainMarker"
    android:orientation="vertical"
    android:padding="4dp"
    android:background="#ffffff"
    app:cardBackgroundColor="#ffffff"
    app:cardCornerRadius="1dp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <LinearLayout
        android:padding="2dp"
        android:layout_width="wrap_content"
        android:orientation="vertical"
        android:layout_height="wrap_content">
        <ImageView
            android:id="@+id/card_view_image"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:scaleType="fitXY"/>
        <TextView
            android:id="@+id/t"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:lines="1"
            android:maxWidth="80dp"
            android:textAppearance="@style/TextAppearance.FontPath.Bold"
            android:textColor="@android:color/black"/>
        <TextView
            android:id="@+id/d"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:lines="1"
            android:maxWidth="80dp"
            android:text=""/>
    </LinearLayout>
</androidx.cardview.widget.CardView>

<ImageView
    android:layout_width="15dp"
    android:layout_height="15dp"
    android:layout_below="@+id/mainMarker"
    android:layout_centerHorizontal="true"
    android:scaleType="fitXY"
    android:src="@drawable/ic_marker" />
</RelativeLayout>

解决方法

动态(以编程方式)创建 CardView 及其内容。在 XML 文件中,只需在 java 文件中创建一个布局并使用 CardView 动态添加卡片。

在类内部创建对象,但在 onCreate 方法外部。

RelativeLayout relativeLayout = new RelativeLayout;

然后,使用其 id 链接布局

relativeLayout = findViewById(R.id.marker);

然后创建一个将在创建卡片时调用的函数。该函数内的代码如下所示:

TextView textView = new TextView(this);
textView.setText("Something...");
CardView cardView = new CardView(this);
cardView.addView(textView);
relativeLayout.addView(cardView);
,

我找到了解决方案。

Logcat 中有一个 Glide 信息,其他人提到我可以稍微忽略。

Glide treats LayoutParams.WRAP_CONTENT as a request for an image the size of this device's screen dimensions. If you want to load the original image and are ok with the corresponding memory cost and OOMs (depending on the input size),use override(Target.SIZE_ORIGINAL). Otherwise,use LayoutParams.MATCH_PARENT,set layout_width and layout_height to fixed dimension,or use .override() with fixed dimensions.

现在我只需要像这样将布局参数设置为 Target.SIZE_ORIGINAL

view.setLayoutParams(new LinearLayout.LayoutParams(
                      Target.SIZE_ORIGINAL,Target.SIZE_ORIGINAL));