recycleview實現(xiàn)分組列表

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

最近看到diycodeAPP中一個列表分組界面,起初是用listview嵌套gridview實現(xiàn)的,效果一樣只是有些復雜,但是后來看了下源碼,是用recycleview實現(xiàn)的,并且還很簡單,

最后就嘗試了一下,實現(xiàn)了這個列表功能,所以在這里記錄一下,方便以后遇到類似功能,直接可以拿來使用,這里感謝一下diycode的API以及實體類,為了方便接口和實體類直接用diycode的,API:https://diycode.cc/api/v3/sites.json

看下效果圖吧

image

1、實體類

[java] view plaincopy

<embed id="ZeroClipboardMovie_1" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="16" height="16" name="ZeroClipboardMovie_1" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=1&width=16&height=16" wmode="transparent" style="box-sizing: border-box;">

  1. public class Sites implements Serializable {

  2. private String name;

  3. private int id;

  4. private List<Site> 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<Site> getSites() {

  18. return sites;

  19. }

  20. public void setSites(List<Site> sites) {

  21. this.sites = sites;

  22. }

  23. public static class Site implements Serializable {

  24. /**

    • name : botlist
  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

<embed id="ZeroClipboardMovie_2" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="16" height="16" name="ZeroClipboardMovie_2" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=2&width=16&height=16" wmode="transparent" style="box-sizing: border-box;">

  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<RecyclerView.ViewHolder>{

  4. public static final int SITES = 0;//標題 跨一列 也就是合并兩列

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

  6. //所有數(shù)據(jù)的集合,將標題和數(shù)據(jù)項,全部裝在到這個集合中,在適配器中利用viewtype來區(qū)分,并顯示不同的布局

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

  8. private Context context;

  9. public SitesAdapter(Context context, List<Object> 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) {//根據(jù)viewtyupe來區(qū)分,是標題還是數(shù)據(jù)項

  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://數(shù)據(jù)項,雷同不贅述了,標題和數(shù)據(jù)項的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. //這個方法很重要,這里根據(jù)position取出items集合中的對象,用instanceof判斷他是標題還是數(shù)據(jù)項,來返回對應的標識

  46. if (items.get(position) instanceof Sites) {//根據(jù)items數(shù)據(jù)類型的不同來判斷他是標題還是數(shù)據(jù)項

  47. return SITES;//標題

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

  49. return SITE;//數(shù)據(jù)項

  50. } else {

  51. return -1;

  52. }

  53. }

  54. @Override

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

  56. //根據(jù)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://數(shù)據(jù)項

  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. /**

    • 數(shù)據(jù)項的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. }

接下來就是 當數(shù)據(jù)獲取成功之后,如何和適配器進行綁定顯示

sites就是從獲取獲取到了并解析好的數(shù)據(jù)集合

[java] view plaincopy

<embed id="ZeroClipboardMovie_3" src="https://csdnimg.cn/public/highlighter/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="16" height="16" name="ZeroClipboardMovie_3" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=3&width=16&height=16" wmode="transparent" style="box-sizing: border-box;">

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

  2. //數(shù)據(jù)獲取之后 將數(shù)據(jù)循環(huán)遍歷,放進items集合中,至于服務器返回什么格式的數(shù)據(jù),我想看下實體類就應該明白了

  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. //實例化適配器將遍歷好的數(shù)據(jù)放進適配器中

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

  11. //new一個布局管理器,這里是用GridLayoutManager,要區(qū)分3列

  12. GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity() , 3);//多少列,如果數(shù)據(jù)項只需要1列,這里寫1,下面return 也返回1即可實現(xiàn)

  13. //下面這個方法很重要,根據(jù)position獲取當前這條數(shù)據(jù)是標題還是數(shù)據(jù)項,來設置他的跨列

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

  15. @Override

  16. public int getSpanSize(int position) {

  17. //適配器中有這么一個方法,根據(jù)position獲取當前這條數(shù)據(jù)是標題還是數(shù)據(jù)項,來設置他的跨列

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

  19. case SitesAdapter.SITES://標題的話跨多少列 這個值要跟整個列數(shù)相等 如果大于會出錯,小于布局會亂

  20. return 3;

  21. case SitesAdapter.SITE://數(shù)據(jù)項

  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的點擊事件,這里實現(xiàn),進行具體的操作

  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. });

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容