问题
I was trying to add & show messages dynamically in recycler view but I could not figure out how to send proper data type to it's adapter. In "getNewMessage(dataSnapshot) " function, I have to add all messages to list and send it to recycler view via adapter. I tried both
MessageModel model = dataSnapshot.getValue(MessageModel.class)
and creating a SampleModel that contains List<MessageModel> list
, and
SampleModel model = dataSnapshot.getValue(SampleModel.class);
They didn't work. Here sample JSON file that created with sending message:
"chat" : {
"-Ksbjn0yCEB6EXhNNCM5" : {
"author" : "Ali Alacan",
"content" : "dummy content",
"date" : "Mon Aug 28 10:29:50 GMT+03:00 2017",
"id" : "H6huNPUggjtugjsERPCRSAp1"
},
"-KsbjpUtjp0oeipjjxMI" : {
"author" : "Ali Alacan",
"content" : "dummy content",
"date" : "Mon Aug 28 10:30:00 GMT+03:00 2017",
"id" : "H6huNPUggjtugjsERPCRSAp1"
}
I'm adding new messages with code below which I learnt from firebase docs.
@Exclude
public Map<String, Object> toMap(MessageModel messageModel) {
HashMap<String, Object> result = new HashMap<>();
result.put("id", messageModel.getId());
result.put("author", messageModel.getAuthor());
result.put("content", messageModel.getContent());
result.put("date", messageModel.getDate());
return result;
}
private void sendMessage() {
if (!TextUtils.isEmpty(etMessage.getText())) {
Date currentTime = Calendar.getInstance().getTime();
String key = firebaseDatabase.push().getKey();
MessageModel message = new MessageModel(UserData.getInstance().getUserId(), UserData.getInstance().getName(), "dummy content", currentTime.toString());
Map<String, Object> messageValues = toMap(message);
Map<String, Object> childUpdates = new HashMap<>();
childUpdates.put("/chat/" + key, messageValues);
childUpdates.put("/user-chat/" + UserData.getInstance().getUserId() + "/" + key, messageValues);
firebaseDatabase.updateChildren(childUpdates);
} else {
Snackbar snackbar = Snackbar
.make(getActivity().findViewById(R.id.dashboard_container), "Enter a message please ! " + UserData.getInstance().getName(), Snackbar.LENGTH_LONG);
snackbar.show();
}
}
My MessageModel is:
public class MessageModel {
String id;
String author;
String content;
String date;
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public MessageModel(String id, String author, String content, String date) {
this.id = id;
this.author = author;
this.content = content;
this.date = date;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public MessageModel() {
}
}
And firebase listener
firebaseDatabase.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
getNewMessage(dataSnapshot);
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
// getNewMessage(dataSnapshot);
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
// taskDeletion(dataSnapshot);
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
RecyclerView Adapter:
public class MyMessageRecyclerViewAdapter extends RecyclerView.Adapter<MyMessageRecyclerViewAdapter.ViewHolder> {
private final List<MessageModel> mValues;
private final OnListFragmentInteractionListener mListener;
public MyMessageRecyclerViewAdapter(List<MessageModel> items, OnListFragmentInteractionListener listener) {
mValues = items;
mListener = listener;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_chat, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.mItem = mValues.get(position);
holder.mIdView.setText(mValues.get(position).getId());
holder.mContentView.setText(mValues.get(position).getContent());
holder.mAuthor.setText(mValues.get(position).getAuthor());
holder.mDate.setText(mValues.get(position).getDate());
holder.mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (null != mListener) {
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
mListener.onListFragmentInteraction(holder.mItem);
}
}
});
}
@Override
public int getItemCount() {
return mValues.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public final View mView;
public final TextView mIdView;
public final TextView mContentView;
TextView mAuthor;
TextView mDate;
public MessageModel mItem;
public ViewHolder(View view) {
super(view);
mView = view;
mIdView = (TextView) view.findViewById(R.id.id);
mContentView = (TextView) view.findViewById(R.id.content);
mAuthor = (TextView) view.findViewById(R.id.author);
mDate = (TextView) view.findViewById(R.id.date);
}
@Override
public String toString() {
return super.toString() + " '" + mContentView.getText() + "'";
}
}
Sorry for reading such a long post and thank you for your time.
回答1:
You don't need to use your toMap anymore, it is making you more confused on what you're doing since You already have a POJO.
Make a List in your Activity.
ArrayList<MessageModel> myListModel = new ArrayList<MessageModel>();
Do this on your firebase Listener. Make a List on your Activity
This is for Child Added.
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
MessageModel tempMessage = dataSnapshot.getValue(MessageModel.class);
myListModel.add(tempRace);
}
Now That you have a List Model. By using the onChildAdeed by Firebase. Use this to your supply your Adapter Model and apply it.
IMPORTANT FOR FIREBASE. In everyquery for the fire base, if you need to do something AFTER the anything else is done ex: "onChildAdded" You would need to add another listener to THE SAME DatabaseReference in your case. I have no idea, you did not include your activity even your DatabaseReference so I would provide one.
DatabaseReference myReference = firebaseDatabase.getReferane("chat");
myReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
MyMessageRecyclerAdapter myMessageAdapter= new MyMessageRecyclerAdapter(myListModel, listener);
//now you have to apply this to the RecyclerView.
yourWhateverNameofTheRecyclerview.SetAdapter(myMessageAdater);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
来源:https://stackoverflow.com/questions/45914759/android-firebase-database-adding-items-with-keys-to-recycler-view