Setel visibilitas bilah kemajuan yang hilang saat menyelesaikan pemuatan gambar menggunakan pustaka Glide


90

Hai, saya ingin memiliki bilah kemajuan untuk gambar yang akan ditampilkan saat pemuatan gambar tetapi ketika pemuatan gambar selesai saya ingin mengaturnya agar hilang. Sebelumnya saya menggunakan perpustakaan Picasso untuk ini. Tapi saya tidak tahu bagaimana menggunakannya dengan perpustakaan Glide. Saya memiliki gagasan bahwa beberapa fungsi siap sumber daya ada di sana tetapi saya tidak tahu bagaimana menggunakannya. Ada yang bisa bantu saya?

Kode untuk Perpustakaan Picasso

Picasso.with(mcontext).load(imgLinkArray.get(position).mUrlLink)
       .into(imageView, new Callback() {
           @Override
           public void onSuccess() {
               progressBar.setVisibility(View.GONE);
           }

           @Override
           public void onError() {
           }
        })
;

Sekarang Bagaimana Saya Dapat Melakukan Ini dengan Glide?

Glide.with(mcontext).load(imgLinkArray.get(position).mUrlLink)
     .into(imageView);

Saya dapat memuat gambar dengan ini dengan Glide tetapi bagaimana saya bisa menulis progressBar.setVisibility(View.GONE);di suatu tempat dalam kode jika gambar dimuat?


2
Mengapa Anda mengubah perpustakaan Anda? Picasso luar biasa.
tasomaniac

Saya juga merekomendasikan untuk tetap menggunakan Picasso kecuali Anda memiliki alasan yang kuat untuk mengubah perpustakaan
Chris

Jawaban:


229

Pertanyaan agak lama, dan saya tidak tahu apa situasi dengan glide pada masa itu, tetapi sekarang dapat dengan mudah dilakukan dengan pendengar (tidak seperti yang diusulkan dalam jawaban yang dipilih sebagai benar).

progressBar.setVisibility(View.VISIBLE);
Glide.with(getActivity())
     .load(args.getString(IMAGE_TO_SHOW))
     .listener(new RequestListener<String, GlideDrawable>() {
         @Override
         public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
             return false;
         }

         @Override
         public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
             progressBar.setVisibility(View.GONE);
             return false;
         }
     })
     .into(imageFrame)
;

Anda mengembalikan true jika ingin menangani hal-hal seperti animasi sendiri dan false jika ingin meluncur untuk menanganinya.


13
Pertimbangkan untuk menyembunyikan bagian progressBardalam onExceptionjuga, jika tidak maka akan berputar tanpa batas dan memberikan harapan palsu. Setelah onExceptiondisebut Glide tidak akan melakukan apa pun selain mengatur apa yang diteruskan .error().
TWiStErRob

2
Ini bisa menghasilkan NullPointerException jika Anda meninggalkan Fragment / Activity sebelum gambar dimuat.
aProperFox

1
Saya tidak mendorong Anda untuk membuat pendengar kelas dalam, hanya cara paling ringkas untuk menunjukkan alat untuk menyelesaikan tugas.
Yaroslav

1
Tentu saja, saya menyelesaikan ini dengan menambahkan panggilan di onDestroyVIew () sebelum panggilan super untuk mengatakan Glide.clear (yourImageView)
aProperFox

7
CATATAN: .listenerharus dipanggil sebelumnya.into()
Ahmed Mostafa

31

Jika Anda ingin melakukan ini di KOTLIN, Anda dapat mencobanya dengan cara:

    Glide.with(context)
            .load(url)
            .listener(object : RequestListener<Drawable> {
                override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean {
                    //TODO: something on exception
                }
                override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
                    Log.d(TAG, "OnResourceReady")
                    //do something when picture already loaded
                    return false
                }
            })
            .into(imgView)

5
Juga perlu mengimpor Target:import com.bumptech.glide.request.target.Target
Gibolt

@Gibolt ini mengganggu saya selama 10 menit berturut
johnrao07

17

Jawaban saya didasarkan pada API yang sudah ketinggalan zaman. Lihat di sini untuk jawaban yang lebih mutakhir.


.listener()lebih baik karena Anda akan menerima lebih banyak informasi tentang pemuatan Anda (model, cache memori, ...) sehingga lebih mudah untuk memutuskan lebih banyak logika kustom. RequestListenerjuga lebih stabil, menimpa yang Targetakan dibuat tidak akan memberi Anda manfaat untuk perbaikan di masa mendatang. Anda juga dapat dengan mudah membuat VisibilityListener<T, R>yang dapat digunakan kembali dalam konteks yang berbeda.
TWiStErRob

10

Dalam pengecualian, berikan syarat untuk menampilkan lagi ProgressBar

 Glide.with(context)
    .load(image_url)
    .listener(new RequestListener<String, GlideDrawable>() {
        @Override
        public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
            if(e instanceof UnknownHostException)
                progressBar.setVisibility(View.VISIBLE);
            return false;
        }

        @Override
        public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
            progressBar.setVisibility(View.GONE);
            return false;
        }
    })
    .into(imageView);

7

Solusi di atas bekerja cukup baik untuk saya juga, tetapi ketika saya menggunakan asBitmap () untuk mengunduh gambar. Tidak bekerja.

Kita perlu menggunakan BitmapImageViewTarget

Glide.with(this) .load(imageURL)
 .asBitmap()
 .placeholder(R.drawable.bg)
 .into(new BitmapImageViewTarget(imageView) {
            @Override
            public void onResourceReady(Bitmap  drawable, GlideAnimation anim) {
                super.onResourceReady(drawable, anim);
                progressBar.setVisibility(View.GONE);
            }
        });

Lihat komentar saya: stackoverflow.com/questions/26054420/… . Jawaban ini adalah demonstrasi yang bagus dari apa yang saya katakan di sana.
TWiStErRob

7

GlideDrawable tidak digunakan lagi, gunakan Drawable sederhana

RequestOptions requestOptions = new RequestOptions();
requestOptions.placeholder(R.drawable.placeholder);
requestOptions.error(R.drawable.error);

Glide.with(getContext())
                 .setDefaultRequestOptions(requestOptions)
                 .load(finalPathOrUrl)
                 .listener(new RequestListener<Drawable>() {
                        @Override
                        public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                            progressBar.setVisibility(View.GONE);
                            return false;
                        }

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

4

Di Kotlin Anda bisa melakukan seperti di bawah ini

Glide.with(context)
            .setDefaultRequestOptions(RequestOptions().placeholder(R.drawable.ic_image_placeholder).error(R.drawable.ic_image_placeholder))
            .load(url)
            .listener(object : RequestListener<Drawable>{
                override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean {
                    return false
                }

                override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
                    return false
                }

            })
            .into(imageView)

2
  1. Dalam xml, ambil progress bar dengan tinggi & lebar (match_parent).
  2. Sebelum panggilan di bawah menyebutkan metode, atur visibilitas bilah kemajuan Terlihat.

    public void setImageWIthProgressBar(Context context, final ImageView imageView, String imageUrl, final ProgressBar progressBar) {
    
            Glide.with(context)
                    .load(imageUrl)
                    .listener(new RequestListener<String, GlideDrawable>() {
                        @Override
                        public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
                            progressBar.setVisibility(View.GONE);
                            return false;
                        }
    
                        @Override
                        public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
                            progressBar.setVisibility(View.GONE);
                            return false;
                        }
                    })
                    .into(imageView);
    
        }//setImageWIthProgressBar
    

Apa perbedaan jawaban Anda dengan stackoverflow.com/a/31675796/3812404 ? Juga, poin 1 tidak diperlukan.
HariRam

2

Memperbarui:

Glide.with(this)
            .load(imageUrl)
            .listener(new RequestListener<Drawable>() {
                @Override
                public boolean onLoadFailed(@Nullable final GlideException e,
                                            final Object model, final Target<Drawable> target,
                                            final boolean isFirstResource) {
                    showProgress(false);

                    mNoContentTextView.setVisibility(View.VISIBLE);

                    return false;
                }

                @Override
                public boolean onResourceReady(final Drawable resource, 
                                               final Object model, 
                                               final Target<Drawable> target, 
                                               final DataSource dataSource, 
                                               final boolean isFirstResource) {
                    showProgress(false);

                    mNoContentTextView.setVisibility(View.GONE);
                    mContentImageView.setImageDrawable(resource);

                    return false;
                }
            })
            .into(mContentImageView);

Misalnya, jika Anda sudah memiliki onResourceReady, apa gunanya "into"? Tidak bisakah saya menggunakan pendengar saja? Jika demikian, bagaimana cara membuatnya mulai memuat tanpa "ke?
pengembang android

Pengembang @android seperti yang saya tahu Anda dapat menggunakan tanpa menjadi
Narek Hayrapetyan

berdiri untuk mencoba
Narek Hayrapetyan

Tetapi jika saya tidak menggunakan "ke", saya pikir itu memperingatkan tentang itu.
pengembang android

1

Bagaimana saya melakukan sesuatu. cara yang lebih pendek, kode yang lebih bersih

contoh:

progress_bar.visibility = View.VISIBLE

profilePicturePath?.let {
    GlideApp.with(applicationContext)
        .load(CloudStorage.pathToReference(it))
        .placeholder(R.drawable.placeholder)
        .listener(GlideImpl.OnCompleted {
            progress_bar.visibility = View.GONE
        })
    .into(profile_picture)
} ?: profile_picture.setImageResource(R.drawable.placeholder)

pemakaian:

GlideImpl.OnCompleted {
    // completed
}

langsung saja GlideImpl.OnCompleted { }ke Glide's.listener()

Kelas GlideImpl.kt yang menerima RequestListener Glide

import android.graphics.drawable.Drawable
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target

object GlideImpl {

    object OnCompleted : RequestListener<Drawable> {

        private lateinit var onComplete: () -> Unit

        operator fun invoke(onComplete: () -> Unit): OnCompleted {
            OnCompleted.onComplete = { onComplete() }
            return this
        }

        override fun onResourceReady(
            resource: Drawable?,
            model: Any?,
            target: Target<Drawable>?,
            dataSource: DataSource?,
            isFirstResource: Boolean
        ): Boolean {
            onComplete()
            return false
        }

        override fun onLoadFailed(
            e: GlideException?,
            model: Any?,
            target: Target<Drawable>?,
            isFirstResource: Boolean
        ): Boolean {
            onComplete()
            return false
        }
    }
}

dan itu dia!


0

Cara Kotlin

Glide.with(context)
                .load(image_url)
                .listener(object : com.bumptech.glide.request.RequestListener<Drawable> {
                    override fun onLoadFailed(
                        e: GlideException?,
                        model: Any?,
                        target: Target<Drawable>?,
                        isFirstResource: Boolean
                    ): Boolean {
                        return false
                    }

                    override fun onResourceReady(
                        resource: Drawable?,
                        model: Any?,
                        target: Target<Drawable>?,
                        dataSource: DataSource?,
                        isFirstResource: Boolean
                    ): Boolean {
                        img_product_banner.visibility = View.VISIBLE
                        return false
                    }

                }).placeholder(R.drawable.placeholder)
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .into(img_product_banner)

-1

Ini adalah jawaban terbaik karena tidak menggunakan peretasan seperti mengatur visibilitas untuk mendapatkan hasil yang diinginkan.

Unduh gif dari bilah kemajuan dan panggil progressbargifdan taruh di folder drawable.

        Glide.with(ctx)
            .load(url)
            .thumbnail(Glide.with(ctx).load(R.drawable.progressbargif))
            .diskCacheStrategy(DiskCacheStrategy.SOURCE)
            .error(R.drawable.image_unavailable)
            .crossFade(200)
            .into(iv);

Setelah gambar url dimuat, thumbnail menghilang. Thumbnail langsung hilang saat gambar cache dimuat.


4
Saya pikir itu karena tidak menjawab pertanyaan: OP sudah memiliki pemintal yang dia sukai. Ini juga bertentangan dengan praktik terbaik Android: menggunakan GIF sebagai pemintal sama saja dengan 90-an dan meningkatkan ukuran APK secara signifikan; dan memasukkan GIF ke drawabledalam itu sendiri buruk karena tidak dimuat oleh kerangka kerja, seharusnya dalam rawatau yang assetsterbaik. Tidak ada yang salah dengan mengubah visibilitas saat peristiwa terjadi di aplikasi Anda, Android dirancang untuk itu.
TWiStErRob

1
Pengguna juga akan melihat ruang kosong saat decoding GIF terjadi, asinkron dan tidak langsung. Anda juga RESULT-caching bilah kemajuan yang berarti perlu beberapa saat untuk memuat. GIF sebaiknya di- SOURCEcache untuk efisiensi; tetapi karena ini adalah file lokal, cache harus NONEtidak menduplikasinya di disk, sehingga menghabiskan lebih banyak ruang pengguna.
TWiStErRob
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.