RecycleView具有多种类型的子视图

时间:2016-03-09 12:06:23

标签: android android-recyclerview

我有一个RecycleView和一个RecycleViewAdapter,所有内容都适用于单一类型的Row,然后我添加了一个新的Row(所以现在我有2种行)并且列表开始表现得很奇怪。

一旦列表显示行正确,然后我开始添加元素到列表,我期望第一种行但应用程序显示第二种类型的行,有时它可以工作,其他时候我期望第二种,应用程序播放第一种。

滚动列表有时会随机更改行的类型。

查看日志并使用调试器一切看起来都很好。

有什么建议吗?

这是代码的一部分:

完整代码:

 public class ChatAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements com.timehop.stickyheadersrecyclerview.StickyRecyclerHeadersAdapter {

    private Context context;
    private Fragment fragment;
    private List<Message> messages;
    private boolean isMine;

    private int sent_imageRowResId = R.layout.row_messages_image_sent;
    private int sent_videoRowResId = R.layout.row_messages_video_sent;
    private int sent_audioRowResId = R.layout.row_messages_audio_sent;
    private int sent_textRowResId = R.layout.row_messages_text_sent;

    private int recv_imageRowResId = R.layout.row_messages_image_recv;
    private int recv_videoRowResId = R.layout.row_messages_video_recv;
    private int recv_audioRowResId = R.layout.row_messages_audio_recv;
    private int recv_textRowResId = R.layout.row_messages_text_recv;

    private static final int TEXT = 1;
    private static final int VIDEO = 2;
    private static final int IMAGE = 3;
    private static final int AUDIO = 4;


    public ChatAdapter(Context context, List<Message> messages, Fragment fragment) {
        this.fragment = fragment;
        this.context = context;
        this.messages = messages;
    }


    @Override
    public int getItemViewType(int position) {   
        return position;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int position) {
        Message message = messages.get(position);
        String senderAccountIdentifier = message.getSenderAccountIdentifier();

        isMine = senderAccountIdentifier.equals(userAccountIdentifier);

        int viewType = TEXT;

        if (message instanceof TextMessage) viewType = TEXT;
        else if (message instanceof VideoMessage) viewType = VIDEO;
        else if (message instanceof ImageMessage)viewType = IMAGE;
        else if (message instanceof AudioMessage) viewType = AUDIO;

      if (viewType == IMAGE) {
            View view = LayoutInflater.from(parent.getContext()).inflate(isMine ? sent_imageRowResId : recv_imageRowResId, parent, false);
            ViewHolderImage viewHolder = new ViewHolderImage(view);
            return viewHolder;
        } else if (viewType == VIDEO) {
            View view = LayoutInflater.from(parent.getContext()).inflate(isMine ? sent_videoRowResId : recv_videoRowResId, parent, false);
            ViewHolderVideo viewHolder = new ViewHolderVideo(view);
            return viewHolder;
        } else if (viewType == AUDIO) {
            View view = LayoutInflater.from(parent.getContext()).inflate(isMine ? sent_audioRowResId : recv_audioRowResId, parent, false);
            ViewHolderAudio viewHolder = new ViewHolderAudio(view);
            return viewHolder;
        } else {
            View view = LayoutInflater.from(parent.getContext()).inflate(isMine ? sent_textRowResId : recv_textRowResId, parent, false);
            ViewHolderText viewHolder = new ViewHolderText(view);
            return viewHolder;
        }
    }

    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {    
        if (holder instanceof BaseViewHolder) {

            final Message message = messages.get(position);

            final BaseViewHolder bvh = (BaseViewHolder) holder;
            bvh.dateTextView.setText(getDateString(position));
            bvh.senderTextView.setVisibility(View.GONE);

            bvh.rowMessage.setActivated(selectedItems.get(position, false));

            if (bvh instanceof ViewHolderText) {
                if (message instanceof TextMessage) {
                    TextMessage textMessage = (TextMessage) message;
                    ViewHolderText viewHolderText = (ViewHolderText) bvh;
                    viewHolderText.init(textMessage);
                }
            }
        }
    }

    @Override
    public int getItemCount() {
        return messages.size();
    }

修改

使用几乎完整的代码进行更新

这两行的差异(我只使用文本一行)只是文本的颜色和布局重力

编辑 - 已解决

更改getItemViewType()中的回报已解决了这个问题,我已将return viewType替换为return position,并且已在onCreateViewHolder中移动了一些逻辑。

1 个答案:

答案 0 :(得分:4)

遵循这种方法

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    class ViewHolder1 extends RecyclerView.ViewHolder {
        ...
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
    switch(getItemViewType(position)){
        case 1: // put your values in the view
        case 2: // put your values in the view
    }


    class ViewHolder2 extends RecyclerView.ViewHolder {
        ...
    }

    @Override
    public int getItemViewType(int position) {
        // for your different positions, return different numbers say 1, 2 these numbers will signify your view types 
        return position viewType;
    }

    public int getViewTypeCount(){
         return 2;
    }


    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
         switch (viewType) {
             case 1: // handle your viewholder 1
             case 2: //handle your viewholder 2
         }
    }
}