背景
背景从一个图片过渡到另一个图片,走的都是网络图片。
遇到的问题
貌似是一个简单的需求,但是好像也不简单。背景组件就是我们熟悉的image view,然后通过一些图片加载框架给他上图片。实际上应该怎么操作呢。
第一种图片加载完成之后,切换图片,加载图片,使用placeholder的api把已经显示的内容丢进去加一个transition设置时间过度,收工下班。

以上,就是程序员的日常。
经过测试之后,反馈了一些问题,闪退了。
java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@460e6c48
	at android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1084)
	at android.view.GLES20Canvas.drawBitmap(GLES20Canvas.java:844)
	at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:490)
	at android.widget.ImageView.onDraw(ImageView.java:1019)
	at android.view.View.draw(View.java:14479)
	at android.view.View.getDisplayList(View.java:13376)
	at android.view.View.getDisplayList(View.java:13418)
	at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3077)
	
	//后面堆栈就是设置bg的地方了

堆栈明确告诉我们了,非法使用一个不存在的对象,我们在placeholder中设置的是上一个图片的内容,这个归glide管理,如果在内存吃紧的时候触发回收,而这个时候刚刚好我们跑到了切换背景图片的页面,然后加载的时候就回收了,巧不巧呢,而且在使用之前进行了判空,是真的巧啊,问题是程序结果只有0和1,没有巧不巧。最后当然是crash了。
还是cv大法
本来是想利用glide的placeholder加配置过度动画方式偷懒做业务,奈何不可靠。
既然图像数据是别人管理的不可靠,那我自己来好吧。
使用我们程序员的技能中用的最骚的:cv大法。
我们设置placeholder设置我们自己管理的就好了。
怎么说呢,就是把image view的内容复制出来。
public class AppImgUtils {
    /**
     * 复制一个新的drawable
     *
     * @param drawable 旧的
     * @return 新的
     */
    public static Drawable getNewDrawable(@NonNull Drawable drawable) {
        return drawable.getConstantState().newDrawable();
    }
}
加载图片前
Drawable newDrawable = AppImgUtils.getNewDrawable(oldDrawable);
Glide.with(context)
                        
    .load(imageUrl)
    .placeholder(newDrawable)
还有一种方式可以做过度动画,但是还是需要上面方式,自己管理图像,不然就回收了。
伪代码。
//glide加载,完成之后,动画切换
Glide.with(this).load("https://sfsdfasdf")
        .into(new SimpleTarget<Drawable>() {
            @Override
            public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drtransition) {
                Drawable newDrawable = AppImgUtils.getNewDrawable(oldDrawable);
                Drawable[] drawableArray = {
                        newDrawable,
                        resource
                };
                TransitionDrawable fade = new TransitionDrawable(drawableArray);
                mIvTransition.setImageDrawable(fade);
                //设置过度时间
                fade.startTransition(3000);
            }
        });
效果:

最后
以上奔溃不是我搞的,我只是看到了错误,做了一个分析和修复。
各位观众姥爷如果有更好的方案,欢迎评论区留下你宝贵的经验~





























