如何对传入和传出的聊天消息使用不同的布局
How to use different layouts for incoming & outgoing chat messages
我有一个消息设计。
2xml个文件负责设计:
recyclerview_item_incoming.xml
recyclerview_item_outgoing.xml
看起来像这样:
消息存储在 RecyclerView
中。
RecyclerView
通过 LiveData
-> Room
连接到 SQLite。
More Info
要使用 RecyclerView,我有 2 个 classes:
消息列表适配器:
package com.mardaunt.telesupp.recyclerview;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ListAdapter;
import com.mardaunt.telesupp.room.Message;
public class MessageListAdapter extends ListAdapter<Message, MessageViewHolder> {
public static int idMessage = 0; // I added that
public static int countMessages = 0; // I added that
public MessageListAdapter(@NonNull DiffUtil.ItemCallback<Message> diffCallback) {
super(diffCallback);
}
@Override
public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
countMessages = getItemCount();
//System.out.println(countMessages + " - This countMessages\n" + idMessage + "- This idMessage; " + viewType + " - viewType");
System.out.println(idMessage);
//if(idMessage >= countMessages) idMessage = 0;
// I need to pass the create index method of the current message.!!!!!!!!!!
// The getItem() function returns a Message object.
return MessageViewHolder.create(parent, getItem(idMessage));
}
@Override
public void onBindViewHolder(MessageViewHolder holder, int position) {
Message current = getItem(position);
//System.out.println(current.getId() + " " + current.getPhone() + " " + current.getText());
holder.bind(current.getPhone() ,current.getText()); // Бинтим только тело телефон и сообщение!
idMessage = position+1;
if(idMessage >= countMessages) idMessage = 0;
}
public static class MessageDiff extends DiffUtil.ItemCallback<Message> {
@Override
public boolean areItemsTheSame(@NonNull Message oldItem, @NonNull Message newItem) {
return oldItem == newItem;
}
@Override
public boolean areContentsTheSame(@NonNull Message oldItem, @NonNull Message newItem) {
return oldItem.getText().equals(newItem.getText());
}
}
}
MessageViewHolder:
package com.mardaunt.telesupp.recyclerview;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import com.mardaunt.telesupp.R;
import com.mardaunt.telesupp.room.Message;
class MessageViewHolder extends RecyclerView.ViewHolder {
private final TextView phoneItemView;
private final TextView messageItemView;
private MessageViewHolder(View itemView) {
super(itemView);
messageItemView = itemView.findViewById(R.id.text_view_message);
phoneItemView = itemView.findViewById(R.id.text_view_phone);
}
public void bind(String phone, String message) {
phoneItemView.setText(phone);
messageItemView.setText(message);
}
//The method decides which design to choose for the message bubble.
static MessageViewHolder create(ViewGroup parent, Message current) {
View view;
if (current.getNature().equals("outgoing"))
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recyclerview_item_outgoing, parent, false);
else view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recyclerview_item_incoming, parent, false);
return new MessageViewHolder(view);
}
}
和消息:
package com.mardaunt.telesupp.room;
import androidx.annotation.NonNull;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
@Entity(tableName = "messages_table")
public class Message {
@PrimaryKey(autoGenerate = true)
private int id;
private String phone;
private String text;
private String nature;
public Message(int id,
@NonNull String phone,
@NonNull String text,
@NonNull String nature
) {
this.id = id;
this.phone = phone;
this.text = text;
this.nature = nature; // incoming OR outgoing
}
public int getId(){return this.id;}
public String getPhone(){return this.phone;}
public String getText(){return this.text;}
public String getNature(){return this.nature;}
}
问题:
我希望传入消息位于左侧。传出消息位于右侧。
为此,我稍微更改了 MessageViewHolder
class:
的静态方法
//The method decides which design to choose for the message bubble.
static MessageViewHolder create(ViewGroup parent, Message current) {
View view;
if (current.getNature().equals("outgoing"))
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recyclerview_item_outgoing, parent, false);
else view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recyclerview_item_incoming, parent, false);
return new MessageViewHolder(view);
}
但问题是我不知道如何才能正确地将 Message 对象传递给此方法?
如您所见,我试图在 MessageListAdapter
class:
中传递 Message 对象
@Override
public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
countMessages = getItemCount();
// I need to pass the create index method of the current message.!!!!!!!!!!
// The getItem() function returns a Message object.
return MessageViewHolder.create(parent, getItem(idMessage));
}
@Override
public void onBindViewHolder(MessageViewHolder holder, int position) {
Message current = getItem(position);
holder.bind(current.getPhone() ,current.getText()); // Бинтим только тело телефон и сообщение!
idMessage = position+1;
if(idMessage >= countMessages) idMessage = 0;
}
我添加了 2 个静态变量(idMessage、countMessages),但这并不能正常工作。
如何为方法 MessageViewHolder.create(...)
添加 Message 对象?
GitHub 上的项目:https://github.com/MinorityMeaning/HelloApp
getItemViewType()
是确定项目布局的正确位置。所以你需要把逻辑移到那里,所以在适配器中覆盖它:
@Override
public int getItemViewType(int position) {
if (getItem(position).getNature().equals("outgoing"))
return R.layout.recyclerview_item_outgoing;
else
return R.layout.recyclerview_item_incoming;
}
并且反映在 onCreateViewHolder()
的 viewType
参数中,因此它拥有当前项目的正确布局。所以你会把它传递给 ViewHolder:
@Override
public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return MessageViewHolder.create(parent, viewType);
}
并在 ViewHolder 中将其设置为您的布局:
static MessageViewHolder create(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(viewType, parent, false);
return new MessageViewHolder(view);
}
我有一个消息设计。 2xml个文件负责设计:
recyclerview_item_incoming.xml
recyclerview_item_outgoing.xml
看起来像这样:
消息存储在 RecyclerView
中。
RecyclerView
通过 LiveData
-> Room
连接到 SQLite。
More Info
要使用 RecyclerView,我有 2 个 classes:
消息列表适配器:
package com.mardaunt.telesupp.recyclerview;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ListAdapter;
import com.mardaunt.telesupp.room.Message;
public class MessageListAdapter extends ListAdapter<Message, MessageViewHolder> {
public static int idMessage = 0; // I added that
public static int countMessages = 0; // I added that
public MessageListAdapter(@NonNull DiffUtil.ItemCallback<Message> diffCallback) {
super(diffCallback);
}
@Override
public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
countMessages = getItemCount();
//System.out.println(countMessages + " - This countMessages\n" + idMessage + "- This idMessage; " + viewType + " - viewType");
System.out.println(idMessage);
//if(idMessage >= countMessages) idMessage = 0;
// I need to pass the create index method of the current message.!!!!!!!!!!
// The getItem() function returns a Message object.
return MessageViewHolder.create(parent, getItem(idMessage));
}
@Override
public void onBindViewHolder(MessageViewHolder holder, int position) {
Message current = getItem(position);
//System.out.println(current.getId() + " " + current.getPhone() + " " + current.getText());
holder.bind(current.getPhone() ,current.getText()); // Бинтим только тело телефон и сообщение!
idMessage = position+1;
if(idMessage >= countMessages) idMessage = 0;
}
public static class MessageDiff extends DiffUtil.ItemCallback<Message> {
@Override
public boolean areItemsTheSame(@NonNull Message oldItem, @NonNull Message newItem) {
return oldItem == newItem;
}
@Override
public boolean areContentsTheSame(@NonNull Message oldItem, @NonNull Message newItem) {
return oldItem.getText().equals(newItem.getText());
}
}
}
MessageViewHolder:
package com.mardaunt.telesupp.recyclerview;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import com.mardaunt.telesupp.R;
import com.mardaunt.telesupp.room.Message;
class MessageViewHolder extends RecyclerView.ViewHolder {
private final TextView phoneItemView;
private final TextView messageItemView;
private MessageViewHolder(View itemView) {
super(itemView);
messageItemView = itemView.findViewById(R.id.text_view_message);
phoneItemView = itemView.findViewById(R.id.text_view_phone);
}
public void bind(String phone, String message) {
phoneItemView.setText(phone);
messageItemView.setText(message);
}
//The method decides which design to choose for the message bubble.
static MessageViewHolder create(ViewGroup parent, Message current) {
View view;
if (current.getNature().equals("outgoing"))
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recyclerview_item_outgoing, parent, false);
else view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recyclerview_item_incoming, parent, false);
return new MessageViewHolder(view);
}
}
和消息:
package com.mardaunt.telesupp.room;
import androidx.annotation.NonNull;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
@Entity(tableName = "messages_table")
public class Message {
@PrimaryKey(autoGenerate = true)
private int id;
private String phone;
private String text;
private String nature;
public Message(int id,
@NonNull String phone,
@NonNull String text,
@NonNull String nature
) {
this.id = id;
this.phone = phone;
this.text = text;
this.nature = nature; // incoming OR outgoing
}
public int getId(){return this.id;}
public String getPhone(){return this.phone;}
public String getText(){return this.text;}
public String getNature(){return this.nature;}
}
问题:
我希望传入消息位于左侧。传出消息位于右侧。
为此,我稍微更改了 MessageViewHolder
class:
//The method decides which design to choose for the message bubble.
static MessageViewHolder create(ViewGroup parent, Message current) {
View view;
if (current.getNature().equals("outgoing"))
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recyclerview_item_outgoing, parent, false);
else view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recyclerview_item_incoming, parent, false);
return new MessageViewHolder(view);
}
但问题是我不知道如何才能正确地将 Message 对象传递给此方法?
如您所见,我试图在 MessageListAdapter
class:
@Override
public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
countMessages = getItemCount();
// I need to pass the create index method of the current message.!!!!!!!!!!
// The getItem() function returns a Message object.
return MessageViewHolder.create(parent, getItem(idMessage));
}
@Override
public void onBindViewHolder(MessageViewHolder holder, int position) {
Message current = getItem(position);
holder.bind(current.getPhone() ,current.getText()); // Бинтим только тело телефон и сообщение!
idMessage = position+1;
if(idMessage >= countMessages) idMessage = 0;
}
我添加了 2 个静态变量(idMessage、countMessages),但这并不能正常工作。
如何为方法 MessageViewHolder.create(...)
添加 Message 对象?
GitHub 上的项目:https://github.com/MinorityMeaning/HelloApp
getItemViewType()
是确定项目布局的正确位置。所以你需要把逻辑移到那里,所以在适配器中覆盖它:
@Override
public int getItemViewType(int position) {
if (getItem(position).getNature().equals("outgoing"))
return R.layout.recyclerview_item_outgoing;
else
return R.layout.recyclerview_item_incoming;
}
并且反映在 onCreateViewHolder()
的 viewType
参数中,因此它拥有当前项目的正确布局。所以你会把它传递给 ViewHolder:
@Override
public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return MessageViewHolder.create(parent, viewType);
}
并在 ViewHolder 中将其设置为您的布局:
static MessageViewHolder create(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(viewType, parent, false);
return new MessageViewHolder(view);
}