类支付宝首页——RecycleView多布局结构实现

大家都知道,RecycleView默认只能通过setLayoutManager()方法指定一种布局结构,那么像支付宝首页这样复杂的多布局情况如何处理呢?在ListView中,我们也遇到过这种情况,是通过getItemViewType结合其他方法,通过判断类型来加载不同的布局。在RecycleView中也同样使用,今天我们主要介绍RecycleView多布局实现,其中布局嵌套了GridView,有些坑需要注意,避免陷入。

一、效果图

废话不多说,献上效果图。

从图中可以看出,一共有三种布局样式。第一种:头布局,包含各种类型的新闻频道。第二种布局:普通的新闻。第三种布局:多图图集新闻。

二、多布局实现的思路

步骤一、getItemViewType()方法判断不同的布局,返回判断结果。

步骤二、创建不同的ViewHolder类,针对不同的布局类型,进行对应的布局内控件的初始化。

步骤三、onCreateViewHolder()方法根据第一步的判断结果,得到viewType,根据viewType值,实例化不同类型的ViewHolder对象。

步骤四、onBindViewHolder()方法判断holder所属类型,进行相对应类型的布局内控件内容的赋值。

以上就是实现多布局的思路,很简单(可能描述不到位,不易理解),下面我们以代码的形式更直观的来了解具体步骤。

三、RecycleView多布局实现代码

首先定义三种类型常量

 //新闻模式
    private static final int TYPE_SINGLE = 0;
    //图集模式
    private static final int TYPE_MULTI = 1;
    //头布局模式
    private static final int TYPE_HEADER = 2;

getItemViewType()方法判断不同的布局,返回判断结果

@Override
    public int getItemViewType(int position) {
        //所有的新闻详情数据,在第一个位置自己手动加入了一个假的新闻数据,把它的title设置为“头布局”
        NewsInfo info = list.get(position);
        //识别出“头布局”,则是第一个数据,把它归于头布局类型
        if(info.getTitle().endsWith("头布局")){
            return TYPE_HEADER;
        }
       //有新闻具体内容,是普通新闻
        if (!TextUtils.isEmpty(info.getDigest()))
        {
            return TYPE_SINGLE;
        }
      //其他情况,是图集新闻
        return TYPE_MULTI;
    }

创建不同的ViewHolder类,针对不同的布局类型,进行对应的布局内控件的初始化。

扫描二维码关注公众号,回复: 6400969 查看本文章

省略了具体的初始化操作

 public class SingleViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
         .......
         .......
        public SingleViewHolder(View itemView) {
            super(itemView);
         .......
         .......
        }

        @Override
        public void onClick(View view) {
            Toast.makeText(context,"点击了",Toast.LENGTH_SHORT).show();
        }
    }
    public class MultiViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
         .......
         .......

        public MultiViewHolder(View itemView) {
            super(itemView);
        .......
        .......
        }

        @Override
        public void onClick(View view) {
            Toast.makeText(context,"点击了",Toast.LENGTH_SHORT).show();
        }
    }
    public class HeaderViewHolder extends RecyclerView.ViewHolder{
         .......
         .......
        public HeaderViewHolder(View itemView) {
            super(itemView);
          .......
          .......
        }
    }

onCreateViewHolder()方法根据第一步的判断结果,得到viewType,根据viewType值,实例化不同类型的ViewHolder对象。

@Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType) {
            case TYPE_SINGLE:
                return new SingleViewHolder(inflater.inflate(R.layout.item_news, parent, false));
            case TYPE_MULTI:
                return new MultiViewHolder(inflater.inflate(R.layout.item_news_photo, parent, false));
            case TYPE_HEADER:
                return new HeaderViewHolder(inflater.inflate(R.layout.item_news_header,parent,false));
        }
        return null;
    }

onBindViewHolder()方法判断holder所属类型,进行相对应类型的布局内控件内容的赋值。

@Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        //设置不同的布局内控件的值
        if (holder instanceof SingleViewHolder) {
            setNormalItemValues((SingleViewHolder) holder,position);
        }else if(holder instanceof  MultiViewHolder){
            setMultiItemValues((MultiViewHolder) holder,position);
        }else{
            setHeaderItemValues((HeaderViewHolder) holder);
        }
    }

针对不同类型,设置布局内控件的值的具体内容就不介绍了,比较繁多,下面有源码链接。

**由于本例中头布局是个GridView,需要注意的一点是RecycleView中嵌套GridView会出现只显示一行的问题。**下面给出具体解决方法:

setHeaderItemValues((HeaderViewHolder) holder);中,主动测量出GridView的高度,并设置给布局。本例中默认GridView是两行。

 //解决GridView只显示一行的原因 主动设置GridView的高度
        ViewGroup.LayoutParams params = holder.mGridView.getLayoutParams();
        View view = mAdapter.getView(0, null, holder.mGridView);
        view.measure(0,0);
        int height =view.getMeasuredHeight();
        int totalHeight = holder.mGridView.getVerticalSpacing() * 2 + height * 2;
        params.height = totalHeight;
        holder.mGridView.setLayoutParams(params);

源码地址比较乱,直接看NewsFragment相关内容即可。

自己是从事了七年开发的Android工程师,不少人私下问我,2019年Android进阶该怎么学,方法有没有?

没错,年初我花了一个多月的时间整理出来的学习资料,希望能帮助那些想进阶提升Android开发,却又不知道怎么进阶学习的朋友。【包括高级UI、性能优化、架构师课程、NDK、Kotlin、混合式开发(ReactNative+Weex)、Flutter等架构技术资料】,希望能帮助到您面试前的复习且找到一个好的工作,也节省大家在网上搜索资料的时间来学习。

资料获取方式:加入Android架构交流QQ群聊:513088520 ,进群即领取资料!!!

点击链接加入群聊【Android移动架构总群】:加入群聊

资料大全

猜你喜欢

转载自blog.csdn.net/weixin_43351655/article/details/90758255
今日推荐