recycleview

why recycleview ?  是ListView的更高度定制版,当你需要高效的展示大量数据时候,动态改变列表样式的时候,就用这个。

当然,如果只是动态展示数据,listview也可以做到,用它替代listview的原因有几个:

  1. 简介中提到的它封装了viewholder的回收复用。
  2. RecyclerView使用布局管理器管理子view的位置(目前尚只提供了LinearLayoutManager),你能够使用复杂的布局来展示一个列表 ,再不用拘泥于ListView的线性展示方式,如果之后提供其他custom LayoutManager的支持。

    StaggeredGridLayoutManager mStaggeredGridLayoutManager =
    new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
    //表示两列,并且是竖直方向的瀑布流
    mRecyclerView.setLayoutManager(mStaggeredGridLayoutManager);

    在布局上支持三种StaggeredGridLayoutManager(错列的), GridLayoutManager LinearLayoutManager

  3. 自带了ItemAnimation,可以设置加载和移除时的动画,方便做出各种动态浏览的效果。
  4. 分开的view 
    我们平时用listview的时候,adapter一般这么写的

    if (convertView == null) {
          holder = new ViewHolder();
           LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
           convertView = inflater.inflate(
                   R.layout.list_device_binding, parent, false);
    
           holder.deviceImage = (ImageView) convertView
                   .findViewById(R.id.bluetoothDeviceImage);
           holder.deviceName = (TextView) convertView
                   .findViewById(R.id.bluetoothDeviceName);
           holder.deviceType = (TextView) convertView
                   .findViewById(R.id.bluetoothDeviceType);
           convertView.setTag(holder);
       } else {
           holder = (ViewHolder) convertView.getTag();
       }
    

    但是,到了这里,他把他分隔开了,如下

    @Override
    public A onCreateViewHolder(ViewGroup parent, int viewType) {
        final View view = LayoutInflater.from(mContext).
              inflate(R.layout.listitem_track_history, parent, false);
        return new ViewHolder(view);
     }  
    
    @Override
    public void onBindViewHolder(A holder, int position) {
         Data da=getData(position);
        holder.tvDate.setText(da.getDate());
    }
    

    我们就再也不用像以前那样写了.

  5. 相对简单 
    我们看下Listview他背后的继承关系

    public class ListView extends AbsListView
    public abstract class AbsListView extends AdapterView<ListAdapter>
    public abstract class AdapterView<T extends Adapter> extends ViewGroup
    

    三重继承,内容还挺多的,不是直接继承ViewGroup,而相反的RecycleView却是直接继承自ViewGroup的。

缺点:

目前相对于我们对listview经常用到的方法,有下面两个问题:

1. 不能简单的加头和尾 header、footer

2. 不能简单的设置子item的点击事件。

具体的解决方案如下

  1. 不能简单的添加Head和Footer 
    在使用过程中,你发现你要添加头和尾不是很容易,因为没有直接的addHead和addFoot的方法了,不过这里有一个tumblr开源的库,可以让你实现这个功能,核心的代码如下

     @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        if (isHeader(viewType)) {
            int whichHeader = Math.abs(viewType - HEADER_VIEW_TYPE);
            View headerView = mHeaders.get(whichHeader);
            return new RecyclerView.ViewHolder(headerView) { };
        } else if (isFooter(viewType)) {
            int whichFooter = Math.abs(viewType - FOOTER_VIEW_TYPE);
            View footerView = mFooters.get(whichFooter);
            return new RecyclerView.ViewHolder(footerView) { };
    
        } else {
            return mBase.onCreateViewHolder(viewGroup, viewType);
        }
    }
    
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
            if (position < mHeaders.size()) {
                // Headers don‘t need anything special
        } else if (position < mHeaders.size() + mBase.getItemCount()) {
            // This is a real position, not a header or footer. Bind it.
            mBase.onBindViewHolder(viewHolder, position - mHeaders.size());
        } else {
            // Footers don‘t need anything special
        }
    }
    
    @Override
    public int getItemViewType(int position) {
        if (position < mHeaders.size()) {
            return HEADER_VIEW_TYPE + position;
    
    } else if (position < (mHeaders.size() + mBase.getItemCount())) {
        return mBase.getItemViewType(position - mHeaders.size());
    
    } else {
        return FOOTER_VIEW_TYPE + position - mHeaders.size() - mBase.getItemCount();
    }
    
  2. 不能简单的添加点击事件onListItemClickListener 
    我们在使用listview设置子item的点击事件的时候,只需要像下面这么写
    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
           @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    
               User user= parent.getItemAtPosition(position);
            }
    });
    

    但是,如果你使用这个RecycleView,会发现没有这个接口了。RecyclerView不再负责Item视图的布局及显示,所以RecyclerView也没有为Item开放OnItemClick等点击事件,这就需要我们自己实现,实现的方法像看到有三种,目前下面这种比较合理,所以推荐如下写法

    1. 让你的viewholder实现onClickListener,然后在这个方法里面回调我们自己写的接口。

      public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
      
          private TextView tvDate;             
      
          public ViewHolder(View itemView) {
              super(itemView);
              tvDate = (TextView) itemView.findViewById(R.id.tv_date);
              itemView.setOnClickListener(this);
          }
      
          @Override
          public void onClick(View v) {
              if(listener!=null){
                  listener.onItemClick(getPosition(),mList.get(getPosition()));
              }
          }
      }
      
      //我们回调的自定义接口
      public  interface  onListItemClickListener{
          void onItemClick(int position,TrackHistory mTrackHistory);
      }
      
    2. 接着在你的Adapter里面加多个set方法,里面设置回调接口
      public  void setOnItemClickListener(onListItemClickListener listener){
          this.listener = listener;
      }
      

小结

从上面的简单比较,对于我而言如果不是最求很高的效率,我不选择用这个,确实有点不方便了

时间: 2024-11-14 04:50:41

recycleview的相关文章

IAdjustCountOption--动态设置recycleView的itemCount(不需要修改数据源)

概述RecycleViewUtil是新增的一个主要针对RecycleView的一个工具类.该工具类中提供了部分方法用来增强HeaderRecycleAdapter功能的扩展方法. 包括动态计算均分RecycleView的界面从而显示childView的功能,可随意调整itemCount的功能(不影响数据源) 概述 RecycleViewUtil是新增的一个主要针对RecycleView的一个工具类.该工具类中提供了部分RecycleView可能会使用到的方法,其中也包括了一些用来增强Header

RecycleView + CardView 控件简析

今天使用了V7包加入的RecycleView 和 CardView,写篇简析. 先上效果图: 原理图: 这是RecycleView的工作原理: 1.LayoutManager用来处理RecycleView的“列表”样式,Support包默认包含了:LinearLayoutManager  横向或纵向的滚动列表. GridLayoutManager  网格列表.StaggeredGridLayoutManager  交错的网格列表. 2.Adapter负责处理RecycleView的数据和样式 3

RecycleView的使用(一)(转)

最近,笔者花了很多时间学习了一些Google官方推荐的RecycleView的用法,发现相比于原来的ListView,RecycleView的功能实在是太强大,很值得大家去学习一下. 基本的使用 我们就不讲如何导入包什么的了吧,我们直接进入主题. xml <android.support.v7.widget.RecyclerView android:id="@+id/recycleview" android:layout_width="match_parent"

recycleView 使用指南1

最近看了很多 recycleView 的使用文章,一直晕乎乎的,完全不知道套路是啥.很多人都是直接上代码,但是却没有详细说明代码的使用,于是打算自己写写,理理思路.顺便帮助那些正在学习 android 的新人. 本文源码参见  https://github.com/huanshen/Learn-Android/tree/master/recycleTest 1.单个 item 的 recycleView 首先 recycleView 需要我们引入,所以在 build.gradle ( model

安卓开发笔记 RecycleView (三)

创建RecycleView的步骤: 在Layout中创建RecycleView 创建List Item 和 ViewHolder 添加RecycleView 适配器 添加LayoutManager 和 将所有事情连接起来. 练习一:RecycleView 布局 第一 步:在app/build.gradle(Module:app)文件中添加依赖 dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com

RecycleView在eclipse的初体验

在sdk中找到v7包 \sdk\extras\android\support\v7\recyclerview 导入工程 Import\Android\Existing Android Code Into Workspace 将导入的recycleview作为依赖库Library 工程上右键properties,勾选is Library,Apply,ok 将recycleview\libs\android_support_v7_recycleview.jar包复制粘贴到主工程的libs文件夹下 在

RecycleView 实现多布局

最近的一个新需求,简单描述下吧: 需求: 目标样式如图所示,我们需要根据需求动态添加网关和设备. 目标有了下面就是怎么实现了.首先我们选用的是RecycleView 那么主要目标就成了 在recycleView下如何实现多布局(我们看到网关和设备的布局不同) 首先写两个布局(一个网关 , 一个设备) 网关布局样式: 设备布局样式: 这些都比较简单,在这里就不赘述. RecycleView的基本用法: 1)引入包 2)在布局中使用控件 3)在activity中绑定并使用recycleView 4)

Android Studio第十三期 - RecycleView所有用法

综合了一下hongyang和loader的RecycleView的所有场景用法: 1.ListView列表分页用法核心代码: private void createAdapter(){     mAdapter = new RecycleAdapter1(this);     LinearLayoutManager mLinearLayoutManager1 = new LinearLayoutManager(this);     mLinearLayoutManager1.setOrienta

RecycleView的使用(一)

RecycleView是Android5.0推出的用来替代ListView和GridView的控件. 使用RecycleView也很简单,不过需要先引入support-v7中的RecycleView. 在eclipse中的引入方法就要小伙伴自己去百度了,由于楼主用的是Android Studio 所以这里贴下Android Studio的引入方法: RecycleView的引入 : File ->Project Structure 可以看到这个弹出框: 选项卡选择到Dependencies(图中