动态向回收者视图添加多个视图

时间:2018-07-30 21:39:26

标签: android android-studio android-recyclerview recycler-adapter recyclerview-layout

我正在创建一个聊天应用程序,在该应用程序中,我需要根据显示与特定用户的所有对话的聊天页面中的messageType填充另一个Xml文件。例如,如果messageType是图像,我想填充不同的xml,如果messageType是视频,我想填充不同的xml文件,并且类似地,对于文本和音频,每次都填充不同的xml文件。但是,在我的代码中,我在onCreateViewHolder方法中填充了一个通用xml。从模型类检索messageType。

任何帮助该怎么做?

谢谢!

2 个答案:

答案 0 :(得分:1)

您可以通过为每个messageType使用不同的“项目视图类型”值来实现。该逻辑的根源是适配器的getItemViewType()回调:

@Override
public int getItemViewType(int position) {
    if (isImage(position)) {
        return R.layout.layout_for_image;
    } else if (isVideo(position) {
        return R.layout.layout_for_video;
    } else {
        // and so on...
    }
}

我们在这里使用技巧:getItemViewType()只关心您返回int;它并不关心实际的int值是什么,因此我们使用布局ID作为返回值。这很好,因为它意味着您不必定义额外的常量,也不必跟踪0所使用的视图类型以及1所使用的视图类型,等等。

您还需要为每种视图类型创建不同种类的ViewHolder。传递给此方法的viewType参数将具有您从getItemViewType()返回的任何值,并且由于我们返回了布局ID,因此我们可以将获得的任何值进行膨胀。当然,我们仍然必须将其传递到右侧的ViewHolder,但这仍然使事情变得简单一些:

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    View itemView = inflater.inflate(viewType, parent, false);

    switch (viewType) {
        case R.layout.layout_for_image: return new ImageViewHolder(itemView);
        case R.layout.layout_for_video: return new VideoViewHolder(itemView);
        ...
    }
}

最后一件是具有约束力的:

@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
    switch (holder.getItemViewType()) {
        case R.layout.layout_for_image:
            bindImage(holder, position);
            break;

        case R.layout.layout_for_video:
            bindVideo(holder, position);
            break;

        ...
    }
}

答案 1 :(得分:0)

重写getViewType(int index)并返回不同的对象类型值,然后在onCreateViewHolder上获取它,并使用不同的ViewHolders填充正确的视图,相同类型的viewholder将在onBindViewHolder返回等于viewTypes。