Android ScrollView 内的 ListView Glide 加载图像 FireBase 并不总是加载

Android ListView inside ScrollView Glide to load images off FireBase not loading always

我在将显示图像和文本的 ScrollView 中有一个 ListView。文字显示完美。然而图像不是。如果我缓慢滚动列表 - 所有图像都可以完美加载而不会失败,但如果我滚动得非常快,它们就永远不会加载。我认为这是我在调用方法的地方设置的方式,但这是我在 Android 的第一天。以下是资源、布局和 classes。

我如何在列表中添加 Text 和 ImageView:

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TableRow>
        <ImageView
            android:id="@+id/img"
            android:layout_width="50dp"
            android:layout_height="50dp"/>

        <TextView
            android:id="@+id/txt"
            android:layout_width="wrap_content"
            android:layout_height="50dp" />

    </TableRow>

</TableLayout>

class一起去吧:

public class someClass extends ArrayAdapter<String>{

    private final Activity context;
    private final ArrayList<String> web;
    ImageView imageView;
    FirebaseStorage storage = FirebaseStorage.getInstance();
    StorageReference storageRef = storage.getReference();
    final ArrayList<Uri> uriList = new ArrayList<>();
    public galveon_character_creation_spelllist(Activity context,
                      ArrayList<String> web) {
        super(context, R.layout.someClass, web);
        this.context = context;
        this.web = web;

    }
    @Override
    public View getView(int position, View view, ViewGroup parent) {
        LayoutInflater inflater = context.getLayoutInflater();
        View rowView = inflater.inflate(R.layout.someClass, null, true);
        TextView txtTitle = (TextView) rowView.findViewById(R.id.txt);


        imageView = (ImageView) rowView.findViewById(R.id.img);
        txtTitle.setText(web.get(position));
        getImages(position);

        return rowView;
    }

    public void getImages(Integer position) {
        storageRef.child("FolderRef/" + web.get(position) + ".png").getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
            @Override
            public void onSuccess(Uri uri) {
                //imageView.setImageURI(null);
                //imageView.setImageURI(uri);
                Glide.with(getContext())
                        .load(uri) // the uri you got from Firebase
                        .placeholder(R.drawable.unknown) //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.
                        .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(imageView); //Your imageView variable

            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception exception) {
                // Handle any errors
                imageView.setImageResource(R.drawable.unknown);
            }
        });
    }
}

web只是与图片名称对齐的文字。此外,当 activity 加载列表时,所有看到的 "cells" 都不会加载,但是当您缓慢向下滚动并返回时,图像会出现(如果您滚动缓慢)。

如果我需要 post 更多信息,我可以。仍在学习 Android 的工作原理。

尝试将 imageview 作为 getImage 的参数而不是全局变量。 例如:

    // inside getView
    ImageView imageView = (ImageView) rowView.findViewById(R.id.img);
    getImages(position, imageView);

    // GetImage
    public void getImages(Integer position, ImageView im) {
       ....
    }

首先,最好在您的列表中实现 ViewHolder 模式或使用 RecyclerView。在您当前的情况下,您一遍又一遍地膨胀视图,这是没有必要的,如果视图太复杂,可能会降低应用程序的性能。您可以阅读有关 ViewHolder 模式的更多信息 here

 @Override
public View getView(int position, View convertView, ViewGroup parent) {

    ViewHolder holder;
    if (convertView == null) {
        //Inflate the view once if the view is null
        LayoutInflater inflater = context.getLayoutInflater();
        convertView = inflater.inflate(R.layout.someClass, null, true);
        holder = new ViewHolder();
        holder.txtTitle = (TextView) convertView.findViewById(R.id.txt)
        holder.imageView = (ImageView) convertView.findViewById(R.id.img);
        convertView.setTag(holder);
    }
    else {
        //retrieve the reference of the inflated view
        holder = (ViewHolder) convertView.getTag();
    }

    holder.txtTitle.setText(web.get(position));
    getImages(holder.imageView, position);
    return convertView;
}

public void getImages(ImageView imageView, int position) {
    storageRef.child("FolderRef/" + web.get(position) + ".png").getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
        @Override
        public void onSuccess(Uri uri) {
            //imageView.setImageURI(null);
            //imageView.setImageURI(uri);
            Glide.with(getContext())
                    .load(uri) // the uri you got from Firebase
                    .placeholder(R.drawable.unknown) //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.
                    .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(imageView); //Your imageView variable

        }
    }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception exception) {
            // Handle any errors
            imageView.setImageResource(R.drawable.unknown);
        }
    });
}

static class ViewHolder {
   TextView txtTitle;
   ImageView imageView;
}