问题
Declaring
private List<SQLiteHelper> messages = new ArrayList<>();
privare MessagesAdapter mAdapter;
private RecyclerView messageList;
Initialising
messageList = (RecyclerView) findViewById(R.id.message_list);
messageList.setHasFixedSize(true);
messageList.setLayoutManager(linearLayoutManager);
mAdapter = new MessagesAdapter(messages);
messageList.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
Fetching
while (csr.moveToNext()) {
String mSender = csr.getString(csr.getColumnIndex(KEY_SENDER));
String mMessage = csr.getString(csr.getColumnIndex(KEY_MESSAGE));
String mTime = csr.getString(csr.getColumnIndex(KEY_TIME));
String mSeen = csr.getString(csr.getColumnIndex(KEY_SEEN));
String mTimer = csr.getString(csr.getColumnIndex(KEY_TIMER));
String mType = csr.getString(csr.getColumnIndex(KEY_TYPE));
messages.add(new SQLiteHelper(mSender, mMessage, mTime, mSeen, mTimer, mType));
mAdapter.notifyDataSetChanged();
}
No problem in fetching data but doesn't show when new data is added until i close the activity and open it again. I know stackoverflow has a lot of questions on notifydatasetchanged not working but mainly its for listviews and recyclerviews and none on sqlite data so im not sure whether this is even the right way or not. So can someone please help me through this
Full code of adapter
public class MessagesAdapter extends RecyclerView.Adapter<MessagesAdapter.MessageViewHolder>{
ChatData mHelper;
Cursor csr;
private List<SQLiteHelper> mMessagesHelperList;
private FirebaseAuth mAuth;
public MessagesAdapter(List<SQLiteHelper> mMessagesHelperList) {
this.mMessagesHelperList = mMessagesHelperList;
}
public void updateData(List<SQLiteHelper> pMessages){
if(pMessages== null || pMessages.size()==0)
return;
if (pMessages!= null && pMessages.size()>0)
this.mMessagesHelperList.clear();
this.mMessagesHelperList.addAll(pMessages);
notifyDataSetChanged();
}
public class MessageViewHolder extends RecyclerView.ViewHolder{
public TextView messageText;
public MessageViewHolder(View view) {
super(view);
mHelper = new ChatData(view.getContext(),"MessagePlus",null,1);
csr = mHelper.getAllQuestions3();
messageText = (TextView)view.findViewById(R.id.message_text_layout);
}
}
@Override
public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View V = LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_activity_chat,parent,false);
mAuth = FirebaseAuth.getInstance();
return new MessageViewHolder(V);
}
@Override
public void onBindViewHolder(final MessageViewHolder holder, int position) {
String mSender = null;
String mMessage = null;
String mTime;
String mSeen = null;
String mTimer;
String mType;
SQLiteHelper messagesHelper = mMessagesHelperList.get(position);
if (mSender != null && mSender.equals("Me")) {
holder.messageText.setBackgroundColor(Color.BLUE);
holder.messageText.setTextColor(Color.WHITE);
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) holder.messageText.getLayoutParams();
params.removeRule(RelativeLayout.ALIGN_PARENT_LEFT);
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
holder.messageText.setLayoutParams(params);
if (mSeen.equals("Yes")){
holder.messageText.setBackgroundColor(Color.CYAN);
}else{
holder.messageText.setBackgroundColor(Color.BLUE);
}
}else {
holder.messageText.setBackgroundColor(Color.GREEN);
holder.messageText.setTextColor(Color.BLACK);
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) holder.messageText.getLayoutParams();
params.removeRule(RelativeLayout.ALIGN_PARENT_RIGHT);
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
holder.messageText.setLayoutParams(params);
}
holder.messageText.setText(messagesHelper.getMessage());
}
@Override
public int getItemCount() {
return mMessagesHelperList.size();
}
}
回答1:
You are fetching the data in activity but not passing the new data to Recyclerview adapter, notifyAdapter works when the list of adapter is updated. In your case, you can create a method in adapter to get the new message, which you will call everytime new message is added and notify adapter there.
Update below code:
while (csr.moveToNext()) {
String mSender = csr.getString(csr.getColumnIndex(KEY_SENDER));
String mMessage = csr.getString(csr.getColumnIndex(KEY_MESSAGE));
String mTime = csr.getString(csr.getColumnIndex(KEY_TIME));
String mSeen = csr.getString(csr.getColumnIndex(KEY_SEEN));
String mTimer = csr.getString(csr.getColumnIndex(KEY_TIMER));
String mType = csr.getString(csr.getColumnIndex(KEY_TYPE));
messages.add(new SQLiteHelper(mSender, mMessage, mTime, mSeen, mTimer, mType));
//mAdapter.notifyDataSetChanged();
mAdapter.updateData(messages);
}
in your adapter class:
void updateData(List<SQLiteHelper> pMessages){
if(pMessages== null || pMessages.size()==0)
return;
if (pMessages!= null && pMessages.size()>0)
this.messages.clear();
this.messages.addAll(pMessages);
notifyDataSetChanged();
}
Hope it helps
回答2:
First update your list with data, then use notifyItemRangeInserted outside while loop as in
while (csr.moveToNext()) {
String mSender = csr.getString(csr.getColumnIndex(KEY_SENDER));
String mMessage = csr.getString(csr.getColumnIndex(KEY_MESSAGE));
String mTime = csr.getString(csr.getColumnIndex(KEY_TIME));
String mSeen = csr.getString(csr.getColumnIndex(KEY_SEEN));
String mTimer = csr.getString(csr.getColumnIndex(KEY_TIMER));
String mType = csr.getString(csr.getColumnIndex(KEY_TYPE));
messages.add(new SQLiteHelper(mSender, mMessage, mTime, mSeen, mTimer, mType));
}
mAdapter.notifyItemRangeInserted(0,messages.size());
来源:https://stackoverflow.com/questions/53774023/notifydatasetchanged-not-working-while-retrieving-sqlite-data