我正在尝试实现一个聊天应用,其中Recycler视图有多个视图布局。但是每次聊天的最后一项都没有到位,但是当我们向上滚动并返回时,它会回到原位。 这是我的适配器:
@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发送和获取消息。它只发生在最后一条消息上。 Here's the screenshot when I open chatActivity.
Here's the screenshot when I scroll up and then again down. 我甚至尝试过设置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>
答案 0 :(得分:0)
所以我在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;
}
}
所以,我发现当膨胀最后一个消息项(这是我的第一个列表,因为我以相反的顺序显示了recyclelerview)时,我的currentUserId变量给出了null,所以getItemViewType返回了另一个布局,但之后回收currentUserId有值,所以getItemViewType返回正确的布局。这就是为什么最后一个项目一开始就搞乱了,但是在回收之后又回到了正确的位置。
谢谢,Amir Hossein Mirzaei。