ViewsFlipper--最易用的的仿淘宝、京东消息轮播控件

ViewsFlipper--最易用的的仿淘宝、京东消息轮播控件

  • 1-Demo
  • 2-如何使用
  • 3-API说明
  • 4-实现思路
  • 5-源码链接
  • 6-未来的改进方向

1-Demo

ViewsFlipper--最易用的的仿淘宝、京东消息轮播控件_第1张图片 ViewsFlipper--最易用的的仿淘宝、京东消息轮播控件_第2张图片

2-如何使用

在XML中设置如下。其中flipDuration表示动画时长, flipInterval是轮播间隔时间,flipInterval一定要大于flipDuration,否则会抛出异常。

    <fresh.lee.viewsflipper.ViewsFlipper
        android:id="@+id/flipper"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:flipDuration="500"
        app:flipInterval="2500"/>

Activity中Example,和RecyclerView的用法完全一致!!!而且更重要的是,和RecyclerView一样,完全可以自己定制各种Child View。

    private List<Pair<Integer, String>> items = new ArrayList<>();
    items.add(new Pair<>(R.drawable.ic_ac_unit_black_24dp, "感受停在我发端的指尖"));
    items.add(new Pair<>(R.drawable.ic_android_black_24dp, "如何瞬间 冻结时间"));
    items.add(new Pair<>(R.drawable.ic_brightness_3_black_24dp, "记住望着我坚定的双眼"));
    items.add(new Pair<>(R.drawable.ic_cloud_black_24dp, "也许已经 没有明天"));
    final ViewsFlipper flipper = findViewById(R.id.flipper);
    final FlipperAdapter adapter = new FlipperAdapter(items);
    flipper.setAdapter(adapter);
    flipper.setOrientation(RecyclerView.VERTICLE);
    flipper.startFlipping();
    
    class FlipperAdapter extends RecyclerView.Adapter<VH> {
        private List<Pair<Integer, String>> list;

        FlipperAdapter(List<Pair<Integer, String>> list) {
            this.list = list;
        }

        @NonNull
        @Override
        public VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            return new VH(LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_flipper_child, parent, false));
        }

        @Override
        public void onBindViewHolder(@NonNull VH holder, int position) {
            holder.bind(list.get(position).first, list.get(position).second);
        }

        @Override
        public int getItemCount() {
            return list.size();
        }
    }

    class VH extends RecyclerView.ViewHolder {
        private TextView tvLyric;
        private ImageView iv;

        VH(@NonNull View itemView) {
            super(itemView);
            tvLyric = itemView.findViewById(R.id.tv_child);
            iv = itemView.findViewById(R.id.iv_child);
        }

        void bind(int drawableId, String lyric) {
            iv.setImageResource(drawableId);
            tvLyric.setText(lyric);
        }
    }

3-API说明

Function 作用 参数说明
setAdapter(adapter) 设置数据源 RecyclerView.Adapter
startFlipping() 开始轮播
stopFlipping() 停止轮播
setFlipInterval(milliseconds) 设置轮播间隔时间 轮播间隔时间
getFlipInterval() 获取轮播间隔时间
setFlipDuration(milliseconds) 设置滚动动画时间 动画时间
getFlipDuration() 获取滚动动画时间
setOrientation 设置滚动方向 RecyclerView.Orientation
getOrientation 获取当前滚动方向

支持功能:

  • 支持Adapter数据的动态更新,改变数据之后需要调用Adapter.notifyDataSetChanged,不过更新之后会从第一项数据开始展示。
  • 支持设置滚动方向,支持垂直滚动和水平滚动。只需要调用ViewsFlipper.setOrientation即可,参数是RecyclerView.HORIZONTAL或者RecyclerView.VERTICAL。

4-实现思路

  去年曾经写过一篇android 消息垂直滚动轮播控件,这几天在整理之前代码的时候,又拾起来看了一下。这一篇就不讲轮播功能的具体实现了,和上一篇是一致的,有兴趣可以先去上一篇看一下。
  现在看看,当时的实现貌似有点ugly。虽然基本功能都已经实现了,但是代码耦合度还是有点高,而且不支持数据的动态更新,只能是垂直滚动。而且最重要的一点,没有考虑到性能的优化。比如,在原来的实现里面我根据传进来的数据,一次性的生成了所有的子View,加入数据非常多的话,就会生成大量的子View。但是这里其实只需要两个子View就足够了!因为这种轮播的View,只有在滚动的时候,才会展示两个子View,其他的时候只有一个View是显示的,另外的View都是隐藏的。所以只需要创建两个子View,然后只需要在循环播放时,更新每个子View的数据就可以了。
  说到这里,你能想到什么?没错,就是RecyclerView,我当时就在想这个不就是RecyclerView吗,当然我们这里的功能其实比RecyclerView要少很多,我们只需要RecyclerView的Adapter来实现数据与View的分离,还有ViewHolder来实现View的复用就可以了,其他功能暂时并不需要。
  说干就干,开始改造计划。首先将原来实现的自己定义的RollingTextAdapter,改成了RecyclerView.Adapter(其实最初实现的时候也已经考虑数据与View分离了,但是当时实现的方式是类似与ListView的Adapter的方式,没有考虑到复用)。然后在setAdapter方法里,我们就不需要生成所有的子View,我们只需要维护两个ViewHolder,正在显示的View和隐藏的View的ViewHolder就可以了。其他逻辑基本上和之前的版本保持不变。然后还利用了Adapter的notifyDataSetChanged功能,实现了不需要重新setAdapter的数据动态更新(不过实现的很简单,而且更新之后都要从第一项开始展示)。并且还增加了对水平方向滚动的支持。

  • 为什么选用RecyclerView.Adapter?主要是为了让大家减少学习使用成本,而且还可以利用到notifyDataSetChanged的功能。
  • 那为什么不直接用RecyclerView直接实现轮播功能呢?RecyclerView直接实现也是可以的,不过我感觉有点大材小用了,所以就结合Android原生控件ViewFlipper和RecyclerView自定义了ViewsFlipper。

5-源码链接

  想要看具体实现的朋友可以直接去github上直接看源码。欢迎fork,star!

6-未来的改进方向

  1. 数据动态更新目前只是简单做到从第一条重新开始展示(其实就是我懒,这样做最省事),这个应该是可以参考RecyclerView的数据更新方式,然后利用DiffUtil进行比较,然后动态无感知更新;
  2. 目前动画的接口我没有暴露出来,因为动画那块的代码写的太烂了,和其他功能参杂交织在一起。等什么时候我把动画的逻辑和其他逻辑分离开来,再把动画的接口暴露出来。
  3. 代码内部逻辑优化,代码结构优化等。

你可能感兴趣的:(android学习)