RecyclerView Item加载动画

来源:互联网 发布:pptv聚力网络电视下载 编辑:程序博客网 时间:2024/06/05 15:14


这段时间更新的博客内容不太系统,但也是平时比较常用的技术。

今天和大家分享一篇关于ReclcyerView的内容。说到RecyclerView,想必大家都已玩的熟透在心了。之前有人问我ListView和RecyclerView的区别是什么?并且很多人认为RecyclerView比ListView强多了。的确,RecyclerView在动画处理上要优越于ListView。但是如果列表不存在动画的话,加载处理性能都是不相上下的。

关于RecyclerView,网上有很多的开源项目,对其进行了功能封装,例如很常见的下拉刷新,上拉加载更多,侧滑,拖拽等等。但是关于列表展示的动画效果还是比较少,ok,既然如此,咱们就来聊聊如何实现RecyclerView展示加载动画。

先来张效果图压压惊



                                                                                



一、原理分析


RecyclerView 和ListView相同,展示数据都是基于Adapter之上。不同之处在于RecyclerView为了优化ConvertView,限制必须实现ViewHolder。ListView中绑定Item View的方法大家肯定不陌生,即getView。而RecyclerView则是onCreateViewHolder。说了这么多,其实就是为了引出一个问题:我们该在哪里实现展示动画?没错,就是onCreateViewHolder
中。原理也很简单,因为在onCreateViewHolder中,我们需要绑定加载ItemView和Holder,而展示动画显然是附加在ItemView上的。所以,最终的实现就是对ItemView附加动画效果。分析了核心原理,接下来就是撸码了~


二、核心实现


(1)引入RecyclerView


项目中引用RecyclerView库有两种方式:

1.直接引用RecyclerView:

compile ‘com.android.support:recyclerview-v7:24.1.0’
2.引用design库,design库中包含了MD所有的新组件:

compile 'com.android.support:design:24.0.0'

(2)XML布局创建RecyclerView

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/activity_main"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.song.recyclerv.MainActivity">    <android.support.v7.widget.RecyclerView        android:id="@+id/rv"        android:layout_width="match_parent"        android:layout_height="match_parent" /></RelativeLayout>

(3)Activity获取RecyclerView,设置Adapter

package com.song.recyclerv;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import com.song.recyclerv.animation.SlideInBottomAnimation;import com.song.recyclerv.animation.SlideInLeftAnimation;import com.song.recyclerv.animation.SlideInRightAnimation;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity {    RecyclerView rv;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        rv = (RecyclerView) findViewById(R.id.rv);        // 初始化列表数据        List<String> data = new ArrayList<>();        for (int i = 0; i < 300; i++) {            data.add(""+i);        }        // 竖向列表布局        rv.setLayoutManager(new LinearLayoutManager(this));        // 创建Adapter        BaseRecyclerViewAdapter  adapter = new BaseRecyclerViewAdapter(this,data);        // 设置展示动画        adapter.setAnimation(new SlideInRightAnimation());        // 设置Adapter        rv.setAdapter(adapter);    }}
可以发现,上述代码中,我们通过setAnimation设置了动画效果为SlideInRightAnimation,即从右侧滑入。具体动画怎么实现的呢?来看Adapter:


(4)创建Adapter,嵌入动画效果

package com.song.recyclerv;import android.animation.Animator;import android.content.Context;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.view.animation.Interpolator;import android.view.animation.LinearInterpolator;import android.widget.TextView;import com.song.recyclerv.animation.AlphaInAnimation;import com.song.recyclerv.animation.BaseAnimation;import java.util.List;/** * Created by Song on 2017/4/27. */public class BaseRecyclerViewAdapter extends RecyclerView.Adapter<BaseRecyclerViewAdapter.BaseHolder>{    private Context mContext;    private List<String> data;    private LayoutInflater inflater;    private int mLastPosition = -1;    private int mPosition = 0;    private Interpolator mInterpolator = new LinearInterpolator();    private int mDuration = 300;    private BaseAnimation mSelectAnimation = new AlphaInAnimation();    private boolean mOpenAnimationEnable = true;    public BaseRecyclerViewAdapter(Context context,List<String> datas){        this.data = datas;        this.mContext = context;        inflater = LayoutInflater.from(mContext);    }    @Override    public BaseHolder onCreateViewHolder(ViewGroup parent, int viewType) {        View itemView = inflater.inflate(R.layout.item_layout,parent,false);        BaseHolder b = new BaseHolder(itemView);//        ViewHolderHelper holder = ViewHolderHelper.get(mContext, null, parent, R.layout.item_layout, -1);        return b;    }    @Override    public void onBindViewHolder(BaseHolder holder, int position) {        holder.tv.setText(data.get(position));        if(mOpenAnimationEnable) {            addAnimation(holder);        }    }    public void updatePosition(int position) {        mPosition = position;    }    @Override    public int getItemCount() {        return data.size();    }    /**     * 添加动画     * @param holder     */    public void addAnimation(RecyclerView.ViewHolder holder) {        if (mOpenAnimationEnable) {            if (holder.getLayoutPosition() > mLastPosition) {                BaseAnimation animation = null;                if (mSelectAnimation != null) {                    animation = mSelectAnimation;                }                for (Animator anim : animation.getAnimators(holder.itemView)) {                    startAnim(anim);                }                mLastPosition = holder.getLayoutPosition();            }        }    }    /**     * 开启动画     * @param animator     */    private void startAnim(Animator animator) {        animator.setDuration(mDuration).start();        animator.setInterpolator(mInterpolator);    }        /**     * 设置动画效果     * @param animation     */    public void setAnimation(BaseAnimation animation){        this.mOpenAnimationEnable = true;        this.mSelectAnimation = animation;    }    static class BaseHolder extends RecyclerView.ViewHolder {        private TextView tv;        public BaseHolder(View itemView) {            super(itemView);            tv = (TextView) itemView.findViewById(R.id.tv);        }    }}


三、核心功能分析


(1)mOpenAnimationEnable标识是否开启动画效果,onBindViewHolder中,在开启状态下(mOpenAnimationEnable 为 true),执行addAnimation

(2)addAnimation方法中,判断当前显示的Item位置是大于上一个的,才去开启动画效果。然后获取Animator,执行startAnimation开启动画,BaseAnimation其实是一个接口:

/** * 动画接口 */public interface  BaseAnimation {    Animator[] getAnimators(View view);}

(3)在初始化Adapter时,我们调用了setAnimation方法,可以看到该方法初始化了动画效果,那么我们来看具体的动画实现:

/** * 右侧滑入动画 */public class SlideInRightAnimation implements BaseAnimation {    @Override    public Animator[] getAnimators(View view) {        return new Animator[]{                ObjectAnimator.ofFloat(view, "translationX", view.getRootView().getWidth(), 0)        };    }}
上述代码利用Android3.0后的属性动画ObjectAnimator来初始化具体的动画方式。


(4)调用startAnimation开启动画


以上经过4步,就实现了RecyclerView的展示动画效果啦~~


源码下载

 

1 0