recycleview实现分组列表

作者: 你好好吖 | 来源:发表于2018-11-15 14:09 被阅读11次

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

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

    看下效果图吧

    image.png

    1、实体类

    public class Sites implements Serializable {
       
     
        private String name;
        private int id;
        private List<Site> sites;
     
        public String getName() {
            return name;
        }
     
        public void setName(String name) {
            this.name = name;
        }
     
        public int getId() {
            return id;
        }
     
        public void setId(int id) {
            this.id = id;
        }
     
        public List<Site> getSites() {
            return sites;
        }
     
        public void setSites(List<Site> sites) {
            this.sites = sites;
        }
     
        public static class Site implements Serializable {
            /**
             * name : botlist
             * url : http://botlist.co
             * avatar_url : https://favicon.b0.upaiyun.com/ip2/botlist.co.ico
             */
     
            private String name;
            private String url;
            private String avatar_url;
     
            public String getName() {
                return name;
            }
     
            public void setName(String name) {
                this.name = name;
            }
     
            public String getUrl() {
                return url;
            }
     
            public void setUrl(String url) {
                this.url = url;
            }
     
            public String getAvatar_url() {
                return avatar_url;
            }
     
            public void setAvatar_url(String avatar_url) {
                this.avatar_url = avatar_url;
            }
        }
    }
    

    2、适配器

    /**
     * @ProjectName: DiycodeApp
     * @PackageName: com.wenjie.diycode.adapter
     * @FileName: com.wenjie.diycode.adapter.SitesAdapter.java
     * @Author: wenjie
     * @Date: 2017-08-17 14:57
     * @Description:
     * @Version:
     */
    public class SitesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
     
        public static final int SITES = 0;//标题 跨一列 也就是合并两列
        public static final int SITE = 1;//不跨列
        //所有数据的集合,将标题和数据项,全部装在到这个集合中,在适配器中利用viewtype来区分,并显示不同的布局
        private List<Object> items = new ArrayList<>();
        private Context context;
     
        public SitesAdapter(Context context, List<Object> items) {
            this.items = items;
            this.context = context;
        }
     
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            LayoutInflater mInflater = LayoutInflater.from(context);//获取mInflater对象
            switch (viewType) {//根据viewtyupe来区分,是标题还是数据项
                case SITES://标题,加载显示标题的item布局,就一个textview显示文本,这里我们自顶一个标题的viewholder->SitesHolder
                    final SitesHolder sitesHolder = new SitesHolder(mInflater.inflate(R.layout.item_sites, parent, false));
                    //点击事件
                    sitesHolder.itemView.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            if(onItemClickListener != null){
                                onItemClickListener.onClick(sitesHolder.itemView , sitesHolder.getLayoutPosition());
                            }
                        }
                    });
                    return sitesHolder;
                case SITE://数据项,雷同不赘述了,标题和数据项的item布局和veiwholder都不会相互影响的
                    final SiteHolder siteHolder = new SiteHolder(mInflater.inflate(R.layout.item_site, parent, false));
                    siteHolder.itemView.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            if(onItemClickListener != null){
                                onItemClickListener.onClick(siteHolder.itemView , siteHolder.getLayoutPosition());
                            }
                        }
                    });
                    return siteHolder;
            }
            return null;
        }
     
        @Override
        public int getItemViewType(int position) {
            //这个方法很重要,这里根据position取出items集合中的对象,用instanceof判断他是标题还是数据项,来返回对应的标识
            if (items.get(position) instanceof Sites) {//根据items数据类型的不同来判断他是标题还是数据项
                return SITES;//标题
            } else if (items.get(position) instanceof Sites.Site) {
                return SITE;//数据项
            } else {
                return -1;
            }
        }
     
        @Override
        public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
            //根据getItemViewType绑定view进行赋值显示
            switch (holder.getItemViewType()) {
                case SITES://标题
                    SitesHolder sitesHolder = (SitesHolder) holder;
                    sitesHolder.name.setText(((Sites) items.get(position)).getName());
                    break;
                case SITE://数据项
                    SiteHolder siteHolder = (SiteHolder) holder;
                    siteHolder.name.setText(((Sites.Site) items.get(position)).getName());
                    Glide.with(context).load(((Sites.Site) items.get(position)).getAvatar_url()).into(siteHolder.icon);
                    break;
            }
        }
     
        /**
         * 公布点击事件出去
         */
        private OnItemClickListener onItemClickListener;
     
        public void setOnItemClickListener(OnItemClickListener onItemClickListener){
            this.onItemClickListener = onItemClickListener;
        }
     
        public interface OnItemClickListener{
            void onClick(View itemview , int position);
        }
     
        @Override
        public int getItemCount() {
            return items.size();
        }
     
        /**
         * 数据项的viewholder  一个文本textview一个cion  imageview
         */
        private class SiteHolder extends RecyclerView.ViewHolder {
     
            TextView name;
            ImageView icon;
     
            SiteHolder(View itemView) {
                super(itemView);
                name = (TextView) itemView.findViewById(R.id.name);
                icon = (ImageView) itemView.findViewById(R.id.icon);
            }
        }
     
        /**
         * 标题的viewholder  只有一个textview
         */
        private class SitesHolder extends RecyclerView.ViewHolder {
     
            TextView name;
     
            SitesHolder(View itemView) {
                super(itemView);
                name = (TextView) itemView.findViewById(R.id.name);
            }
        }
    }
    

    接下来就是 当数据获取成功之后,如何和适配器进行绑定显示sites就是从获取获取到了并解析好的数据集合

    List<Object> items = new ArrayList<>();
            //数据获取之后  将数据循环遍历,放进items集合中,至于服务器返回什么格式的数据,我想看下实体类就应该明白了
            for (int i=0; i < sites.size(); i++){
                items.add(sites.get(i));
                for(int k = 0; k < sites.get(i).getSites().size(); k ++){
                    items.add(sites.get(i).getSites().get(k));
                }
            }
            //实例化适配器将遍历好的数据放进适配器中
            sitesAdapter = new SitesAdapter(getActivity() ,items);
            //new一个布局管理器,这里是用GridLayoutManager,要区分3列
            GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity() , 3);//多少列,如果数据项只需要1列,这里写1,下面return 也返回1即可实现
            //下面这个方法很重要,根据position获取当前这条数据是标题还是数据项,来设置他的跨列
            gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    //适配器中有这么一个方法,根据position获取当前这条数据是标题还是数据项,来设置他的跨列
                    switch (sitesAdapter.getItemViewType(position)){
                        case SitesAdapter.SITES://标题的话跨多少列 这个值要跟整个列数相等 如果大于会出错,小于布局会乱
                            return 3;
                        case SitesAdapter.SITE://数据项
                            return 1;//不跨列,就是分成三列显示
                        default:
                            return -1;
                    }
                }
            });
            sitesRecycleView.setLayoutManager(gridLayoutManager);
    //        sitesRecycleView.addItemDecoration(new DividerItemDecoration(getActivity() , GridLayoutManager.VERTICAL));
            sitesRecycleView.setAdapter(sitesAdapter);
     
            //item的点击事件,这里实现,进行具体的操作
            sitesAdapter.setOnItemClickListener(new SitesAdapter.OnItemClickListener() {
                @Override
                public void onClick(View itemview, int position) {
                    switch (sitesAdapter.getItemViewType(position)){
                        case SitesAdapter.SITE:
    //                        ToastUtils.showToast(getActivity() , ((CoolSites.Site) items.get(position)).getName());
                            Intent intent = new Intent(getActivity() , WebViewActivity.class);
                            intent.putExtra("url" , ((Sites.Site) items.get(position)).getUrl());
                            startActivity(intent);
                            break;
                        case SitesAdapter.SITES:
                            ToastUtils.showToast(getActivity() , ((Sites) items.get(position)).getName());
                            break;
                    }
                }
            });
    

    相关文章

      网友评论

        本文标题:recycleview实现分组列表

        本文链接:https://www.haomeiwen.com/subject/ucryfqtx.html