android - 带有多视图的回收器视图的最后一项搞砸了
问题描述
我正在尝试实现一个聊天应用程序,其中回收器视图具有多个视图布局。但是每个聊天的最后一项都没有到位,但是当我们向上滚动并向下滚动时,它又回到了它的位置。这是我的适配器:
@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>
解决方案
所以我在 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 返回了正确的布局。这就是为什么最后一个项目一开始搞砸了,但回收后又回到正确位置的原因。
谢谢,阿米尔侯赛因米尔扎伊。
推荐阅读
- android - 桌面文件的自定义通知到 Android 手机
- javascript - 如果对象还没有,如何向对象添加一些东西
- python - Python - 无法在工具提示下单击 Selenium 中的按钮,网页抛出请求错误
- azure - URL Rewrite 未在 Azure 上执行,几个项目
- python - 从函数中的while循环返回列表?
- c# - 通过动态创建 linq 查询,在 c# 中为 Sql Equivalent “column is null”创建 Linq 表达式
- javascript - 仅适用于实例的范围导入
- r - 使用 data.table 根据另一列中的因子级别将 NA 替换为一列中的新因子级别
- swift - 将框架添加到框架项目后单元测试失败
- android - Kotlin 中的非空值产生空指针异常