显示Gif菜单

文章介绍了如何在Android应用的底部菜单中集成GIF播放,以提升用户体验。作者通过Glide库解决了兼容性问题,创建了一个工具类GifUtil,该类使用StateListDrawable根据视图的状态显示不同的图片,当视图被选中时播放GIF一次。难点在于控制GIF仅播放一次以及监听状态变化。文章提供了具体的代码示例和使用方法。
摘要由CSDN通过智能技术生成

需要

最近研究在底部菜单中加入gif播放。这样显得高级一些。研究了一些技术方案,现在写篇博客,沉淀一下。

效果

在这里插入图片描述

实现

通过Glide实现。虽然android官方有AnimatedImageDrawable 但是只支持API28以上,也就是android9.0以上的手机。兼容性太差。

写了一个工具类,可以根据传入的两个drawable的id值。自动生成一个StateListDrawable 。在view被选中的时候,显示相关图片。如果相关图片是gif就播放一次。

难点在于怎么播放一次。
我的方法是先stop,再调用startFromFirstFrame

还有就是怎么监听状态的改变,在onStateChange添加记录即可。

关于StateListDrawable 手动调用addState时要注意。空的状态数组表示默认状态。一定要最后一个添加。如果第一个添加。其他状态都无法匹配,将始终显示默认状态。

这个工具类依赖glide,需要引入依赖

    implementation 'com.github.bumptech.glide:glide:4.15.1'

工具

/**
 * <pre>
 * Created by zhuguohui
 * Date: 2023/7/7
 * Time: 14:54
 * Desc:
 * </pre>
 */
public class GifUtil {

    public static void setDrawable(ImageView imageView,int normalId, int selectedId) {


        GIfStateListDrawable listDrawable = new GIfStateListDrawable();
        addState(imageView, new int[]{android.R.attr.state_selected}, selectedId, listDrawable, () -> {
            addState(imageView, new int[]{}, normalId, listDrawable, () -> {
                imageView.setImageDrawable(listDrawable);
            });
        });
    }

    private interface CallBack {
        void call();
    }

    private static void addState(ImageView imageView, int[] states, int resId, StateListDrawable listDrawable, CallBack callBack) {
        Glide.with(imageView)
                .asDrawable()
                .load(resId)
                .into(new CustomTarget<Drawable>() {
                    @Override
                    public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
                        listDrawable.addState(states, resource);
                        callBack.call();
                    }

                    @Override
                    public void onLoadCleared(@Nullable Drawable placeholder) {

                    }
                });
    }


    public static class GIfStateListDrawable extends StateListDrawable {

        private  boolean stateChange=false;
        @Override
        protected boolean onStateChange(int[] stateSet) {
            boolean change=super.onStateChange(stateSet);
            if(change){
                stateChange=true;
            }
            return change;
        }

        @Override
        public void draw(Canvas canvas) {
            super.draw(canvas);
            if(stateChange) {
                //确保只播放一次gif
                stateChange=false;
                Drawable current = getCurrent();
                if (current instanceof GifDrawable) {
                    GifDrawable gifDrawable = (GifDrawable) current;
                    gifDrawable.setLoopCount(1);
                    gifDrawable.stop();
                    gifDrawable.startFromFirstFrame();
                }
            }
        }
    }

}

使用

demo

使用很简单,传入两个drawable就行了。更过修改view的selected状态来自动播放gif

public class MainActivity extends AppCompatActivity {
    ImageView iv1,iv2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        iv1=findViewById(R.id.iv_1);
        iv2=findViewById(R.id.iv_2);
        GifUtil.setDrawable(iv1,R.drawable.city_normal,R.drawable.city_selected);
        GifUtil.setDrawable(iv2,R.drawable.home_normal,R.drawable.home_selected);


        iv1.setOnClickListener(v->{
            iv1.setSelected(true);
            iv2.setSelected(false);
        });

        iv2.setOnClickListener(v->{
            iv2.setSelected(true);
            iv1.setSelected(false);
        });
    }


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值