recycleview实现分组列表

https://blog.csdn.net/csdn576038874/article/details/77648366

最近看到diycodeAPP中一个列表分组界面,起初是用listview嵌套gridview实现的,效果一样只是有些复杂,但是后来看了下源码,是用recycleview实现的,并且还很简单,

最后就尝试了一下,实现了这个列表功能,所以在这里记录一下,方便以后遇到类似功能,直接可以拿来使用,这里感谢一下diycode的API以及实体类,为了方便接口和实体类直接用diycode的,API:https://diycode.cc/api/v3/sites.json

看下效果图吧

image

1、实体类

[java] view plaincopy

  1. public class Sites implements Serializable {

  2. private String name;

  3. private int id;

  4. private List sites;

  5. public String getName() {

  6. return name;

  7. }

  8. public void setName(String name) {

  9. this.name = name;

  10. }

  11. public int getId() {

  12. return id;

  13. }

  14. public void setId(int id) {

  15. this.id = id;

  16. }

  17. public List getSites() {

  18. return sites;

  19. }

  20. public void setSites(List sites) {

  21. this.sites = sites;

  22. }

  23. public static class Site implements Serializable {

  24. /**

    • name : botlist
    • url : http://botlist.co
    • avatar_url : https://favicon.b0.upaiyun.com/ip2/botlist.co.ico
  25. */

  26. private String name;

  27. private String url;

  28. private String avatar_url;

  29. public String getName() {

  30. return name;

  31. }

  32. public void setName(String name) {

  33. this.name = name;

  34. }

  35. public String getUrl() {

  36. return url;

  37. }

  38. public void setUrl(String url) {

  39. this.url = url;

  40. }

  41. public String getAvatar_url() {

  42. return avatar_url;

  43. }

  44. public void setAvatar_url(String avatar_url) {

  45. this.avatar_url = avatar_url;

  46. }

  47. }

  48. }

2、适配器

[java] view plaincopy

  1. /**

    • @ProjectName: DiycodeApp
    • @PackageName: com.wenjie.diycode.adapter
    • @FileName: com.wenjie.diycode.adapter.SitesAdapter.java
    • @Author: wenjie
    • @Date: 2017-08-17 14:57
    • @Description:
    • @Version:
  2. */

  3. public class SitesAdapter extends RecyclerView.Adapter{

  4. public static final int SITES = 0;//标题 跨一列 也就是合并两列

  5. public static final int SITE = 1;//不跨列

  6. //所有数据的集合,将标题和数据项,全部装在到这个集合中,在适配器中利用viewtype来区分,并显示不同的布局

  7. private List items = new ArrayList<>();

  8. private Context context;

  9. public SitesAdapter(Context context, List items) {

  10. this.items = items;

  11. this.context = context;

  12. }

  13. @Override

  14. public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

  15. LayoutInflater mInflater = LayoutInflater.from(context);//获取mInflater对象

  16. switch (viewType) {//根据viewtyupe来区分,是标题还是数据项

  17. case SITES://标题,加载显示标题的item布局,就一个textview显示文本,这里我们自顶一个标题的viewholder->SitesHolder

  18. final SitesHolder sitesHolder = new SitesHolder(mInflater.inflate(R.layout.item_sites, parent, false));

  19. //点击事件

  20. sitesHolder.itemView.setOnClickListener(new View.OnClickListener() {

  21. @Override

  22. public void onClick(View view) {

  23. if(onItemClickListener != null){

  24. onItemClickListener.onClick(sitesHolder.itemView , sitesHolder.getLayoutPosition());

  25. }

  26. }

  27. });

  28. return sitesHolder;

  29. case SITE://数据项,雷同不赘述了,标题和数据项的item布局和veiwholder都不会相互影响的

  30. final SiteHolder siteHolder = new SiteHolder(mInflater.inflate(R.layout.item_site, parent, false));

  31. siteHolder.itemView.setOnClickListener(new View.OnClickListener() {

  32. @Override

  33. public void onClick(View view) {

  34. if(onItemClickListener != null){

  35. onItemClickListener.onClick(siteHolder.itemView , siteHolder.getLayoutPosition());

  36. }

  37. }

  38. });

  39. return siteHolder;

  40. }

  41. return null;

  42. }

  43. @Override

  44. public int getItemViewType(int position) {

  45. //这个方法很重要,这里根据position取出items集合中的对象,用instanceof判断他是标题还是数据项,来返回对应的标识

  46. if (items.get(position) instanceof Sites) {//根据items数据类型的不同来判断他是标题还是数据项

  47. return SITES;//标题

  48. } else if (items.get(position) instanceof Sites.Site) {

  49. return SITE;//数据项

  50. } else {

  51. return -1;

  52. }

  53. }

  54. @Override

  55. public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {

  56. //根据getItemViewType绑定view进行赋值显示

  57. switch (holder.getItemViewType()) {

  58. case SITES://标题

  59. SitesHolder sitesHolder = (SitesHolder) holder;

  60. sitesHolder.name.setText(((Sites) items.get(position)).getName());

  61. break;

  62. case SITE://数据项

  63. SiteHolder siteHolder = (SiteHolder) holder;

  64. siteHolder.name.setText(((Sites.Site) items.get(position)).getName());

  65. Glide.with(context).load(((Sites.Site) items.get(position)).getAvatar_url()).into(siteHolder.icon);

  66. break;

  67. }

  68. }

  69. /**

    • 公布点击事件出去
  70. */

  71. private OnItemClickListener onItemClickListener;

  72. public void setOnItemClickListener(OnItemClickListener onItemClickListener){

  73. this.onItemClickListener = onItemClickListener;

  74. }

  75. public interface OnItemClickListener{

  76. void onClick(View itemview , int position);

  77. }

  78. @Override

  79. public int getItemCount() {

  80. return items.size();

  81. }

  82. /**

    • 数据项的viewholder 一个文本textview一个cion imageview
  83. */

  84. private class SiteHolder extends RecyclerView.ViewHolder {

  85. TextView name;

  86. ImageView icon;

  87. SiteHolder(View itemView) {

  88. super(itemView);

  89. name = (TextView) itemView.findViewById(R.id.name);

  90. icon = (ImageView) itemView.findViewById(R.id.icon);

  91. }

  92. }

  93. /**

    • 标题的viewholder 只有一个textview
  94. */

  95. private class SitesHolder extends RecyclerView.ViewHolder {

  96. TextView name;

  97. SitesHolder(View itemView) {

  98. super(itemView);

  99. name = (TextView) itemView.findViewById(R.id.name);

  100. }

  101. }

  102. }

  103. 接下来就是 当数据获取成功之后,如何和适配器进行绑定显示

    sites就是从获取获取到了并解析好的数据集合

    [java] view plaincopy

    1. List items = new ArrayList<>();

    2. //数据获取之后 将数据循环遍历,放进items集合中,至于服务器返回什么格式的数据,我想看下实体类就应该明白了

    3. for (int i=0; i < sites.size(); i++){

    4. items.add(sites.get(i));

    5. for(int k = 0; k < sites.get(i).getSites().size(); k ++){

    6. items.add(sites.get(i).getSites().get(k));

    7. }

    8. }

    9. //实例化适配器将遍历好的数据放进适配器中

    10. sitesAdapter = new SitesAdapter(getActivity() ,items);

    11. //new一个布局管理器,这里是用GridLayoutManager,要区分3列

    12. GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity() , 3);//多少列,如果数据项只需要1列,这里写1,下面return 也返回1即可实现

    13. //下面这个方法很重要,根据position获取当前这条数据是标题还是数据项,来设置他的跨列

    14. gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {

    15. @Override

    16. public int getSpanSize(int position) {

    17. //适配器中有这么一个方法,根据position获取当前这条数据是标题还是数据项,来设置他的跨列

    18. switch (sitesAdapter.getItemViewType(position)){

    19. case SitesAdapter.SITES://标题的话跨多少列 这个值要跟整个列数相等 如果大于会出错,小于布局会乱

    20. return 3;

    21. case SitesAdapter.SITE://数据项

    22. return 1;//不跨列,就是分成三列显示

    23. default:

    24. return -1;

    25. }

    26. }

    27. });

    28. sitesRecycleView.setLayoutManager(gridLayoutManager);

    29. // sitesRecycleView.addItemDecoration(new DividerItemDecoration(getActivity() , GridLayoutManager.VERTICAL));

    30. sitesRecycleView.setAdapter(sitesAdapter);

    31. //item的点击事件,这里实现,进行具体的操作

    32. sitesAdapter.setOnItemClickListener(new SitesAdapter.OnItemClickListener() {

    33. @Override

    34. public void onClick(View itemview, int position) {

    35. switch (sitesAdapter.getItemViewType(position)){

    36. case SitesAdapter.SITE:

    37. // ToastUtils.showToast(getActivity() , ((CoolSites.Site) items.get(position)).getName());

    38. Intent intent = new Intent(getActivity() , WebViewActivity.class);

    39. intent.putExtra("url" , ((Sites.Site) items.get(position)).getUrl());

    40. startActivity(intent);

    41. break;

    42. case SitesAdapter.SITES:

    43. ToastUtils.showToast(getActivity() , ((Sites) items.get(position)).getName());

    44. break;

    45. }

    46. }

    47. });

    48. 你可能感兴趣的:(recycleview实现分组列表)