I using the firebase API. to send and retrieve messages. However I am having trouble in trying to set layout for the sender/retriever so Messages will align left/right. At the moment I only have one layout which both the sender/retriever is using, but not sure on how to set different layouts.
public class MessageAdapter extends RecyclerView.Adapter<MessageViewHolder> {
private List<Message> messagesList;
private DatabaseReference databaseReference;
private DatabaseReference userDatabaseRef;
private FirebaseAuth firebaseAuth;
private Context context;
private String imageUrl;
public MessageAdapter(List<Message> messagesList) {
this.messagesList = messagesList;
}
@Override
public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Message c = messagesList.get(viewType);
String sender = c.getFrom();
databaseReference = FirebaseDatabase.getInstance().getReference().child("Users").child(sender);
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.messages_layout, parent, false);
return new MessageViewHolder(v);
}
@Override
public void onBindViewHolder(final MessageViewHolder viewHolder, final int index) {
final Message c = messagesList.get(index);
final String sender = c.getFrom();
databaseReference = FirebaseDatabase.getInstance().getReference().child("Users").child(sender);
databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
imageUrl = dataSnapshot.child("image").getValue(String.class);
viewHolder.setUserimage(context,imageUrl);
String name = dataSnapshot.child("name").getValue().toString();
viewHolder.displayName.setText(name);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
viewHolder.messageText.setText(c.getMessage());
viewHolder.time.setText(EpochtimeToDateAndTimeString(c.getTime()));
}
@Override
public int getItemCount() {
return messagesList.size();
}
public String EpochtimeToDateAndTimeString(long time) {
Date date = new Date(time);
DateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
format.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
String formatted = format.format(date);
return formatted;
}
}
MessageViewHolder
public class MessageViewHolder extends RecyclerView.ViewHolder {
public TextView messageText;
public TextView displayName;
public TextView time;
public ImageView showImage;
public MessageViewHolder(View view) {
super(view);
messageText = (TextView) view.findViewById(R.id.messagetext);
displayName = (TextView) view.findViewById(R.id.displayname);
time = (TextView) view.findViewById(R.id.timestamp);
showImage = (ImageView) view.findViewById(R.id.imageview_post_userimage3);
}
You should use different view holders for sender's and receiver's messages.
Create two layouts: R.layout.sender_message_layout and R.layout.receiver_message_layout
Create two viewholders: SenderMessageHolder and ReceiverMessageHolder .
Define view type integer constants:
public static final int VIEW_TYPE_SENDER = 1;
public static final int VIEW_TYPE_RECEIVER = 2;
Implement getItemViewType(int position) on your adapter:
if(messageList.get(position).getFrom().equals(...)) {
return VIEW_TYPE_SENDER;
} else {
return VIEW_TYPE_RECEIVER;
}
In onCreateViewHolder() function check view type and create different holders for different senders:
View v;
if(viewType == VIEW_TYPE_SENDER) {
v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.sender_message_layout, parent, false);
return new SenderMessageHolder(v);
} else {
v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.receiver_message_layout, parent, false);
return new ReceiverMessageHolder(v);
}
In onBindViewHolder() check holder instance to bind values to views accordingly:
if(holder instanceof SenderMessageHolder) {
((SenderMessageHolder) holder).textView.setText(...);
...
} else {
((ReceiverMessageHolder) holder).textView.setText(...);
...
}
Hope that it helps!
There are a couple of ways to do this. The way I would recommend is by overriding the public int getItemViewType(int position)
for your adapter. You must implement logic here to help you determine the layout file to return and returning a view type constant.
public static int INCOMING = 1;
public static int OUTGOING = 2;
@Override
public int getItemViewType(int position) {
int viewType = -1;
Message m = messagesList.get(position)
//Logic here determining if m is left or right aligned and
// return either
// MessageAdapter.OUTGOING OR MessageAdapter.INCOMING
return viewType;
}
Create a left-aligned layout file and a right-aligned layout file. Your new onCreateviewHolder()
adapter method will look something like this:
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Message c = messagesList.get(viewType);
String sender = c.getFrom();
databaseReference = FirebaseDatabase.getInstance().getReference().child("Users").child(sender);
View v;
if( viewType == MessageAdapter.INCOMING ) {
v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.messages_layout_left, parent, false);
}else if ( viewType == MessageAdapter.OUTGOING) {
v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.messages_layout_right, parent, false);
}
return new MessageViewHolder(v);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.