Как правильно загрузить образы хранилища Firebase в recycelrView - PullRequest
1 голос
/ 02 мая 2019

У меня есть утилита просмотра, и в каждой строке у меня есть изображение, которое я загружаю с хранилищем базы данных .Похоже, что загрузка изображений влияет на производительность прокрутки recyclerView.

Я использую glide для загрузки изображений, полученных из firebase внутри onBindViewHolder, вызывая метод imageLoadGlide, подобный этому:

//Download image from firebase Storage and set gameImage("ImageView") image.
private void imageLoadGlide(DocumentSnapshot documentSnapshot, final QuestionsHolder questionsHolder) {
    //for firebase storage
    FirebaseStorage storage = FirebaseStorage.getInstance();
    // Create a storage reference from our app
    StorageReference storageRef = storage.getReference();
    storageRef.child(documentSnapshot
            .get("image").toString())
            .getDownloadUrl()
            .addOnSuccessListener(new OnSuccessListener<Uri>() {
        @Override
        public void onSuccess(Uri uri) {
            //this part is loading image from url library
            Glide
                    .with(context.getApplicationContext())   // pass Context
                    .load(uri)// pass the image url
                    .centerCrop() // optional scaletype
                    .crossFade() //optional - to enable image crossfading
                    .transform(new CircleTransform(context))//transfoms the imageView onto circle with the custon class CircleTransform
                    .into(questionsHolder.gameImage); // the ImageView to which the image is to be loaded
            //stop the loading bar from spinning
            questionsHolder.loadProgress.setVisibility(View.GONE);
        }
    });
}

Загрузка работает нормально, но делает прокрутку очень медленной.

Я понятия не имею, почему это происходит, потому что я сжимаю изображения перед их загрузкой, поэтому я не думаю, что этопроблема веса изображения.

Сжатие изображения сделано так:

Bitmap bitmap = ((BitmapDrawable) questionImage.getDrawable()).getBitmap();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 10, baos);
byte[] data = baos.toByteArray();
UploadTask uploadTask = mountainImagesRef.putBytes(data);

Есть идеи, почему это происходит и как этого избежать?

Вот onBindViewHolder для запроса @Vadim Eksler:

@Override
public void onBindViewHolder(@NonNull final QuestionsHolder holder, final int position) {
    holder.gameImage.setImageBitmap(null);
    setInfoForViews(holder, result.get(position));

    imageLoadGlide(result.get(position), holder);

    setOnClicksListners(holder, position);
    setRankTextView(position, holder);
    if (position == result.size() - 1 && !endOfDocs && next != null) {
        loadMoreDocs(position);
    }
}

1 Ответ

0 голосов
/ 02 мая 2019

Этот ответ основан на всех комментариях вместе.

Итак, как уже упоминалось в комментариях, я ошибся в том, что каждый раз, когда вызывался onBindViewHolder, я снова и снова извлекал изображение из firebase - это приводит к плохой производительности recyclerView.

Что я сделал, чтобы это исправить:

Я использовал flyweight шаблон проектирования, чтобы загрузить изображение только в первый раз из firebase, а после этого просто перезапустить это изображение в следующий раз, когда будет вызван onBindViewHolder.

  • Сначала я создал карту как глобальную переменную:

    private Map<String, Bitmap> flyweight = new HashMap<>();

  • после этого, когда изображение загружается с первого раза, я сохраню его на потом, когда onBindViewHolder будет вызван снова:

    Внутри onBindViewHolder:

    if (flyweight.get(result.get(position).get("image").toString()) == null) {
        imageLoadGlide(result.get(position), holder); // load the image
    } else {
        //recycle the image that i already have
        holder.gameImage.setImageBitmap(flyweight.get(result.get(position).get("image").toString()));
    }
    

И последнее, что нужно добавить, это изображение, которое я создал после того, как оно было успешно извлечено:

flyweight.put(documentSnapshot.get("image").toString(), resource);
...