首页 > 解决方案 > 带有多视图的回收器视图的最后一项搞砸了

问题描述

我正在尝试实现一个聊天应用程序,其中回收器视图具有多个视图布局。但是每个聊天的最后一项都没有到位,但是当我们向上滚动并向下滚动时,它又回到了它的位置。这是我的适配器:

     @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int 
       viewType) {

    mAuth = FirebaseAuth.getInstance();
    currentUserId = mAuth.getCurrentUser().getUid();
    View view;
    switch (viewType) {
        case TEXT_TYPE_OTHER:
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_single_layout, parent, false);
            return new TextMessageViewHolder(view);
        case TEXT_TYPE_USER:
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_single_layout_user, parent, false);
            return new TextMessageViewHolderUser(view);
        case IMAGE_TYPE_OTHER:
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_image_single_layout, parent, false);
            return new ImageMessageViewHolder(view);
        case IMAGE_TYPE_USER:
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_image_single_layout_user, parent, false);
            return new ImageMessageViewHolderUser(view);
        case IMAGE_TEXT_TYPE_OTHER:
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_image_single_layout_with_text, parent, false);
            return new ImageMessageWithTextViewHolder(view);
        case IMAGE_TEXT_TYPE_USER:
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_image_single_layout_with_text_user, parent, false);
            return new ImageMessageWithTextViewHolderUser(view);
    }
    return null;
}

public class TextMessageViewHolder extends RecyclerView.ViewHolder {
    private TextView time;
    private TextView messageText;
    //private CardView cardView;
    private TextView textDate;
    private View view;

    public TextMessageViewHolder(View view) {
        super(view);
        messageText = view.findViewById(R.id.message_text_layout);
        time = view.findViewById(R.id.time_text_layout);
        textDate = view.findViewById(R.id.text_chat_date);
        //cardView = itemView.findViewById(R.id.cardView);
        view = itemView.findViewById(R.id.text_message_view);
    }
}


public class TextMessageViewHolderUser extends RecyclerView.ViewHolder {
    private TextView timeUser;
    private TextView messageTextUser;
    private TextView textDateUser;
    //private CardView cardViewUser;
    private View view;

    public TextMessageViewHolderUser(View view) {
        super(view);
        messageTextUser = view.findViewById(R.id.message_text_layout_user);
        timeUser = view.findViewById(R.id.time_text_layout_user);
        textDateUser = view.findViewById(R.id.text_chat_date_user);
        //cardViewUser = itemView.findViewById(R.id.cardViewUser);
        view = itemView.findViewById(R.id.text_message_view_user);

    }
}

public class ImageMessageWithTextViewHolder extends RecyclerView.ViewHolder {
    private ImageView messageImage;
    //private CardView imageMessage;
    private TextView imageText;
    private TextView imageTime;
    private TextView imageTextDate;
    private View view;

    public ImageMessageWithTextViewHolder(View itemView) {
        super(itemView);
        imageText = itemView.findViewById(R.id.imageText_with_text);
        imageTime = itemView.findViewById(R.id.time_text_layout_image_with_text);
        messageImage = itemView.findViewById(R.id.message_image_layout_with_text);
        imageTextDate = itemView.findViewById(R.id.text_image_chat_date);
        view = itemView.findViewById(R.id.text_message_image_view);
        //imageMessage = itemView.findViewById(R.id.imageMessageWithText);
    }
}

public class ImageMessageWithTextViewHolderUser extends RecyclerView.ViewHolder {
    private ImageView messageImageUser;
    //private CardView imageMessageUser;
    private TextView imageTextUser;
    private TextView imageTimeUser;
    private TextView imageTextDateUser;
    private View view;

    public ImageMessageWithTextViewHolderUser(View itemView) {
        super(itemView);
        imageTextUser = itemView.findViewById(R.id.imageText_with_text_user);
        imageTimeUser = itemView.findViewById(R.id.time_text_layout_image_with_text_user);
        messageImageUser = itemView.findViewById(R.id.message_image_layout_with_text_user);
        imageTextDateUser = itemView.findViewById(R.id.text_image_chat_date_user);
        view = itemView.findViewById(R.id.text_message_image_user_view);

        //imageMessageUser = itemView.findViewById(R.id.imageMessageWithTextUser);
    }
}

public class ImageMessageViewHolder extends RecyclerView.ViewHolder {
    private ImageView messageImage;
    //private CardView cardView;
    private TextView imageTime;
    private TextView imageChatDate;
    private View view;

    public ImageMessageViewHolder(View itemView) {
        super(itemView);
        imageTime = itemView.findViewById(R.id.time_text_layout_image);
        //cardView = itemView.findViewById(R.id.imageMessage);
        messageImage = itemView.findViewById(R.id.message_image_layout);
        imageChatDate = itemView.findViewById(R.id.image_chat_date);
        view = itemView.findViewById(R.id.message_image_view);

    }
}

public class ImageMessageViewHolderUser extends RecyclerView.ViewHolder {
    private ImageView messageImageUser;
    //private CardView cardViewUser;
    private TextView imageTimeUser;
    private TextView imageChatDateUser;
    private View view;

    public ImageMessageViewHolderUser(View itemView) {
        super(itemView);
        imageTimeUser = itemView.findViewById(R.id.time_text_layout_image_user);
        //cardViewUser = itemView.findViewById(R.id.imageMessageUser);
        messageImageUser = itemView.findViewById(R.id.message_image_layout_user);
        imageChatDateUser = itemView.findViewById(R.id.image_chat_date_user);
        view = itemView.findViewById(R.id.message_image_view_user);

    }
}

        public int getItemViewType(int position) {
        switch (mMessageList.get(position).getType()){
        case 0:
            if (mMessageList.get(position).getFrom().equals(currentUserId))
                return TEXT_TYPE_USER;
            else
                return TEXT_TYPE_OTHER;
        case 1:
            if (mMessageList.get(position).getFrom().equals(currentUserId))
                return IMAGE_TYPE_USER;
            else
                return IMAGE_TYPE_OTHER;
        case 2:
            if (mMessageList.get(position).getFrom().equals(currentUserId))
                return IMAGE_TEXT_TYPE_USER;
            else
                return IMAGE_TEXT_TYPE_OTHER;
        default:
            return 1234567890;
    }
}


public void onBindViewHolder(final RecyclerView.ViewHolder holder, int listPosition) {

    final Messages object = mMessageList.get(holder.getAdapterPosition());
    final String fromUser = object.getFrom();
    final String lastSeenTime = DateFormat.format("HH:mm", new Date(object.getTime())).toString();
    RequestBuilder<Drawable> thumbnailRequestBlogImage;
    thumbnailRequestBlogImage =glide.load(object.getThumb());

        switch (holder.getItemViewType()) {
            case TEXT_TYPE_USER:
                    ((TextMessageViewHolderUser) holder).messageTextUser.setText(object.getMessage());
                    ((TextMessageViewHolderUser) holder).timeUser.setText(lastSeenTime);
                break;
            case TEXT_TYPE_OTHER:
                    ((TextMessageViewHolder) holder).messageText.setText(object.getMessage());
                    ((TextMessageViewHolder) holder).time.setText(lastSeenTime);
                break;
            case IMAGE_TYPE_USER:
                    ((ImageMessageViewHolderUser) holder).imageTimeUser.setText(lastSeenTime);
                   glide.load(object.getImage())
                            .apply(new RequestOptions().dontAnimate().dontTransform())
                            .thumbnail(thumbnailRequestBlogImage)
                            .listener(new RequestListener<Drawable>() {
                                @Override
                                public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                                    return false;
                                }

                                @Override
                                public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                                    return false;
                                }
                            })
                            .into(((ImageMessageViewHolderUser) holder).messageImageUser);
                break;
            case IMAGE_TYPE_OTHER:

                    ((ImageMessageViewHolder) holder).imageTime.setText(lastSeenTime);
                    glide.load(object.getImage())
                            .apply(new RequestOptions().dontAnimate().dontTransform())
                            .thumbnail(thumbnailRequestBlogImage)
                            .listener(new RequestListener<Drawable>() {
                                @Override
                                public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                                    return false;
                                }

                                @Override
                                public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                                    return false;
                                }
                            })
                            .into(((ImageMessageViewHolder) holder).messageImage);
                break;
            case IMAGE_TEXT_TYPE_USER:

                    ((ImageMessageWithTextViewHolderUser) holder).imageTextUser.setText(object.getImageText());
                    ((ImageMessageWithTextViewHolderUser) holder).imageTimeUser.setText(lastSeenTime);

                    glide.load(object.getImage())
                            .apply(new RequestOptions().dontAnimate().dontTransform())
                            .thumbnail(thumbnailRequestBlogImage)
                            .listener(new RequestListener<Drawable>() {
                                @Override
                                public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                                    return false;
                                }

                                @Override
                                public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                                    return false;
                                }
                            })
                            .into(((ImageMessageWithTextViewHolderUser) holder).messageImageUser);
                break;
            case IMAGE_TEXT_TYPE_OTHER:

                    ((ImageMessageWithTextViewHolder) holder).imageText.setText(object.getImageText());
                    ((ImageMessageWithTextViewHolder) holder).imageTime.setText(lastSeenTime);

                    glide.load(object.getImage())
                            .apply(new RequestOptions().dontAnimate().dontTransform())
                            .thumbnail(thumbnailRequestBlogImage)
                            .listener(new RequestListener<Drawable>() {
                                @Override
                                public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                                    return false;
                                }

                                @Override
                                public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                                    return false;
                                }
                            })
                            .into(((ImageMessageWithTextViewHolder) holder).messageImage);

                break;
        }
}

我正在使用 firestore 发送和获取消息。它只发生在最后一条消息中。 这是我打开 chatActivity 时的屏幕截图。

这是我向上滚动然后向下滚动时的屏幕截图。 我什至尝试设置 holder.setIsRecyclable(false) 但仍然没有成功。这是chatActivity XML:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#cfd8dc"
tools:context=".Activities.ChatActivity">

<android.support.v7.widget.RecyclerView
            android:layout_above="@+id/linearLayout"
            android:id="@+id/messages_list"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        </android.support.v7.widget.RecyclerView>

<LinearLayout
    android:id="@+id/linearLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentStart="true"
    android:background="@android:color/white"
    android:orientation="horizontal"
    android:weightSum="10">

    <ImageButton
        android:layout_gravity="center"
        android:id="@+id/chat_add_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:alpha="0.5"
        android:background="@android:color/white"
        android:padding="10dp"
        app:srcCompat="@drawable/ic_add_black_24dp" />

    <EditText
        android:id="@+id/chat_message_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="8"
        android:background="@android:color/white"
        android:ems="10"
        android:hint="Enter Message..."
        android:inputType="textPersonName"
        android:paddingBottom="12dp"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:paddingTop="14dp" />

    <ImageButton
        android:layout_gravity="center"
        android:id="@+id/chat_send_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:alpha="0.5"
        android:background="@android:color/white"
        android:padding="10dp"
        app:srcCompat="@drawable/ic_send_black_24dp" />
</LinearLayout>
</RelativeLayout>

标签: androidandroid-recyclerview

解决方案


所以我在 onCreateViewHolder 中获取 currentUserId,

 @Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int 
   viewType) {

        mAuth = FirebaseAuth.getInstance();
        currentUserId = mAuth.getCurrentUser().getUid();
       ........}

然后使用它在 getItemView() 中返回 itemview 类型,

public int getItemViewType(int position) {
    switch (mMessageList.get(position).getType()){
    case 0:
        if (mMessageList.get(position).getFrom().equals(currentUserId))
            return TEXT_TYPE_USER;
        else
            return TEXT_TYPE_OTHER;
    case 1:
        if (mMessageList.get(position).getFrom().equals(currentUserId))
            return IMAGE_TYPE_USER;
        else
            return IMAGE_TYPE_OTHER;
    case 2:
        if (mMessageList.get(position).getFrom().equals(currentUserId))
            return IMAGE_TEXT_TYPE_USER;
        else
            return IMAGE_TEXT_TYPE_OTHER;
    default:
        return 1234567890;
    }
}

所以,我发现当膨胀最后一个消息项(这是我的列表中的第一个,因为我以相反的顺序显示 recyclerview)时,我的 currentUserId 变量给出了 null,所以 getItemViewType 返回了另一个布局,但是在回收 currentUserId 之后有值所以 getItemViewType 返回了正确的布局。这就是为什么最后一个项目一开始搞砸了,但回收后又回到正确位置的原因。

谢谢,阿米尔侯赛因米尔扎伊。


推荐阅读