logo
当前位置:首 页 > 移动开发 >android > 查看文章

转自:JonesYang

ListView 相关

ListView 是什么?(上古神器)不,是不是该问 RecyclerView 是什么?(也是上古神器?在它的替代品出来之前最好别这样称呼)趁着这段时间,我想我也应该把这些乱七八糟的东西整理一下。

OK,不演了,ListView 和 RecyclerView 都是用来展示列表数据了。相比与 ListView ,RecyclerView 更加强大,下面先说 ListView。

ListView 适配器

关于 ListView 先简单看一下它的适配器代码:

public class ListViewAdapter extends BaseAdapter {
    //用于加载 item    private LayoutInflater mInflater;    //通过构造函数 把 Context 传递进来    public ListViewAdapter(Context context) {        mInflater = LayoutInflater.from(context);    }
    /**     * 获取的数据存储在这个集合中,一般来说这个集合中存储了子项的 item     */    private List mList = new ArrayList();
    /**     * @return 返回集合的大小     */    @Override    public int getCount() {        return mList.size();    }
    /**     * @param position     * @return 返回具体的 item     */    @Override    public Object getItem(int position) {        return mList.get(position);    }
    @Override    public long getItemId(int position) {        return position;    }
    /**     * 作用:加载 子项 item 的布局     *     * @param position    item 的位置     * @param convertView item 进行复用,避免一个 item 发生多次加载的情况     * @param parent      父容器,根据具体的情况而定     * @return item     */    @Override    public View getView(int position, View convertView, ViewGroup parent) {        if (convertView == null){            convertView = mInflater.inflate(R.layout.activity_detail,parent,false);        }        //对 item 进行复用,返回 convertView        return convertView;    }}

ListView 的优化

可以看到,基本上每一个 item 都需要在 getView() 中加载,如果 item 的数量过多,就会产生性能问题,影响用户体验。这个时候我们就需要使用 ViewHolder(开发者自定义类),这是 ListViewAdapter 的内部类,它的代码如下:

    /**     * 作用:加载 子项 item 的布局     *     * @param position    item 的位置     * @param convertView item 进行复用,避免一个 item 发生多次加载的情况     * @param parent      父容器,根据具体的情况而定     * @return item     */    @Override    public View getView(int position, View convertView, ViewGroup parent) {        ViewHolder holder = null;        if (convertView == null){            holder = new ViewHolder();            convertView = mInflater.inflate(R.layout.activity_detail,parent,false);            convertView.setTag(holder);        } else {          如果 convertView 不为空,直接进行复用            holder = (ViewHolder) convertView.getTag();        }        //对 item 进行复用,返回 convertView        return convertView;    }  //这是一个内部类    private class ViewHolder{        //获取 item 的控件都定义在这里    }

好了,关于 ListView 就到这里了,下面总结两个关键点:

  • 自定义 ListViewAdapter ,继承 BaseAdapter。
  • 自定义 ViewHolder 和 convertView 一起完成复用优化工作。

RecyclerView 相关

下面开始写 RecyclerView ,先把 RecyclerView 的关键点总结在这里。其实和 ListView 是差不多的,主要有两条:

  • RecyclerViewAdapter 继承 Recyclerview.Adapter ,其内部类 ViewHolder 继承 RecyclerView.ViewHolder。
  • 设置布局管理器,控制布局效果

RecyclerView 适配器

先看下面 RecyclerView 适配器的代码:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
    /**     * 这个方法主要生成为每个Item inflater出一个View,但是该方法返回的是一个ViewHolder。     * 该方法把View直接封装在ViewHolder中,然后我们面向的是ViewHolder这个实例,     * 当然这个ViewHolder需要我们自己去编写。     *     * @param parent     * @param viewType     * @return viewHolder     */    @NonNull    @Override    public RecyclerViewAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {        return null;    }
    /**     * 这个方法主要用于适配渲染数据到View中,     * 方法提供给你了一viewHolder而不是原来的convertView     *     * @param holder     * @param position     */    @Override    public void onBindViewHolder(@NonNull RecyclerViewAdapter.ViewHolder holder, int position) {        //在这里更新 UI    }
    /**     * @return 返回 item 的数量     */    @Override    public int getItemCount() {        return 0;    }
    public class ViewHolder extends RecyclerView.ViewHolder {        public ViewHolder(@NonNull View itemView) {            super(itemView);        }    }}

从基础使用上看,我们明显可以看出,RecyclerView 相比 ListView 在基础使用上的区别主要有如下几点:

  • ViewHolder 的编写规范化了。
  • RecyclerView 复用 item 的工作 Google 全帮你搞定了,不需要再像 ListView 那样自己调用 setTag()。
  • RecyclerView 需要设置 KayoutManager

如何在 Activity 中使用 RecyclerView

接下来看一下如何在 Activity 中使用 RecyclerView :(ListView 大致相同)

        //1、设置布局管理器        LinearLayoutManager manager = new LinearLayoutManager(this);        RecyclerView recyclerView = findViewById(R.id.detail_rv);        recyclerView.setLayoutManager(manager);        //2、设置适配器        RecyclerViewAdapter adapter = new RecyclerViewAdapter();        recyclerView.setAdapter(adapter);

RecyclerView 的布局管理器

关于 RecyclerView ,还得再说一下它的布局管理器,RecyclerView 提供了三种布局管理器可供选择:

  • LinerLayoutManager 以垂直或者水平列表方式展示
  • GridLayoutManager 以网格方式展示item
  • StaggeredGridLayoutManager 以瀑布流方式展示Item

之所以说 RecyclerView 更加强大,也正是因为 RecyclerView 提供了多种布局管理器,只需在 Activity 中进行设置即可。另外,关于布局管理器的一些API如下:

    canScrollHorizontally();//能否横向滚动    canScrollVertically();//能否纵向滚动    scrollToPosition(int position);//滚动到指定位置
    setOrientation(int orientation);//设置滚动的方向    getOrientation();//获取滚动方向
    findViewByPosition(int position);//获取指定位置的Item View    findFirstCompletelyVisibleItemPosition();//获取第一个完全可见的Item位置    findFirstVisibleItemPosition();//获取第一个可见Item的位置    findLastCompletelyVisibleItemPosition();//获取最后一个完全可见的Item位置    findLastVisibleItemPosition();//获取最后一个可见Item的位置

RecyclerView 的分割线

我们可以为 REcyclerview 的 item 绘制分割线,用系统已经定义好的分割线:

//添加分割线myRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));

同样,我们也可以定义自己的分割线,实现不同的效果:

自定义间隔样式需要继承RecyclerView.ItemDecoration类,该类是个抽象类,官方目前并没有提供默认的实现类,主要有三个方法。

  • onDraw(Canvas c, RecyclerView parent, State state),在Item绘制之前被调用,该方法主要用于绘制间隔样式。
  • onDrawOver(Canvas c, RecyclerView parent, State state),在Item绘制之前被调用,该方法主要用于绘制间隔样式。
  • getItemOffsets(Rect outRect, View view, RecyclerView parent, State state),设置item的偏移量,偏移的部分用于填充间隔样式,即设置分割线的宽、高;在RecyclerView的onMesure()中会调用该方法

– EOF –

说说梦想,谈谈感悟 ,聊聊技术,有啥要说的来github留言吧 https://github.com/cjx2328

—— 陈 建鑫

陈建鑫
你可能也喜欢Related Posts
footer logo
未经许可请勿自行使用、转载、修改、复制、发行、出售、发表或以其它方式利用本网站之内容。站长联系:cjx2328#126.com(修改#为@)
Copyright ©ziao Studio All Rights Reserved. E-mail:cjx2328#126.com(#号改成@) 沪ICP备14052271号-3