RecycleView简单总结

2019-05-01  本文已影响0人  _Felix__

基础知识

下拉加载更多

https://www.jianshu.com/p/b502c5b59998

基本实现

RecycleView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);  

//设置布局管理器  必选
/*  
RecyclerView提供了三种布局管理器:
LinerLayoutManager 以垂直或者水平列表方式展示Item
GridLayoutManager 以网格方式展示Item
StaggeredGridLayoutManager 以瀑布流方式展示Item

如果你想用 RecyclerView 来实现自己自定义效果,则应该去继承实现自己的 LayoutManager,
并重写相应的方法,而不应该想着去改写 RecyclerView。
*/
LinearLayoutManager layoutManager = new LinearLayoutManager(this);  
recyclerView.setLayoutManager(layoutManager);  

//设置为垂直布局,这也是默认的  
layoutManager.setOrientation(OrientationHelper. VERTICAL);  

//设置Adapter  必选
recyclerView.setAdapter(recycleAdapter);  

 //设置分隔线  可选(默认为空)
recyclerView.addItemDecoration( new DividerGridItemDecoration(this) );  
//设置增加或删除条目的动画  可选(默认为DefaultItemAnimator)
recyclerView.setItemAnimator( new DefaultItemAnimator());  

点击事件

Adapter

// ① 创建Adapter
public class NormalAdapter extends RecyclerView.Adapter<NormalAdapter.VH>{
    //② 创建ViewHolder
    public static class VH extends RecyclerView.ViewHolder{
        public final TextView title;
        public VH(View v) {
            super(v);
            title = (TextView) v.findViewById(R.id.title);
        }
    }
    
    private List<String> mDatas;
    public NormalAdapter(List<String> data) {
        this.mDatas = data;
    }

    public void updateData(ArrayList<String> data){
        this.mData = data;
        notifyDataSetChanged();
    }

    //1.定义点击回调接口
    public interface OnItemClickListener{
        void onItemClick(View view, int position);
        void onItemLongClick(View view, int position);
    }
    //2.定义一个设置点击监听器的方法
    public void setOnItemClickListener(MyAdapter.OnItemClickListener listener){
        listener.onItemClickListener = listener;
    }

    //③ 在Adapter中实现3个方法
    @Override
    public void onBindViewHolder(VH holder, int position) {
        holder.title.setText(mDatas.get(position));
        /*holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //item 点击事件
            }
        });*/
        //3.对RecycleView的每一个itemView设置点击事件
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(final View v) {
                if(onItemClickListener != null) {
                    int pos = holder.getLayoutPosition();
                    onItemClickListener.onItemClick(holder.itemView, pos);
                }
            }
        });

        holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                if(onItemClickListener != null) {
                    int pos = holder.getLayoutPosition();
                    onItemClickListener.onItemLongClick(holder.itemView, pos);
                }
                //表示此事件已经消费,不会触发单击事件
                return true;
            }
        });
    }

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

    @Override
    public VH onCreateViewHolder(ViewGroup parent, int viewType) {
        //LayoutInflater.from指定写法
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_1, parent, false);
        //不能是inflate(R.layout.item_1,null);
        return new VH(v);
    }
}

常见的坑

补充

可通过ItemTouchHelper类 轻易实现拖拽,侧滑删除

ListView 和RecycleView的差异

刷新

ListView
我们都知道ListView通过adapter.notifyDataSetChanged()实现ListView的更新,这种更新方法的缺点是全局更新,即对每个Item View都进行重绘。但事实上很多时候,我们只是更新了其中一个Item的数据,其他Item其实可以不需要重绘。
这里给出ListView实现局部更新的方法:

public void updateItemView(ListView listview, int position, Data data){
    int firstPos = listview.getFirstVisiblePosition();
    int lastPos = listview.getLastVisiblePosition();
    if(position >= firstPos && position <= lastPos){  //可见才更新,不可见则在getView()时更新
        //listview.getChildAt(i)获得的是当前可见的第i个item的view
        View view = listview.getChildAt(position - firstPos);
        VH vh = (VH)view.getTag();
        vh.text.setText(data.text);
    }
}

可以看出,我们通过ListView的getChildAt()来获得需要更新的View,然后通过getTag()获得ViewHolder,从而实现更新。

RecyclerView
RecyclerView提供了notifyItemInserted(),notifyItemRemoved(),notifyItemChanged() 等API更新单个或某个范围的Item视图。

缓存

基本上相似。ListView和RecyclerView最大的区别在于数据源改变时的缓存的处理逻辑,ListView是”一锅端”,将所有的mActiveViews都移入了二级缓存mScrapViews,而RecyclerView则是更加灵活地对每个View修改标志位,区分是否重新bindView。

RecyclerView四级缓存:
mAttachedScrap 缓存在屏幕上的ViewHolder
mCachedViews 缓存屏幕外的ViewHolder,默认为2个
mViewCacheExtensions
mRecyclerPoor

回收机制

基本上相似。ListView是以View作为单位进行回收,RecyclerView是以ViewHolder作为单位进行回收。

参考文献:https://www.jianshu.com/p/4f9591291365

上一篇下一篇

猜你喜欢

热点阅读