首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android RecyclerView浅析(分类型)

Android RecyclerView浅析(分类型)

作者头像
程序员飞飞
发布2020-02-27 16:55:07
1K0
发布2020-02-27 16:55:07
举报
文章被收录于专栏:Android&Java技术Android&Java技术

Android RecyclerView浅析

1.RecyclerView概述&简介

简单介绍:

整体上看RecyclerView架构,提供了一种插拔式的体验,高度的解耦,异常的灵活,通过设置它提供的不同LayoutManager,ItemDecoration , ItemAnimator实现令人瞠目的效果。

你想要控制其显示的方式,请通过布局管理器LayoutManager

你想要控制Item间的间隔(可绘制),请通过ItemDecoration

你想要控制Item增删的动画,请通过ItemAnimator

你想要控制点击、长按事件,请自己写(擦,这点尼玛。)

给Recycler的Item的布局去设置margin,当然了这种方式不够优雅,我们文章开始说了,我们可以自由的去定制它,当然我们的分割线也是可以定制的。

ItemDecoration

我们可以通过该方法添加分割线:

mRecyclerView.addItemDecoration()

该方法的参数为RecyclerView.ItemDecoration,该类为抽象类,官方目前并没有提供默认的实现类(我觉得最好能提供几个)

提示:如果布局管理器里面设置的Horizontal就是行,如果是Vertical就是显示几列。

2.实现步骤:

布局,适配器,继承于RecyclerView的适配器,

viewHolder继承于RecyclerView的适配器

设置泛型,然后再次实现对应的方法

3.RecyclerView各个布局管理器的说明

1).线性布局管理器:

mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));  

参数一:上下文; 参数二:指明线性布局的方向,参数三:是否为倒序排列;

2).网格布局管理器:

mRecyclerView.setLayoutManager(new GridLayoutManager(this, 4, GridLayoutManager.VERTICAL, false));

参数一:上下文; 参数二:指明行数(Horizontal),或列数(Vertical);

参数三:指明方向;参数四:是否倒序;

3).瀑布流布局管理器

mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(4, StaggeredGridLayoutManager.VERTICAL));

参数一:指明行数(Horizontal),或列数(Vertical);

参数二:指明方向;

4.给RecyclerView的Item设置点击事件有两种:

方式一:在Adapter的onBindViewHolder()方法中设置,也可以定义一个接口回调,让MainAcitivity实现自定义的接口,然后在MainActivity设置接口回调的监听即可:mRvAdapter.setonItemClickListener();

5.一般的RecyclerView

5.1布局

	<android.support.v7.widget.RecyclerView

        android:id="@+id/recyclerView"

        android:layout_width="match_parent"

        android:layout_height="match_parent" />

5.2初始化控件,设置布局管理器(3种)

	recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        // 设置线性布局管理器
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

5.3设置适配器

    recyclerView.setAdapter(new MyAdapter());

5.4创建适配器

写一个类继承于Recyclerview的Adapter重写几个方法,写一个viewHolder,然后设置Adapter的泛型为当前的ViewHolder,如果有不一样的就要重写其方法

关于其几个方法的说明:

	class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

		// 创建一个ViewHolder,加载一个视图

        @Override

        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(AddHeadRecyclerViewActivity.this).inflate(R.layout.item, parent, false);
            return new ViewHolder(view);
        }

		// 绑定ViewHolder,一般进行数据的绑定操作
        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

        }

		// 返回有多少条Item
        @Override
        public int getItemCount() {
            return 9;
        }

		// ViewHolder
        class ViewHolder extends RecyclerView.ViewHolder {
            public ViewHolder(View itemView) {
                super(itemView);
            }
        }
    }

5.5在onCreateViewHolde中,创建一个ViewHolder(),一般为加载一个布局文件,注意此处inflate和LayoutInflater的区别

6.分类型的RecyclerView

6.1重写方法和和一般的类似,多了一个getItemViewType()方法下面是分类的代码示例及解释

	public class HomeRecycleAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    public static final String GOODS_BEAN = "goods_bean";
    /**
     * 上下文
     */

    private Context mContext;
    /**
     * 数据Bean对象
     */
    private ResultBean resultBean;
    /**
     * 五种类型
     */
     
    /**
     * 横幅广告
     */
    public static final int BANNER = 0;

    /**
     * 频道
     */
    public static final int CHANNEL = 1;

    /**
     * 活动
     */
    public static final int ACT = 2;

    /**
     * 秒杀
     */
    public static final int SECKILL = 3;
    /**
     * 推荐
     */
    public static final int RECOMMEND = 4;

    /**
     * 热卖
     */
    public static final int HOT = 5;

    /**
     * 当前类型
     */
    public int currentType = BANNER;

    private final LayoutInflater mLayoutInflater;

    public HomeRecycleAdapter(Context mContext, ResultBean resultBean) {

        this.mContext = mContext;

        this.resultBean = resultBean;

        mLayoutInflater = LayoutInflater.from(mContext);

    }

    /**
     * 根据位置得到类型-系统调用
     * @param position
     * @return
     */
    @Override

    public int getItemViewType(int position) {

        switch (position) {
            case BANNER:
                currentType = BANNER;
                break;
            case CHANNEL:
                currentType = CHANNEL;
                break;
            case ACT:
                currentType = ACT;
                break;
            case SECKILL:
                currentType = SECKILL;
                break;
            case RECOMMEND:
                currentType = RECOMMEND;
                break;
            case HOT:
                currentType = HOT;
                break;
        }

        return currentType;

    }

    /**

     * 返回总条数,共六种类型

     * @return

     */

    @Override

    public int getItemCount() {

        return 6;

    }

    @Override

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

        if (viewType == BANNER) {

            return new BannerViewHolder(mLayoutInflater.inflate(R.layout.banner_viewpager, null), mContext, resultBean);

        } else if (viewType == CHANNEL) {

            return new ChannelViewHolder(mLayoutInflater.inflate(R.layout.channel_item, null), mContext);

        } else if (viewType == ACT) {

            return new ActViewHolder(mLayoutInflater.inflate(R.layout.act_item, null), mContext);

        } else if (viewType == SECKILL) {

            return new SeckillViewHolder(mLayoutInflater.inflate(R.layout.seckill_item, null), mContext);

        } else if (viewType == RECOMMEND) {

            return new RecommendViewHolder(mLayoutInflater.inflate(R.layout.recommend_item, null), mContext);

        } else if (viewType == HOT) {

            return new HotViewHolder(mLayoutInflater.inflate(R.layout.hot_item, null), mContext);

        }

        return null;

    }

    /**

     * 绑定数据

     * @param holder

     * @param position

     */

    @Override

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

        if (getItemViewType(position) == BANNER) {

            BannerViewHolder bannerViewHolder = (BannerViewHolder) holder;

            bannerViewHolder.setData(resultBean.getBanner_info());

        } else if (getItemViewType(position) == CHANNEL) {

            ChannelViewHolder channelViewHolder = (ChannelViewHolder) holder;

            channelViewHolder.setData(resultBean.getChannel_info());

        } else if (getItemViewType(position) == ACT) {

            ActViewHolder actViewHolder = (ActViewHolder) holder;

            actViewHolder.setData(resultBean.getAct_info());

        } else if (getItemViewType(position) == SECKILL) {

            SeckillViewHolder seckillViewHolder = (SeckillViewHolder) holder;

            seckillViewHolder.setData(resultBean.getSeckill_info());

        } else if (getItemViewType(position) == RECOMMEND) {

            RecommendViewHolder recommendViewHolder = (RecommendViewHolder) holder;

            recommendViewHolder.setData(resultBean.getRecommend_info());

        } else if (getItemViewType(position) == HOT) {

            HotViewHolder hotViewHolder = (HotViewHolder) holder;

            hotViewHolder.setData(resultBean.getHot_info());

        }

    }

    class HotViewHolder extends RecyclerView.ViewHolder {

        private TextView tv_more_hot;

        private GridView gv_hot;

        private Context mContext;



        public HotViewHolder(View itemView, Context mContext) {

            super(itemView);

            tv_more_hot = (TextView) itemView.findViewById(R.id.tv_more_hot);

            gv_hot = (GridView) itemView.findViewById(R.id.gv_hot);

            this.mContext = mContext;

        }



        public void setData(final List<ResultBean.HotInfoBean> data) {

            HotGridViewAdapter adapter = new HotGridViewAdapter(mContext, data);

            gv_hot.setAdapter(adapter);



            //点击事件

            gv_hot.setOnItemClickListener(new AdapterView.OnItemClickListener() {

                @Override

                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                    // Toast.makeText(mContext, "position:" + position, Toast.LENGTH_SHORT).show();

                    String cover_price = data.get(position).getCover_price();

                    String name = data.get(position).getName();

                    String figure = data.get(position).getFigure();

                    String product_id = data.get(position).getProduct_id();

                    GoodsBean goodsBean = new GoodsBean(name, cover_price, figure, product_id);



                    Intent intent = new Intent(mContext, GoodsInfoActivity.class);

                    intent.putExtra(GOODS_BEAN, goodsBean);

                    mContext.startActivity(intent);

                }

            });

        }

    }

6.2一般将分类型的每种类型都声明为一个常量,然后根据常量来创建对应的ViewHolder(加载自己对应的布局文件),然后在根据类型绑定自己的对应的数据;所以每一中类型都要对应自己的ViewHolder,进而实现分类型;一般还有实现其有参构造为了传递和初始化相关数据;

7.RecyclerView三种布局管理添加头的方式:

7.1LinearLayoutManager添加头部

直接分类型就可以 第一个头部是第一种类型

7.2GridLayoutManager添加头部

代码

RecyclerView rv = (RecyclerView) findViewById(R.id.rv);



 GridLayoutManager manager = new GridLayoutManager(this,2);



 // 重点在这 需要实现这个方法

 manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {

 @Override

 public int getSpanSize(int position) {

       return position == 0 ? 2 : 1;

 });



 rv.setLayoutManager(manager);



 rv.setAdapter(new MyAdapter());



//解释:明明头部返回的是2 怎么会是这个效果呢?返回2不应该是2列返回1是1列吗?

position 就是我们的item位置



getSpanSize返回的值就是我们的跨列度

  

GridLayoutManager manager = new GridLayoutManager(this,2); 

 

大家看这个方法里的第二个参数,我们是不是指定了2列 



而我们的头是不是返回了2然后显示了一行,没错,就是所占的列数。也就是我们的头占了2列 第二个item往后只占一列也就是一个item占屏幕的一半。

###7.3StaggeredGridLayoutManager添加头部

在adapter中重写些方法

	@Override

	public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {



    super.onViewAttachedToWindow(holder);



    ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();



    if(lp != null



            && lp instanceof StaggeredGridLayoutManager.LayoutParams) {



            StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;



			//设置全屏

            p.setFullSpan(holder.getLayoutPosition() == 0);

    	}

	}

onViewAttachedToWindow()

当列表项出现到可视界面的时候调用

8.inflate&LayoutInflater

其实View.inflate的底层就是 LayoutInflate.form()
View.inflate
public static View inflate(Context context, @LayoutRes int resource, ViewGroup root) {

        LayoutInflater factory = LayoutInflater.from(context);

        return factory.inflate(resource, root);

}

inflate(int resource, ViewGroup root, boolean attachToRoot)

1. 如果root为null,attachToRoot将失去作用,设置任何值都没有意义。
2. 如果root不为null,attachToRoot设为true,则会给加载的布局文件的指定一个父布局,即root。
3. 如果root不为null,attachToRoot设为false,则会将布局文件最外层的所有layout属性进行设置,当该view被添加到父view当中时,这些layout属性会自动生效。
4. 在不设置attachToRoot参数的情况下,如果root不为null,attachToRoot参数默认为true。

今天给大家简单的介绍了一下RecyclerView的一般用法和分类的用法,一般我们开发使用最多的也就是这两种了,希望对大家能有所帮助。

Thanks all.

本文首发于我的微信公众号,更多干货文章,请扫描二维码订阅哦:

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-04-02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Android RecyclerView浅析
    • 1.RecyclerView概述&简介
      • 2.实现步骤:
        • 3.RecyclerView各个布局管理器的说明
          • 1).线性布局管理器:
          • 2).网格布局管理器:
          • 3).瀑布流布局管理器
        • 4.给RecyclerView的Item设置点击事件有两种:
          • 5.一般的RecyclerView
            • 5.1布局
            • 5.2初始化控件,设置布局管理器(3种)
            • 5.3设置适配器
            • 5.4创建适配器
            • 5.5在onCreateViewHolde中,创建一个ViewHolder(),一般为加载一个布局文件,注意此处inflate和LayoutInflater的区别
          • 6.分类型的RecyclerView
            • 6.1重写方法和和一般的类似,多了一个getItemViewType()方法下面是分类的代码示例及解释
            • 6.2一般将分类型的每种类型都声明为一个常量,然后根据常量来创建对应的ViewHolder(加载自己对应的布局文件),然后在根据类型绑定自己的对应的数据;所以每一中类型都要对应自己的ViewHolder,进而实现分类型;一般还有实现其有参构造为了传递和初始化相关数据;
          • 7.RecyclerView三种布局管理添加头的方式:
            • 7.1LinearLayoutManager添加头部
            • 7.2GridLayoutManager添加头部
          • 8.inflate&LayoutInflater
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档