ตั้งค่าการแสดงแถบความคืบหน้าเมื่อเสร็จสิ้นการโหลดภาพโดยใช้ไลบรารี Glide


90

สวัสดีฉันต้องการมีแถบความคืบหน้าสำหรับรูปภาพซึ่งจะแสดงในขณะที่โหลดรูปภาพ แต่เมื่อการโหลดรูปภาพเสร็จสมบูรณ์ฉันต้องการตั้งค่าให้หายไป ก่อนหน้านี้ฉันใช้ห้องสมุด Picasso สำหรับสิ่งนี้ แต่ฉันไม่รู้ว่าจะใช้กับคลัง Glide ได้อย่างไร ฉันมีความคิดว่ามีฟังก์ชั่นพร้อมทรัพยากรอยู่ที่นั่น แต่ฉันไม่รู้วิธีใช้ ใครสามารถช่วยฉัน?

รหัสสำหรับห้องสมุด 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() {
           }
        })
;

ตอนนี้ฉันจะทำสิ่งนี้ด้วย Glide ได้อย่างไร?

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

ฉันสามารถโหลดรูปภาพได้ด้วย Glide แต่ฉันจะเขียนprogressBar.setVisibility(View.GONE);โค้ดที่ไหนสักแห่งได้อย่างไรหากรูปภาพถูกโหลด


2
ทำไมคุณถึงเปลี่ยนห้องสมุดของคุณ? ปิกัสโซยอดเยี่ยมมาก
tasomaniac

ฉันอยากจะแนะนำให้ใช้ Picasso เว้นแต่คุณจะมีเหตุผลที่ดีในการเปลี่ยนห้องสมุด
Chris

คำตอบ:


232

คำถามค่อนข้างเก่าและฉันไม่รู้ว่าสถานการณ์เหินในยุคนั้นเป็นอย่างไร แต่ตอนนี้สามารถทำได้อย่างง่ายดายกับผู้ฟัง (ไม่ใช่ตามที่เสนอไว้ในคำตอบที่เลือกว่าถูกต้อง)

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)
;

คุณคืนค่าจริงหากต้องการจัดการสิ่งต่างๆเช่นภาพเคลื่อนไหวด้วยตัวเองและเท็จหากต้องการร่อนเพื่อจัดการกับคุณ


13
ลองซ่อนprogressBarอินonExceptionด้วยมิฉะนั้นมันจะทำให้ความหวังผิด ๆ หมุนไปเรื่อย ๆ เมื่อถูกเรียกว่าร่อนจะทำอะไรนอกเหนือจากชุดสิ่งที่ผ่านไปonException .error()
TWiStErRob

2
ซึ่งอาจส่งผลให้เกิด NullPointerException ถ้าคุณออกจาก Fragment / Activity ก่อนที่รูปภาพจะโหลด
aProperFox

1
ฉันไม่ได้กวนคุณเพื่อสร้างผู้ฟังชั้นใน แต่เป็นวิธีที่กระชับที่สุดในการแสดงเครื่องมือสำหรับการทำงานให้สำเร็จ
Yaroslav

1
แน่นอนฉันแก้ไขสิ่งนี้โดยเพิ่มการโทรใน onDestroyVIew () ก่อนการโทรสุดยอดเพื่อพูดว่า Glide.clear (yourImageView)
aProperFox

7
หมายเหตุ: .listenerต้องโทรมาก่อน.into()
Ahmed Mostafa

31

หากคุณต้องการทำใน KOTLIN คุณสามารถลองวิธีนั้น:

    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)

7
ต้องนำเข้าเป้าหมายด้วย:import com.bumptech.glide.request.target.Target
Gibolt

@Gibolt นี้ที่ bugging ฉันสำหรับ 10 นาทีตรง
johnrao07

17

คำตอบของฉันอ้างอิงจาก API ที่ล้าสมัย ดูที่นี่สำหรับคำตอบขึ้นไปวันที่


.listener()จะดีกว่าเพราะคุณจะได้รับข้อมูลเพิ่มเติมเกี่ยวกับการโหลดของคุณ (โมเดลแคชหน่วยความจำ ... ) ดังนั้นจึงง่ายต่อการตัดสินใจตรรกะที่กำหนดเองมากขึ้น RequestListenerยังมีเสถียรภาพมากขึ้นการลบล้างสิ่งที่Targetจะสร้างจะไม่ทำให้คุณได้รับประโยชน์จากการแก้ไขในอนาคต คุณยังสามารถสร้างสิ่งVisibilityListener<T, R>ที่คุณสามารถใช้ซ้ำในบริบทต่างๆได้อย่างง่ายดาย
TWiStErRob

10

ในข้อยกเว้นให้วางเงื่อนไขสำหรับการแสดงอีกครั้ง 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);

8

วิธีแก้ปัญหาข้างต้นก็ใช้ได้ดีสำหรับฉันเช่นกัน แต่เมื่อฉันใช้asBitmap ()เพื่อดาวน์โหลดรูปภาพ มันไม่ทำงาน.

เราจำเป็นต้องใช้ 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);
            }
        });

ดูความคิดเห็นของฉัน: stackoverflow.com/questions/26054420/… . คำตอบนี้เป็นการสาธิตที่ดีของสิ่งที่ฉันพูดที่นั่น
TWiStErRob

7

GlideDrawable เลิกใช้แล้วใช้ Drawable แบบธรรมดา

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

ใน Kotlin คุณสามารถทำได้ดังนี้

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. ใน xml ใช้แถบความคืบหน้าที่มีความสูงและความกว้าง (match_parent)
  2. ก่อนโทรด้านล่างวิธีการกล่าวถึงให้ตั้งค่าการเปิดเผยแถบความคืบหน้าที่มองเห็นได้

    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
    

คำตอบของคุณแตกต่างจากstackoverflow.com/a/31675796/3812404อย่างไร นอกจากนี้ไม่จำเป็นต้องใช้จุดที่ 1
HariRam

2

อัปเดต:

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);

สมมติว่าคุณมี onResourceReady อยู่แล้วการใช้ "into" คืออะไร? ฉันไม่สามารถใช้ฟังเพียงอย่างเดียวได้หรือไม่ ถ้าเป็นเช่นนั้นฉันจะเริ่มโหลดได้อย่างไรโดยไม่ต้อง "เข้า"
นักพัฒนา Android

@android developer อย่างที่ฉันรู้ว่าคุณสามารถใช้ได้โดยไม่ต้องใช้
Narek Hayrapetyan

มันคือความพยายาม
Narek Hayrapetyan

แต่ถ้าฉันไม่ใช้ "into" ฉันคิดว่ามันเตือนเกี่ยวกับเรื่องนี้
นักพัฒนา android

1

ฉันทำสิ่งต่างๆได้อย่างไร วิธีที่สั้นกว่ารหัสที่สะอาดกว่า

ตัวอย่าง:

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)

การใช้งาน:

GlideImpl.OnCompleted {
    // completed
}

เพียงแค่ส่งผ่านGlideImpl.OnCompleted { }ไปยัง Glide's.listener()

คลาส GlideImpl.kt ที่ยอมรับ 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
        }
    }
}

และนั่นมัน!


0

ทาง 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

นี่คือคำตอบที่ดีที่สุดเนื่องจากไม่ใช้แฮ็คใด ๆ เช่นการตั้งค่าการมองเห็นเพื่อให้ได้ผลลัพธ์ที่ต้องการ

ดาวน์โหลด gif ของprogressbargifแถบความคืบหน้าและเรียกมันและวางไว้ในโฟลเดอร์ที่วาดได้

        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);

เมื่อโหลดภาพ URL แล้วภาพขนาดย่อจะหายไป ภาพขนาดย่อจะหายไปทันทีเมื่อโหลดภาพแคช


4
ฉันคิดว่ามันเป็นเพราะมันไม่ตอบคำถาม: OP มีสปินเนอร์ที่เขาพอใจอยู่แล้ว นอกจากนี้ยังขัดต่อแนวทางปฏิบัติที่ดีที่สุดของ Android: การใช้ GIF เนื่องจากสปินเนอร์เป็นยุค 90 และเพิ่มขนาด APK อย่างมาก และการใส่ GIF เข้าไปdrawableนั้นไม่ดีในตัวมันเองเนื่องจากไม่ได้โหลดโดยเฟรมเวิร์กจึงควรอยู่ในrawหรืออย่างassetsดีที่สุด ไม่มีอะไรผิดปกติกับการเปลี่ยนการเปิดเผยเมื่อมีเหตุการณ์เกิดขึ้นในแอปของคุณ Android ออกแบบมาเพื่อสิ่งนั้น
TWiStErRob

1
นอกจากนี้ผู้ใช้จะเห็นพื้นที่ว่างในขณะที่การถอดรหัส GIF เกิดขึ้น แต่จะไม่ซิงค์และไม่ได้ทันที คุณกำลังRESULTแคชแถบความคืบหน้าซึ่งหมายความว่าจะใช้เวลาโหลดสักครู่ GIF ควรได้รับการSOURCEแคชอย่างดีที่สุดเพื่อประสิทธิภาพ แต่เนื่องจากนี่เป็นไฟล์ในเครื่องแคชจึงต้องNONEไม่ทำซ้ำบนดิสก์ทำให้ใช้พื้นที่ผู้ใช้มากขึ้น
TWiStErRob
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.