多种viewType的recyclerView使用MultipleItemRvAdapter示例

Posted 汤米粥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多种viewType的recyclerView使用MultipleItemRvAdapter示例相关的知识,希望对你有一定的参考价值。

package com.chaychan.news.ui.adapter;

import android.support.annotation.Nullable;
import android.text.TextUtils;

import com.chad.library.adapter.base.BaseViewHolder;
import com.chaychan.adapter.MultipleItemRvAdapter;
import com.chaychan.news.model.entity.News;
import com.chaychan.news.ui.adapter.provider.news.CenterPicNewsItemProvider;
import com.chaychan.news.ui.adapter.provider.news.RightPicNewsItemProvider;
import com.chaychan.news.ui.adapter.provider.news.TextNewsItemProvider;
import com.chaychan.news.ui.adapter.provider.news.ThreePicNewsItemProvider;
import com.chaychan.news.utils.ListUtils;

import java.util.List;

/**
 * @author ChayChan
 * @description: 新闻列表的适配器
 * @date 2018/3/22  11
 */

public class NewsListAdapter extends MultipleItemRvAdapter<News,BaseViewHolder> 

    /**
     * 纯文字布局(文章、广告)
     */
    public static final int TEXT_NEWS = 100;
    /**
     * 居中大图布局(1.单图文章;2.单图广告;3.视频,中间显示播放图标,右侧显示时长)
     */
    public static final int CENTER_SINGLE_PIC_NEWS = 200;
    /**
     * 右侧小图布局(1.小图新闻;2.视频类型,右下角显示视频时长)
     */
    public static final int RIGHT_PIC_VIDEO_NEWS = 300;
    /**
     * 三张图片布局(文章、广告)
     */
    public static final int THREE_PICS_NEWS = 400;


    private String mChannelCode;


    public NewsListAdapter(String channelCode, @Nullable List<News> data) 
        super(data);
        mChannelCode = channelCode;

      
        //构造函数若有传参可以在调用finishInitialize()之前进行赋值,赋值给全局变量
        //这样getViewType()和registerItemProvider()方法中可以获取到传过来的值
        //getViewType()中可能因为某些业务逻辑,需要将某个值传递过来进行判断,返回对应的viewType
        //registerItemProvider()中可以将值传递给ItemProvider
        
        //最重要的是这一行,别忘加了!!
		finishInitialize();//调用该方法告知MultipleItemRvAdapter1️已初始化完构造函数参数的传递
        
    

    @Override
    protected int getViewType(News news) 
        if (news.has_video) 
            //如果有视频
            if (news.video_style == 0) 
                //右侧视频
                if (news.middle_image == null || TextUtils.isEmpty(news.middle_image.url)) 
                    return TEXT_NEWS;
                
                return RIGHT_PIC_VIDEO_NEWS;
             else if (news.video_style == 2) 
                //居中视频
                return CENTER_SINGLE_PIC_NEWS;
            
         else 
            //非视频新闻
            if (!news.has_image) 
                //纯文字新闻
                return TEXT_NEWS;
             else 
                if (ListUtils.isEmpty(news.image_list)) 
                    //图片列表为空,则是右侧图片
                    return RIGHT_PIC_VIDEO_NEWS;
                

                if (news.gallary_image_count == 3) 
                    //图片数为3,则为三图
                    return THREE_PICS_NEWS;
                

                //中间大图,右下角显示图数
                return CENTER_SINGLE_PIC_NEWS;
            
        

        return TEXT_NEWS;
    

    @Override
    public void registerItemProvider() 
        //注册itemProvider
        mProviderDelegate.registerProvider(new TextNewsItemProvider(mChannelCode));
        mProviderDelegate.registerProvider(new CenterPicNewsItemProvider(mChannelCode));
        mProviderDelegate.registerProvider(new RightPicNewsItemProvider(mChannelCode));
        mProviderDelegate.registerProvider(new ThreePicNewsItemProvider(mChannelCode));
    
package com.chaychan.news.ui.adapter.provider.news;

import com.chad.library.adapter.base.BaseViewHolder;
import com.chaychan.news.R;
import com.chaychan.news.model.entity.News;
import com.chaychan.news.ui.adapter.NewsListAdapter;

/**
 * @author ChayChan
 * @description: 纯文本新闻
 * @date 2018/3/22  14:36
 */
public class TextNewsItemProvider extends BaseNewsItemProvider 

    public TextNewsItemProvider(String channelCode) 
        super(channelCode);
    

    @Override
    public int viewType() 
        return NewsListAdapter.TEXT_NEWS;
    

    @Override
    public int layout() 
        return R.layout.item_text_news;
    

    @Override
    protected void setData(BaseViewHolder helper, News news) 
         //由于文本消息的逻辑目前已经在基类中封装,所以此处无须写
        //定义此类是提供文本消息的ItemProvider
    

package com.chaychan.news.ui.adapter.provider.news;

import android.widget.TextView;

import com.chad.library.adapter.base.BaseViewHolder;
import com.chaychan.news.R;
import com.chaychan.news.model.entity.News;
import com.chaychan.news.ui.adapter.NewsListAdapter;
import com.chaychan.news.utils.GlideUtils;
import com.chaychan.news.utils.TimeUtils;
import com.chaychan.news.utils.UIUtils;

/**
 * @author ChayChan
 * @description: 居中大图布局(1.单图文章;2.单图广告;3.视频,中间显示播放图标,右侧显示时长)
 * @date 2018/3/22  14:36
 */
public class CenterPicNewsItemProvider extends BaseNewsItemProvider 


    public CenterPicNewsItemProvider(String channelCode) 
        super(channelCode);
    

    @Override
    public int viewType() 
        return NewsListAdapter.CENTER_SINGLE_PIC_NEWS;
    

    @Override
    public int layout() 
        return R.layout.item_center_pic_news;
    

    @Override
    protected void setData(BaseViewHolder helper, News news) 
        //中间大图布局,判断是否有视频
        TextView tvBottomRight = helper.getView(R.id.tv_bottom_right);
        if (news.has_video) 
            helper.setVisible(R.id.iv_play, true);//显示播放按钮
            tvBottomRight.setCompoundDrawables(null, null, null, null);//去除TextView左侧图标
            helper.setText(R.id.tv_bottom_right, TimeUtils.secToTime(news.video_duration));//设置时长
            GlideUtils.load(mContext, news.video_detail_info.detail_video_large_image.url, helper.getView(R.id.iv_img));//中间图片使用视频大图
         else 
            helper.setVisible(R.id.iv_play, false);//隐藏播放按钮
            if (news.gallary_image_count == 1)
                tvBottomRight.setCompoundDrawables(null, null, null, null);//去除TextView左侧图标
            else
                tvBottomRight.setCompoundDrawables(mContext.getResources().getDrawable(R.mipmap.icon_picture_group), null, null, null);//TextView增加左侧图标
                helper.setText(R.id.tv_bottom_right, news.gallary_image_count + UIUtils.getString(R.string.img_unit));//设置图片数
            
            GlideUtils.load(mContext, news.image_list.get(0).url.replace("list/300x196", "large"), helper.getView(R.id.iv_img));//中间图片使用image_list第一张
        
    

package com.chaychan.news.ui.adapter.provider.news;

import com.chad.library.adapter.base.BaseViewHolder;
import com.chaychan.news.R;
import com.chaychan.news.model.entity.News;
import com.chaychan.news.ui.adapter.NewsListAdapter;
import com.chaychan.news.utils.GlideUtils;
import com.chaychan.news.utils.TimeUtils;

/**
 * @author ChayChan
 * @description: 右侧小图布局(1.小图新闻;2.视频类型,右下角显示视频时长)
 * @date 2018/3/22  14:36
 */
public class RightPicNewsItemProvider extends BaseNewsItemProvider 


    public RightPicNewsItemProvider(String channelCode) 
        super(channelCode);
    

    @Override
    public int viewType() 
        return NewsListAdapter.RIGHT_PIC_VIDEO_NEWS;
    

    @Override
    public int layout() 
        return R.layout.item_pic_video_news;
    


    @Override
    protected void setData(BaseViewHolder helper, News news) 
        //右侧小图布局,判断是否有视频
        if (news.has_video) 
            helper.setVisible(R.id.ll_duration, true);//显示时长
            helper.setText(R.id.tv_duration, TimeUtils.secToTime(news.video_duration));//设置时长
         else 
            helper.setVisible(R.id.ll_duration, false);//隐藏时长
        
        GlideUtils.load(mContext, news.middle_image.url, helper.getView(R.id.iv_img));//右侧图片或视频的图片使用middle_image
    


package com.chaychan.news.ui.adapter.provider.news;

import com.chad.library.adapter.base.BaseViewHolder;
import com.chaychan.news.R;
import com.chaychan.news.model.entity.News;
import com.chaychan.news.ui.adapter.NewsListAdapter;
import com.chaychan.news.utils.GlideUtils;

/**
 * @author ChayChan
 * @description: 三张图片布局(文章、广告)
 * @date 2018/3/22  14:36
 */
public class ThreePicNewsItemProvider extends BaseNewsItemProvider 

    public ThreePicNewsItemProvider(String channelCode) 
        super(channelCode);
    

    @Override
    public int viewType() 
        return NewsListAdapter.THREE_PICS_NEWS;
    

    @Override
    public int layout() 
        return R.layout.item_three_pics_news;
    

    @Override
    protected void setData(BaseViewHolder helper, News news) 
        //三张图片的新闻
        GlideUtils.load(mContext, news.image_list.get(0).url, helper.getView(R.id.iv_img1));
        GlideUtils.load(mContext, news.image_list.get(1).url, helper.getView(R.id.iv_img2));
        GlideUtils.load(mContext, news.image_list.get(2).url, helper.getView(R.id.iv_img3));
    


package com.chaychan.news.ui.adapter.provider.news;

import android.text.TextUtils;

import com.chad.library.adapter.base.BaseViewHolder;
import com.chaychan.adapter.BaseItemProvider;
import com.chaychan.news.R;
import com.chaychan.news.constants.Constant;
import com.chaychan.news.model.entity.News;
import com.chaychan.news.utils.TimeUtils;
import com.chaychan.news.utils.UIUtils;

/**
 * @author ChayChan
 * @description: 将新闻中设置数据公共部分抽取
 * @date 2018/3/22  14:48
 */

public abstract class BaseNewsItemProvider extends BaseItemProvider<News,BaseViewHolder> 

    private String mChannelCode;

    public BaseNewsItemProvider(String channelCode) 
        mChannelCode = channelCode;
    

    @Override
    public void convert(BaseViewHolder helper, News news, int i) 
        if (TextUtils.isEmpty(news.title)) 
            //如果没有标题,则直接跳过
            return;
        

        //设置标题、底部作者、评论数、发表时间
        helper.setText(R.id.tv_title, news.title)
                .setText(R.id.tv_author, news.source)
                .setText(R.id.tv_comment_num, news.comment_count + UIUtils.getString(R.string.comment))
                .setText(R.id.tv_time, TimeUtils.getShortTime(news.behot_time * 1000));

        //根据情况显示置顶、广告和热点的标签
        int position = helper.getAdapterPosition();
        String[] channelCodes = UIUtils.getStringArr(R.array.channel_code);
        boolean isTop = position == 0 && mChannelCode.equals(channelCodes[0]); //属于置顶
        boolean isHot = news.hot == 1;//属于热点新闻
        boolean isAD = !TextUtils.isEmpty(news.tag) ? news.tag.equals(Constant.ARTICLE_GENRE_AD) : false;//属于广告新闻
        boolean isMovie = !TextUtils.isEmpty(news.tag) ? news.tag.equals(Constant.TAG_MOVIE) : false;//如果是影视
        helper.setVisible(R.id.tv_tag, isTop || isHot || isAD);//如果是上面任意一个,显示标签
        helper.setVisible(R.id.tv_comment_num, !isAD);//如果是广告,则隐藏评论数

        String tag = "";
        if (isTop) 
            tag = UIUtils.getString(R.string.to_top);
            helper.setTextColor(R.id.tv_tag, UIUtils.getColor(R.color.color_F96B6B));
         else if (isHot) 
            tag = UIUtils.getString(R.string.hot);
            helper.setTextColor(R.id.tv_tag, UIUtils.getColor(R.color.color_F96B6B));
         else if (isAD) 
            tag = UIUtils.getString(R.string.ad);
            helper.setTextColor(R.id.tv_tag, UIUtils.getColor(R.color.color_3091D8));
         else if (isMovie) 
            //如果是影视
            tag = UIUtils.getString(R.string.tag_movie);
            helper.setTextColor(R.id.tv_tag, UIUtils.getColor(R.color.color_F96B6B));
        
        helper.setText(R.id.tv_tag, tag);


        setData(helper, news);
    

    protected abstract void setData(BaseViewHolder helper, News news);

以上是关于多种viewType的recyclerView使用MultipleItemRvAdapter示例的主要内容,如果未能解决你的问题,请参考以下文章

每个ViewType中的MultipleView RecyclerView单选

RecyclerView Adapter 实现自动多 ViewType

RecyclerView Adapter 实现自动多 ViewType

RecyclerView Adapter 实现自动多 ViewType

安卓recyclerview中的adapter怎么设置item的viewtype

这种类型的实现怎么称呼? RecyclerView,布局