RecyclerView-Adapter系列简述(第1篇)

从这篇文章文章开始将会连载几篇文章简单描述下最近抽空针对RecyclerViewAdapter做的一个扩展库。系列文章是对扩展库逐步进行扩展的,有一定的先后关系,所以阅读的话还是按照这个顺序比较好。

这篇先不开始描述怎么去扩展,先说一下这个扩展库将拥有什么样的功能以及如何使用,也就是告诉读者这些功能是不是符合口味,能不能吸引再往下读。
该库github地址:
https://github.com/yangxiaoweihn/RecyclerViewAdapter

该系列内容已经完结,其他部分可以点击下列阅读:
RecyclerView-为Adapter添加头部、尾部及事件响应(第2篇)
RecyclerView-数据域的操作方法(第3篇)
RecyclerView-为Adapter增加滑动菜单支持(第4篇)
RecyclerView-为Adapter增加粘性头部支持(第5篇)

本篇主要描述以下几方面内容:

  1. 扩展库如何在项目中使用
  2. 扩展库具有的功能
  3. 贴图看看效果
  4. 扩展库的api使用说明

扩展库的使用

该库已经打包上传到了mavenjcenter仓库,使用Android Studio开发的同学肯定都知道怎么从仓库引入库的。
特殊注意:另外,这系列文章是针对源码版本2.0描述的

    compile 'ws.dyt.view:recyclerview-adapter-hf:2.0'

具有的功能

  1. 可以添加、删除任意数量的头部、尾部(就像ListView那样)
  2. 可以添加系统头部、尾部(数量和使用上做了限制,在使用上尽量不要去使用这部分),具体说明将会在之后的文章中进行阐述。
  3. 可以针对不同的item添加滑动菜单(目前只支持左滑、右滑),并且菜单定制性高
  4. 支持粘性视图,同时支持滑动菜单

效果图

在能让读者有足够的好奇心读以下的文章前,先贴几张效果图,拿效果图最能说明该库拥有的功能。

1.png
2.png
3.png
4.png
5.png
6.png
7.png

好了,效果图已经贴完,如果觉得这些功能不够吸引的话,同学就可以止步了,因为只有得系列文章主要是为了阐述以上功能的开发过程及思路。

api使用说明

首先要说明一点:该api的使用与系统原生提供的有区别,不要思维定式。简单说起来就是使用更简单,大概姿势如下:
1. 构造(构造方法)
2. 数据绑定
3. 多类型支持(设置布局,如果需要的话)
4. 事件
5. 添加头部尾部控件
6. 横跨列处理
7. 添加菜单
8. 添加粘性头部

该库主要实现了两个具有一定功能的Adapter,命名为SuperAdapterSuperPinnedAdapter。从实现上来讲,SuperPinnedAdapter间接继承自SuperAdapter,所以功能上就不言而喻了。
SuperAdapter具有添加头部尾部、以及滑动菜单功能,而SuperPinnedAdapter在此基础上增加了粘性视图的支持。

通过构造方法进行初始化(具体的参数说明请看注释)

/** 
    * 调用该构造方法时需要调用 {@link #getItemViewLayout(int)} 设置item布局 
    * @param context 
    * @param datas 
    */
  public SuperAdapter(Context context, List<T> datas) {
      super(context, datas);
  }
  /** 
    * 调用该构造方法时默认数据项都采用 itemLayoutResId 布局,同样可以调用 {@link #getItemViewLayout(int)} 重新设置item布局 
    * @param context 
    * @param datas 
    * @param itemLayoutResId 
    */
public SuperAdapter(Context context, List<T> datas, @LayoutRes int itemLayoutResId) {    
      this(context, datas);
}

以上两个构造方法最大的区别是:用第一种方法构造后需要调用getItemViewLayout()设置item的布局。用后一种的话已经设置了item布局,不过这种方式是所有的item布局都是一样的。

数据绑定

数据的绑定在原生里是onBindViewHolder(),而在这里,将该方法进行了屏蔽,而是用convert()方法(使用上与onBindViewHolder()一致,但是也更简单),可以简单的将他俩看成是对等的关系,但是事实上不是这样的,具体的我将会在后续的文章中进行具体描述。

  /** 
    * 绑定数据 
    * @param holder 
    * @param position  数据域从0开始,已经除去头部       
    */
  abstract
  public void convert(BaseViewHolder holder, int position);

该方法的第一个参数该库做了进一步封装,具体来说就是整个库里BaseViewHolder类无法被扩展,所有常用的操作方法已经在该类中进行了封装(后续版本在决定是否可以允许该类扩展),BaseViewHolder的功能将会在后面的文章进行描述。BaseViewHolder的链条操作:

  //只是一个例子而已,旨在说明链条操作,不必注意实体类是什么
  CourseResult.Course e = getItem(position).data;
  holder.
      setText(R.id.tv_name, e.name).
      setText(R.id.tv_length, e.length);

多item支持

通过构造方法已经知道,用构造方法是没有办法设置Adapter的多item样式支持的。那么在该库中,通过以下方法进行设置:

  /**  
    * 提供item对应的布局 
    */
public int getItemViewLayout(int position) {}

事件

网上一大片文章都在讲RecyclerView怎么设置item的点击事件云云,事实上确实很简单,RecyclerView暴露的方法就那么几个,所以在这里事件是怎么加上去的也将在后续的文章中阐述,这里只需要知道该库一定也提供了设置事件监听的方法。
对item的点击事件支持以下两种:

  /** 
    * 点击事件 
    */
  public interface OnItemClickListener {    
      void onItemClick(View itemView, int position);
  }
  /** 
    * 长按事件 
    */
  public interface OnItemLongClickListener {    
      void onItemLongClick(View itemView, int position);
  }

设置监听器:

  //设置点击事件
  adapter.setOnItemClickListener(new SuperAdapter.OnItemClickListener() {    
      @Override    
      public void onItemClick(View itemView, int position) {     
      }
});
  //设置长按事件
  adapter.setOnItemLongClickListener(new SuperAdapter.OnItemLongClickListener() {    
      @Override    
      public void onItemLongClick(View itemView, int position) {     
      }
});

添加头部、尾部控件

原生RecyclerView并没有提供像ListView中那样可以随意添加header和footer的api,但是在实际的场景中我们确实需要这样的功能,那么该库也一定提供了这样的方法。
首先需要简单说一下SuperAdapter数据域的构成:

  {
      item_sys_header - item_header - 
      item_data - 
      item_footer - item_sys_footer
  }
从上面的结构中可以看到,大体分为3中(header部分、数据部分、footer部分),细分的话,头部又分为系统header部分(item_sys_header)和用户header部分(item_header),footer部分分为系统footer部分(item_footer)和用户footer部分(item_sys_footer)。
我为什么要这么划分呢,在实现上是有一些考虑的,头部和尾部不要去污染数据部分(分离),这样在扩展上更好一些。一般在使用时系统header和系统footer可以忽略,加这两个的用途也是为了扩展用,比如在我的另外一个上拉加载库中就用了系统footer。

主要提供了一下几个api:

final
public void addHeaderView(View view);
final
public void addHeaderView(View view, boolean changeAllVisibleItems);
final
public void removeHeaderView(View view);
final
public void removeHeaderView(View view, boolean changeAllVisibleItems);
final
public void addFooterView(View view);
final
public void addFooterView(View view, boolean changeAllVisibleItems);
final
public void removeFooterView(View view);
final
public void removeFooterView(View view, boolean changeAllVisibleItems);

其中changeAllVisibleItems表示是否只刷新可见区域(为true时),否则只刷新当前发生变化的item,默认为false

横跨列的api

RecyclerView的布局管理器是GridLayoutManager或者StaggeredGridLayoutManager时,有些item需要横跨所有列,这种情况下我们也提供了以下api去设置,默认为false,表示保持管理器设置,为true时表示横跨。

/**
 * 设置是否横跨
 * @param position
 * @return
 */
protected boolean isFullSpanWithItemView(int position) {
    return false;
}

添加菜单及菜单事件

public List<MenuItem> onCreateMultiMenuItem(int viewType) {
    List<MenuItem> mm = new ArrayList<>();
    mm.add(new MenuItem(R.layout.menu_item_test_delete, MenuItem.EdgeTrack.RIGHT, 01));
    mm.add(new MenuItem(R.layout.menu_item_test_mark, MenuItem.EdgeTrack.RIGHT, 02));
    return mm;
}
@Override
public boolean isCloseOtherItemsWhenThisWillOpen() {
    return true;}adapter.setOnItemMenuClickListener(new OnItemMenuClickListener() {
    @Override
    public void onMenuClick(SwipeLayout swipeItemView, View itemView, View menuView, int position, int menuId) {
        if (menuId == 01) {
            swipeItemView.closeMenuItem();
            Log.d("DEBUG", "--menu: 删除 -> position: " + position + " , menuId: " + menuId);
            Toast.makeText(getContext(), "删除", Toast.LENGTH_SHORT).show();
        } else if (menuId == 02) {
            Log.d("DEBUG", "--menu: 关注 -> position: " + position + " , menuId: " + menuId);
            Toast.makeText(getContext(), "加关注", Toast.LENGTH_SHORT).show();
        }
    }
});

添加粘性头部及数据绑定

注意粘性头部的AdapterPinnedAdapter.

@Override
public int getPinnedItemViewLayout() {
    return R.layout.item_pinned;
}
@Override
public void convertPinnedHolder(BaseViewHolder holder, int position, int type) {
    holder.setText(R.id.tv_text_pinned, getItem(position).data.title);
}

概括的介绍就到这里。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,566评论 25 707
  • 内容抽屉菜单ListViewWebViewSwitchButton按钮点赞按钮进度条TabLayout图标下拉刷新...
    皇小弟阅读 46,415评论 22 663
  • 我终于等到这年夏天,阳光将万物都涂抹上灿灿的光,碧蓝的天空却把人卷进无尽的虚无。游乐场中人们尖叫、打闹。笑声像...
    绚烂的小哈阅读 443评论 0 2
  • 大清早上的,脑子懵懵的。做了2012年12月真题的听力,严重怀疑自己是不是把脑子丢进太平洋了! 第一大题错2个,第...
    诺凡阅读 346评论 4 1
  • 首先,严把产品的质量 商家在运营社群时,首先要清楚了解产品或者服务的亮点,同时多与社群成员交流互动,从交流中寻找提...
    qzuser_6e42阅读 512评论 0 0