RecyclerView系列 - 多布局问题

1. 说明


在我们实际开发过程中,有时候会有这样的需求,就是使用ListView或者RecyclerView显示一个列表,然后这个列表中的数据有多种布局的类型,这里就使用微信聊天来举例,而针对于这种多种布局类型的条目,后台一般都会给一个字段用来区分当前条目到底是什么类型的,如果后台没有这样一个字段用于区分当前显示哪种类型条目的话,那么这个需求是没有办法去做的。

在这里我们就采用微信聊天举例说明:
比如后台返回的数据是:chatContent 聊天内容 、isMe是否是我自己的

针对于这种多布局,解决方案一般是从对象下手,根据列表当前的条目来确定布局
其实主要还是getItemViewType(int position)方法
具体代码如下:

/**
 * Created by JackChen on 2018/3/4.
 * Description : RecyclerView多布局展示
 */

public class CommonAdapterActivity extends AppCompatActivity {

    private RecyclerView recycler_view;

    private List<ChatData> datas ;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_base_use);


        //测试数据
        initData() ;

        recycler_view = (RecyclerView) findViewById(R.id.recycler_view);
        // 在setAdapter之前必须先设置布局的样式,否则数据不会显示的
        recycler_view.setLayoutManager(new LinearLayoutManager(this));

        recycler_view.setAdapter(new RecyclerAdapter(this,datas));
    }


    /**
     * 测试数据
     */
    private void initData() {
        datas = new ArrayList<>() ;

        for (int i = 0; i < 100; i++) {
            if (i % 3 == 0){   // 1 表示是自己说的话
                datas.add(new ChatData("内容"+i, 1)) ;
            }else{
                datas.add(new ChatData("内容"+i, 0)) ;  // 0 表示别人说的话
            }
        }
    }


    private class RecyclerAdapter extends RecyclerCommonAdapter<ChatData>{


//        // 单布局条目
//        public RecyclerAdapter(Context context, List data, int layoutId) {
//            super(context, data, layoutId);
//        }

        // 多布局显示
        public RecyclerAdapter(Context context, List<ChatData> data) {
            super(context, data, new MutiliTypeSupport<ChatData>() {
                @Override
                public int getLayoutId(ChatData item) {
                    // 如果自己项目中列表是多条目,直接写这个地方,这里需要做的就只是从服务器中取出判断多条目的字段,
                    // 这里为了方便测试,只是从测试数据中取出 字段isMe , 这里的isMe - 1表示自己,0表示朋友
                    if (item.isMe ==1){
                        return R.layout.item_chat_me ;
                    }
                    return R.layout.item_chat_friend;
                }
            });
        }

        @Override
        protected void convert(ViewHolder holder, ChatData item, int position) {
            holder.setText(R.id.chat_text , item.chatContent) ;
        }


    }



    public class ChatData {
        public ChatData(String content , int isMe){
            this.chatContent = content ;
            this.isMe = isMe ;

        }
        public String chatContent ;
        public int isMe ;  // 1 表示是我自己的  0 表示其他人
    }
}

2. 步骤分析


2.1 先去请求网络数据,此处使用initData()测试数据来模拟网络请求;
2.2 然后给RecyclerView设置布局样式、并且自定义一个 RecyclerAdapter继承自己封装的万能Adapter,RecyclerCommonAdapter<ChatData> , 并且复写对应方法,这里注意注释的为单条目方法,下边的为多条目方法:
如果有2个不同类型的条目,那么就用if else 去判断;
如果有3个不同的条目,同样的在getLayoutId()中只去return R.layout.item_chat_xxx ,即可;
也就是说,不管它有多少个不同的布局,我们只需要在这里去用服务器返回的字段对应的值去判断需要加载对应的布局文件就行;

注意 item.isMe 是服务器返回来的变量,而这个字段会有对应的值,比如此处:
is.Me = 1 表示 加载 自己聊天内容的布局;
is.Me = 0 表示 加载 朋友聊天内容的布局;

同样的,在实际开发过程中,如果有加载不同类型条目的需求,就只需要从服务器返回的数据中取出这个字段,然后判断它对应的值是什么,然后我们只需要根据它对应的值去加载它对应的布局文件;

这里 is.Me = 1 表示 加载 自己聊天内容的布局;
is.Me = 0 表示 加载 朋友聊天内容的布局;
是服务器已经规定好了的,我们只需要去加载对应布局就行

2.3 convert()方法是设置数据;

具体代码我会在讲完 RecyclerView后整体上传至github。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,900评论 25 708
  • 内容抽屉菜单ListViewWebViewSwitchButton按钮点赞按钮进度条TabLayout图标下拉刷新...
    皇小弟阅读 46,871评论 22 665
  • 原文链接:https://github.com/opendigg/awesome-github-android-u...
    IM魂影阅读 32,954评论 6 472
  • 小白是一个每天什么都不想的人,但又是个什么都会想的人。他可以天马行空,也可以平淡如水。没有人知道他在想什么,也...
    3a3a47df3b94阅读 166评论 0 0
  • 题目是第一季看的字幕组尽职尽责的名字翻译。 上学期开始看无耻之徒,只敢下了前两季,因为后来有要考试,当时也还有着准...
    亢龙有悔阅读 399评论 0 0