从listView到RecyclerView,实战带你顺利爬坑

— 从入门到放弃,我想说的是,我不是那样的人,这个逼,我要装下去!

listView的相关认知,学习,我们也讲了不少了,要学习的可以 点这里 接下来,我想接着走完RecyclerView,让我们在对比实践中学习吧,毕竟它们相似相杀;

  • 首先,我们来看看他们运用上最大的区别:
    熟悉RecyclerView的人早已经理解了,不熟悉的也早就听说了,RecyclerView相对于listView的最明显的好处就是
    • 横向滚动的ListView,RecyclerView天生自带
    • 横向滚动的GridView,RecyclerView天生自带
    • 瀑布流的效果,RecyclerView天生自带

以上这些效果listview也都能实现,像我这样的懒货,还是喜欢用人家的现成的!说的我好像真的会一样,哈哈。
- 其次,来对比下api的使用吧
- listView的先不说了 点这里 看完懂
- RecyclerView需要继承重写 RecyclerView.Adapter 和 RecyclerView.ViewHolder
- RecyclerView需要设置布局管理器,控制布局效果

这里是示例代码:

//adapter的大概写法
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {

    private ArrayList<String> mData;
    private List<Boolean> boolList;
    private View v;
    private MyAdapter.OnItemClickListener onItemClickListener;

    public MyAdapter(ArrayList<String> data, List<Boolean> boolList) {
        this.mData = data;
        this.boolList = boolList;
    }


    //item的点击事件需要自定义
    public interface OnItemClickListener {
        void onItemClick(View view, int position);
        void onItemLongClick(View view, int position);
    }

    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        if (viewType == 2) {
            // 实例化展示的view
            v = LayoutInflater.from(parent.getContext()).inflate(R.layout.iten_view, parent, false);
            // 实例化viewholder
            ViewHolder viewHolder = new ViewHolder(v);
            return viewHolder;
        } else {
            // 实例化展示的view
            v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_teo, parent, false);
            // 实例化viewholder
            ViewHolder  viewHolderTwo = new ViewHolder(v);
            return viewHolderTwo;
        }

    }

    @Override
    public void onBindViewHolder(ViewHolder holder, final int position) {
        // 绑定数据
        holder.mTv.setText(mData.get(position));
        holder.cbChange.setChecked(boolList.get(position));
        holder.cbChange.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //此处处理checkbox在RecyclerView中状态复用的问题
                MainActivity.changeCheckty(position, boolList);
            }
        });
    }

    @Override
    public int getItemCount() {
        return mData == null ? 0 : mData.size();
    }

    @Override
    public int getItemViewType(int position) {
        if (position == 3 || position == 10) {
            return 1;
        }
        return 2;
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {

        CheckBox cbChange;
        TextView mTv;

        public ViewHolder(View itemView) {
            super(itemView);
            mTv = (TextView) itemView.findViewById(R.id.tv_coments);
            cbChange = (CheckBox) itemView.findViewById(R.id.cb_my);
        }
    }

}

~~~

//以下是在MainActiviy中的代码:
     private void initView() {
        mRecyclerView = (RecyclerView) findViewById(R.id.rv_list);
        // 设置布局管理器
        mRecyclerView.setLayoutManager(mLayoutManager);
       // 设置adapter
        mRecyclerView.setAdapter(mAdapter);
       // 设置Item添加和移除的动画
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());
        // 设置Item之间间隔样式
        mRecyclerView.addItemDecoration(new DividerItemDecoration(MainActivity.this, LinearLayoutManager.VERTICAL));
    }

    private void initData() {
        //设置布局管理器,控制布局效果
        mLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
        mAdapter = new MyAdapter(getData(),boolist);
    }

以上代码就是我们在之前介绍listview的项目中不同的地方,是实现同样的效果的,可以看下图(同样解决了内部复用是,选中状态失去的问题)

RecyclerView的demo.gif

public static abstract class LayoutManager {

官方介绍

代码中介绍

嘛的,说了一大堆,其实就是:
LayoutManager 只是一个抽象类而已,系统已经为我们提供了三个相关的实现类 LinearLayoutManager(线性布局效果)、GridLayoutManager(网格布局效果)、StaggeredGridLayoutManager(瀑布流布局效果)。如果你想用 RecyclerView 来实现自己的一种效果,则应该去继承实现自己的 LayoutManager,并重写相应的方法。

void addView(View child, int index) 
//根据索引在RecyclerView中添加子View。
void addView(View child) 
//添加子View。

int computeHorizontalScrollExtent(RecyclerView.State state) 
int computeHorizontalScrollOffset(RecyclerView.State state) 
int computeHorizontalScrollRange(RecyclerView.State state) 
int computeVerticalScrollExtent(RecyclerView.State state) 
int computeVerticalScrollOffset(RecyclerView.State state) 
int computeVerticalScrollRange(RecyclerView.State state) 
//官方API文档已经说的很清楚了,如果要实现scroll bar可能就需要复写以上的六个方法中的某一些。

//View findViewByPosition(int position) 
根据Adapter的位置查找RecyclerView的子View。

View getChildAt(int index) 
//根据索引获取子View。

int getChildCount() 
//获取RecyclerView的子View的个数。

int getHeight() 
int getWidth() 
//获取RecyclerView的高度和宽度的两个函数

int getItemCount() 
//获取Adapter中子项的个数

int getItemViewType(View view) 
//获取Adapter 中定义的子项的ViewType(子项View的类型),在RecyclerView中并没有ListView的head和footer的实现方法,这个方法也提供了head和footer的实现思路,在初始位置返回的ViewType为head,末尾位置返回的ViewType为footer,根据返回的ViewType的不同,我们可以去创建不同的子项的View和绑定不同的ViewHolder。

void moveView(int fromIndex, int toIndex) 
//移动一个View的位置到另一个View。

Parcelable onSaveInstanceState() 
//当需要保存LayoutManager的状态时调用。

void onScrollStateChanged(int state) 
//当滑动状态改变时RecyclerView调用这个方法去通知LayoutManager。

void removeAllViews() 
Remove all views from the currently attached RecyclerView. 
//移除当前依附在RecyclerView上的所有View。

void removeView(View child) 
//移除当前依附在RecyclerView上的一个子View。
void removeViewAt(int index) 
//根据索引移除当前依附在RecyclerView上的一个子View。

更多的看这里:
https://developer.android.google.cn/reference/android/support/v7/widget/RecyclerView.LayoutManager.html

  • listView和RecyclerView的api不同的对比:
    • listView直接自带setEmptyView()属性,当界面列表没有数据的时候,可以直接设置
    • RecyclerView没有自带的,当然你可以自定义一个;这里有个大神已经做过,他是这样实现的

    ————*———–

    • listView直接自带addFooterView() 和 addFooterView() 的api
    • RecyclerView中,我们在上面讲LayoutManager 的getItemViewType(View view)时候可以做出判断,绑定不同的布局,当然这样实现会有一些问题,有更好的实现方案,没得说,一定是这篇了: http://blog.csdn.net/lmj623565791/article/details/51854533

    ————*———–

    • lsitview的刷新相关 notifyDataSetChanged() ,调用简单,但是并不是每个item都需要重新绘制,造成了一定的资源浪费;

listView的刷新相关

  • RecyclerView的刷新相关,方法更多,notifyItemChanged(int position)可以只针对某个item刷新;

RecyclerView的刷新相关

————*———–
- listView的item加动画,我们只能自己通过属性动画来操作 Item 的视图,可以找别人封装的开源库,相对麻烦一些;
- RecyclerView的动画:系统也为我们提供了两个默认的动画实现:SimpleItemAnimator 和 DefaultItemAnimator。上面写到的mRecyclerView.setItemAnimator(new DefaultItemAnimator()),当然有特殊要求的可以找别人封装的开源库;

————*———–
- 还有就是listView的点击事件值得一提,adapter的内部外部都可以设置点击事件,但是RecyclerView的点击事件是需要我们自己定义的,可这完全不是问题,我们在最上面的代码中已经贴出了代码,不再重复了;

————*———–
- 另外重要的一点就是如果有的时候你需要配合AppBarLayout 、 CollapsingToolbarLayout 这种需要嵌套滚动的机制才能达到效果的控件,那么就选择 RecyclerView ,因为 ListView 内部吃掉了,不支持滚动机制NestedScrollingChild 。

**以上就是简单的RecyclerView的讲解,当然我们不是没有追求的人,我们怎么可以忍受代码这么乱,最基本的封装都没有,那就看这里:http://www.jianshu.com/p/2f2996ef2c75
我只想说,收下我的膝盖!**
- ### 综上所述,在分析项目需求的时候,根据不同的需求选择不同的列表,适当的扩展,合适就好
有兴趣的可以继续学习之前的系列篇:ListView系列详解

我的简书:http://www.jianshu.com/p/e8e61d6b0329

想交流,学习,提意见的可以关注以下的二维码:

公众号:君不见And

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值