im trying to update books on firebase but whenever i click update a new table is created
this is the search page
AdminSearch.java
public class AdminSearch extends AppCompatActivity {
EditText searchbarr;
RecyclerView recyclerVieww;
DatabaseReference referencee;
ArrayList<String> BookNameLists;
ArrayList<String> AuthorNameLists;
ArrayList<String> PicLists;
ArrayList<String> PublisherLists;
ArrayList<String> LinkLists;
ArrayList<String> DescriptionLists;
ArrayList<String>UidList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_adminsearch);
searchbarr = (EditText) findViewById(R.id.searchbar);
referencee = FirebaseDatabase.getInstance().getReference();
referencee.keepSynced(true);
recyclerVieww = (RecyclerView) findViewById(R.id.rv);
recyclerVieww.setHasFixedSize(true);
recyclerVieww.setLayoutManager(new LinearLayoutManager(this));
recyclerVieww.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
BookNameLists = new ArrayList<>();
PublisherLists = new ArrayList<>();
AuthorNameLists = new ArrayList<>();
LinkLists = new ArrayList<>();
PicLists = new ArrayList<>();
DescriptionLists=new ArrayList<>();
UidList=new ArrayList<>();
searchbarr.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
if (!s.toString().isEmpty()) {
setAdapter(s.toString());
}
else{
BookNameLists.clear();
AuthorNameLists.clear();
PicLists.clear();
PublisherLists.clear();
DescriptionLists.clear();
UidList.clear();
}
}
private void setAdapter(final String searchedString) {
referencee.child("books").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
BookNameLists.clear();
AuthorNameLists.clear();
PicLists.clear();
PublisherLists.clear();
DescriptionLists.clear();
UidList.clear();
int counter=0;
for(DataSnapshot snapshot:dataSnapshot.getChildren()){
String uid = snapshot.getKey();
String desc = snapshot.child("Desc").getValue(String.class);
String bookname = snapshot.child("bookname").getValue(String.class);
String author = snapshot.child("author").getValue(String.class);
String image = snapshot.child("image").getValue(String.class);
String publisher = snapshot.child("Publisher").getValue(String.class);
String link=snapshot.child("link").getValue(String.class);
String decscription=snapshot.child("Desc").getValue(String.class);
try {
if ((bookname.toLowerCase().contains(searchedString.toLowerCase())) || (author.toLowerCase().contains(searchedString.toLowerCase()))) {
UidList.add(uid);
BookNameLists.add(bookname);
AuthorNameLists.add(author);
PublisherLists.add(publisher);
PicLists.add(image);
DescriptionLists.add(decscription);
LinkLists.add(link);
counter++;
}
if(BookNameLists.isEmpty() && AuthorNameLists.isEmpty()){
Toast.makeText(getApplicationContext(),"not found",Toast.LENGTH_LONG).show();
}
}
catch (Exception e){
}
if(counter==15){
break;
}
AdminSearchAdapter adminSearchAdapter = new AdminSearchAdapter(AdminSearch.this, BookNameLists, AuthorNameLists, PicLists, PublisherLists,DescriptionLists,LinkLists,UidList);
recyclerVieww.setAdapter(adminSearchAdapter);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
});
}
the adapter class for the search page
AdminSearchAdapter.java
public class AdminSearchAdapter extends RecyclerView.Adapter<AdminSearchAdapter.EditViewHolder> {
Context c;
ArrayList<String> BookNameLists;
ArrayList<String> AuthorNameLists;
ArrayList<String> PicLists;
ArrayList<String> PublisherLists;
ArrayList<String>DescriptionLists;
ArrayList<String>LinkLists;
LinearLayout booklayoutt;
ArrayList<String>UidList;
FirebaseDatabase db;
DatabaseReference referencee;
public String key;
class EditViewHolder extends RecyclerView.ViewHolder{
ImageView bookimages;
TextView booknamess, authornamess,publisherss;
public EditViewHolder(#NonNull View itemView) {
super(itemView);
bookimages = itemView.findViewById(R.id.Bookimg);
booknamess = itemView.findViewById(R.id.BookName);
authornamess = itemView.findViewById(R.id.AuthorName);
publisherss = itemView.findViewById(R.id.Publications);
booklayoutt=itemView.findViewById(R.id.LinLayout);
referencee = FirebaseDatabase.getInstance().getReference();
referencee.keepSynced(true);
}
}
public AdminSearchAdapter(Context c1, ArrayList<String> bookNameLists, ArrayList<String> authorNameLists, ArrayList<String> picLists, ArrayList<String> publisherLists, ArrayList<String> descriptionLists, ArrayList<String> linkLists,ArrayList<String> uidList) {
c = c1;
BookNameLists = bookNameLists;
AuthorNameLists = authorNameLists;
PicLists = picLists;
PublisherLists=publisherLists;
DescriptionLists=descriptionLists;
LinkLists=linkLists;
UidList=uidList;
}
#NonNull
#Override
public AdminSearchAdapter.EditViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(c).inflate(R.layout.activity_search_layout,parent,false);
return new AdminSearchAdapter.EditViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final EditViewHolder holder, final int position) {
holder.booknamess.setText(BookNameLists.get(position));
holder.authornamess.setText(AuthorNameLists.get(position));
holder.publisherss.setText(PublisherLists.get(position));
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(c, AdminBookdetails.class);
i.putExtra("uid",UidList.get(position));
i.putExtra("booknamess",BookNameLists.get(position));
i.putExtra("Images",PicLists.get(position));
i.putExtra("author_names",AuthorNameLists.get(position));
i.putExtra("publisher_names",PublisherLists.get(position));
i.putExtra("descriptions",DescriptionLists.get(position));
i.putExtra("links",LinkLists.get(position));
c.startActivity(i);
}
});
Glide.with(c).asBitmap().load(PicLists.get(position)).placeholder(R.mipmap.ic_launcher_round).into(holder.bookimages);
}
#Override
public int getItemCount() {
return BookNameLists.size();
}
this is the book details layout page where onlick the specific books details are sent and where i want to update it
AdminBookdetails.java
public class AdminBookdetails extends AdminSearch {
EditText titles,authors,pubs,linkss,descss,bookid;
Bookdeets bookdeets;
String key;
Button update;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_adminbooksdetails);
titles = (EditText) findViewById(R.id.bknames);
authors = (EditText) findViewById(R.id.anames);
pubs = (EditText) findViewById(R.id.pnames);
linkss = (EditText) findViewById(R.id.bklinks);
descss = (EditText) findViewById(R.id.bkdescriptions);
update=(Button)findViewById(R.id.updatebtn);
bookid=(EditText)findViewById(R.id.uid);
bookdeets=new Bookdeets();
final DatabaseReference databaseReference=FirebaseDatabase.getInstance().getReference().child("books");
String uid = getIntent().getStringExtra("uid");
bookid.setText(uid,TextView.BufferType.EDITABLE);
String Bname = getIntent().getStringExtra("booknamess");
titles.setText(Bname,TextView.BufferType.EDITABLE);
String Author = getIntent().getStringExtra("author_names");
authors.setText(Author,TextView.BufferType.EDITABLE);
String publisher = getIntent().getStringExtra("publisher_names");
pubs.setText(publisher,TextView.BufferType.EDITABLE);
final String Link = getIntent().getStringExtra("links");
linkss.setText(Link,TextView.BufferType.EDITABLE);
String Desc = getIntent().getStringExtra("descriptions");
descss.setText(Desc);
descss.setMovementMethod(new ScrollingMovementMethod());
update.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String Title = titles.getText().toString().trim();
String Author = authors.getText().toString().trim();
String Publisher = pubs.getText().toString().trim();
String Link = linkss.getText().toString().trim();
String Desc = descss.getText().toString().trim();
String Uid=bookid.getText().toString().trim();
Toast.makeText(getApplicationContext(),""+Title,Toast.LENGTH_SHORT).show();
bookdeets.setBookname(titles.getText().toString().trim());
bookdeets.setAuthor(authors.getText().toString().trim());
bookdeets.setPublisher(pubs.getText().toString().trim());
bookdeets.setLink(linkss.getText().toString().trim());
bookdeets.setDesc(descss.getText().toString().trim());
bookdeets.setId(bookid.getText().toString().trim());
databaseReference.push().setValue(bookdeets);
if(TextUtils.isEmpty(Title) ||TextUtils.isEmpty(Author)||TextUtils.isEmpty(Publisher)||TextUtils.isEmpty(Link)||TextUtils.isEmpty(Desc)){
titles.setError("Field cant be empty");
}
}
});
}
Use this code in AdminBookdetails.java
String Title = titles.getText().toString().trim();
String Author = authors.getText().toString().trim();
String Publisher = pubs.getText().toString().trim();
String Link = linkss.getText().toString().trim();
String Desc = descss.getText().toString().trim();
String Uid=bookid.getText().toString().trim();
HashMap<String, Object> map = new HashMap<>();
map.put("bookName", Title);
map.put("author", Author);
map.put("publisher", Publisher);
map.put("link", Link);
map.put("desc", Desc);
map.put("id", Uid);
databaseReference.child(Uid).updateChildren(map); //To Update value
To update use
databaseReference.child(Uid).updateChildren(map);
To add use
databaseReference.child(Uid).setValue(map);
Related
I have this recyclerview, when I click on an item I want to get the data in the red square from database.
And I want to show it like that
This is how I save it :
Save.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.GINGERBREAD)
#Override
public void onClick(View v) {
String refernce = TextRef.getEditText().getText().toString();
String nompdv = textNomPdv.getEditText().getText().toString();
String etat = textEtatCommande.getEditText().getText().toString();
String datecommande = TextDateCommande.getEditText().getText().toString();
String produitcommande = textProduit.getEditText().getText().toString();
String qntcommande = editTextProduitQnt.getEditText().getText().toString();
DatabaseReference newPost = reference.child(refernce);
newPost.child("refernce").setValue(refernce);
newPost.child("nompdv").setValue(nompdv);
newPost.child("etat").setValue(etat);
newPost.child("datecommande").setValue(datecommande);
newPost.child("user_id").setValue(uid);
Map<String, Object> values = new HashMap<>();
values.put(produitcommande, qntcommande);
DatabaseReference produitRef = reference.child(refernce).child("produit");
produitRef.updateChildren(values);
This is how I send data from first activity (recyclerview) :
v.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(view.getContext(), Order_detail.class);
int pos = v.getAdapterPosition();
if (pos != RecyclerView.NO_POSITION) {
Order clickedDataItem = listArray.get(pos);
intent.putExtra("nompdv", clickedDataItem.getNompdv());
intent.putExtra("reference", clickedDataItem.getRefernce());
intent.putExtra("datecommande", clickedDataItem.getDatecommande());
intent.putExtra("etat", clickedDataItem.getEtat());
}
view.getContext().startActivity(intent);
}
});
How to do to get the products and their quantities when clicking on an item in recyclerview?
Update : This my Order class :
public class Order implements Serializable {
public String refernce, nompdv, etat, datecommande, produitcommande, qntcommande;
String user_id;
public Order(){}
public Order(String refernce, String nompdv, String etat, String datecommande, String produitcommande, String qntcommande, String user_id) {
this.refernce = refernce;
this.nompdv = nompdv;
this.etat = etat;
this.datecommande = datecommande;
this.produitcommande = produitcommande;
this.qntcommande = qntcommande;
this.user_id = user_id;
}
public String getRefernce() {
return refernce;
}
public void setRefernce(String refernce) {
this.refernce = refernce;
}
public String getNompdv() {
return nompdv;
}
public void setNompdv(String nompdv) {
this.nompdv = nompdv;
}
public String getEtat() {
return etat;
}
public void setEtat(String etat) {
this.etat = etat;
}
public String getDatecommande() {
return datecommande;
}
public void setDatecommande(String datecommande) {
this.datecommande = datecommande;
}
public String getProduitcommande() {
return produitcommande;
}
public void setProduitcommande(String produitcommande) {
this.produitcommande = produitcommande;
}
public String getQntcommande() {
return qntcommande;
}
public void setQntcommande(String qntcommande) {
this.qntcommande = qntcommande;
}
public String getUser_id() {
return user_id;
}
public void setUser_id(String user_id) {
this.user_id = user_id;
}
}
The form how I save data
Update 2 :
This the Adapter for the recyclerview :
public class CommandeAdapter extends
RecyclerView.Adapter<CommandeAdapter.CommandeViewHolder> {
List<Order> listArray;
public CommandeAdapter(List<Order> List) {
this.listArray = List;
}
#NonNull
#Override
public CommandeAdapter.CommandeViewHolder onCreateViewHolder(#NonNull #NotNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.commande_model, parent, false);
return new CommandeViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull #NotNull CommandeAdapter.CommandeViewHolder holder, int position) {
CommandeViewHolder v = (CommandeViewHolder) holder;
final Order dataa = listArray.get(position);
v.nom_pdv.setText(dataa.getNompdv());
v.date.setText(dataa.getDatecommande());
v.etat.setText(dataa.getEtat());
v.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(view.getContext(), Order_detail.class);
int pos = v.getAdapterPosition();
if (pos != RecyclerView.NO_POSITION) {
Order clickedDataItem = listArray.get(pos);
intent.putExtra("nompdv", clickedDataItem.getNompdv());
intent.putExtra("reference", clickedDataItem.getRefernce());
intent.putExtra("datecommande", clickedDataItem.getDatecommande());
intent.putExtra("etat", clickedDataItem.getEtat());
}
}
view.getContext().startActivity(intent);
}
});
}
public class CommandeViewHolder extends RecyclerView.ViewHolder {
TextView nom_pdv, date, etat;
public CommandeViewHolder(#NonNull #NotNull View itemView) {
super(itemView);
nom_pdv = itemView.findViewById(R.id.namepdv);
date = itemView.findViewById(R.id.dateliv);
etat = itemView.findViewById(R.id.etat);
}
}
#Override
public int getItemCount() {
return listArray.size();
}}
And this is activity detail :
public class Order_detail extends AppCompatActivity {
TextView namepdv, refcommande, datecommande, etat, produitcmnd, qnt;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_commande_detail2);
namepdv = findViewById(R.id.nompdv);
refcommande = findViewById(R.id.refcommande);
datecommande = findViewById(R.id.datecommande);
etat = findViewById(R.id.etatcommande);
// --------------------- //
namepdv.setText(getIntent().getStringExtra("nompdv"));
refcommande.setText(getIntent().getStringExtra("reference"));
datecommande.setText(getIntent().getStringExtra("datecommande"));
etat.setText(getIntent().getStringExtra("etat"));
}}
From your question I am assuming that keys under produit are random.
So when you will retrieve order details produit will be a Hashmap. Declare produit as Hashmap<String,String> in Order class.
You can print those keys and values.
for(Map.Entry<String, String> e : clickedDataItem.getproduit().entrySet()) {
// print e.getKey() e.getValue()
}
I'm trying to make a replica chat app and I have a list that I need populated into the recyclerview. I'm getting data from firebase realtime database and every time I receive or actually send a message, All the previous item(messages) plus the new one are repopulated/duplicated into the recycler view.
What I have tried
I have tried using .cleaar() method on my list before adding a new item to the list but now all other items in the recycler view disappear
here's my adapter
public class MessageAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public static final int MSG_TYPE_LEFT = 0;
public static final int MSG_TYPE_RIGHT = 1;
FirebaseUser firebaseUser;
private Context ctx;
private List<Messages> msgsR, msgsS;//ignore unused
private ArrayList<Messages> dataSet;
public MessageAdapter(Context context) {
this.ctx = context;
this.dataSet = new ArrayList<>();
//this.msgsR = messagesReceived;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
if (viewType == Messages.SENT_TYPE) {
View view = LayoutInflater.from(ctx).inflate(R.layout.message_item_right, parent, false);
return new ViewHolderS(view);
}
if (viewType == Messages.RECEIVED_TYPE) {
View view = LayoutInflater.from(ctx).inflate(R.layout.message_item_left, parent, false);
return new ViewHolderR(view);
}
return null;
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
Messages object = dataSet.get(position);
if (object != null) {
switch (object.type) {
case Messages.RECEIVED_TYPE:
((ViewHolderR) holder).populate(object, position);
break;
case Messages.SENT_TYPE:
((ViewHolderS) holder).populate(object, position);
break;
}
}
}
//recceives messages object to populate into list
//it does not matter where i put the .clear() method, after or below dataset.add() its still undesireable
public void addMessageSent(Messages messages){
dataSet.clear();
dataSet.add(messages);
// notifyItemInserted(dataSet.size()-1);
//notifyItemRangeChanged(dataSet.size()-1, dataSet.size());
}
#Override
public int getItemCount() {
return dataSet.size();
}
// sent messages are handled here
public static class ViewHolderS extends RecyclerView.ViewHolder {
public TextView msg, time;
public LinearLayout layout;
public ViewHolderS(#NonNull View itemView) {
super(itemView);
layout = itemView.findViewById(R.id.cont);
msg = itemView.findViewById(R.id.send_msg);
time = itemView.findViewById(R.id.time);
}
private void populate(Messages messages, int position) {
msg.setText(messages.getMessage());
msg.setPadding(6, 4, 18, 4);
msg.setMinWidth(100);
msg.setMaxWidth(400);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) msg.getLayoutParams();
layoutParams.gravity = Gravity.START;
layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT;
layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT;
layoutParams.topMargin = layoutParams.bottomMargin = layoutParams.rightMargin = 10;
layoutParams.leftMargin = 20;
msg.setLayoutParams(layoutParams);
time.setText(messages.getTime());
}
}
#Override
public int getItemViewType(int position) {
switch (dataSet.get(position).type) {
case 0:
return Messages.SENT_TYPE;
case 1:
return Messages.RECEIVED_TYPE;
default:
return -1;
}
}
// received messages are handled here
private class ViewHolderR extends ViewHolderS {
public TextView msg, time;
public LinearLayout layout;
public ViewHolderR(#NonNull View itemView) {
super(itemView);
layout = itemView.findViewById(R.id.cont);
msg = itemView.findViewById(R.id.send_msg);
time = itemView.findViewById(R.id.time);
}
private void populate(Messages messages, int position) {
msg.setText(messages.getMessage());
msg.setPadding(6, 4, 18, 4);
msg.setMinWidth(100);
msg.setMaxWidth(400);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) msg.getLayoutParams();
layoutParams.gravity = Gravity.START;
layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT;
layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT;
layoutParams.topMargin = layoutParams.bottomMargin = layoutParams.rightMargin = 10;
layoutParams.leftMargin = 20;
msg.setLayoutParams(layoutParams);
time.setText(messages.getTime());
}
}
}
and here's my data model
public class Messages {
private String message;
public static final int SENT_TYPE=0;
public static final int RECEIVED_TYPE=1;
public static final int AUDIO_TYPE=2;
private long time;
public int type;
private String id;
private String receiver;
public Messages(String message,long time, String sender,String receiver, int type) {
this.message = message;
this.time = time;
this.id = sender;
this.type = type;
this.receiver = receiver;
}
public Messages() {
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getTime() {
SimpleDateFormat output = new SimpleDateFormat("HH:mm", Locale.getDefault());
return output.format(new Date(time));
}
public void setTime(long time) {
this.time = time;
}
public String getSender() {
return id;
}
public void setSender(String sender) {
this.id = sender;
}
public String getReceiver() {
return receiver;
}
public void setReceiver(String receiver) {
this.receiver = receiver;
}
}
and below is activity class where I set the adapter and fill the list
recyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext());
linearLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(linearLayoutManager);
list= new ArrayList();
messageAdapter = new MessageAdapter(PersonChatActivity.this);
recyclerView.setAdapter(messageAdapter);
recyclerView.setItemAnimator(new DefaultItemAnimator());
if (Objects.requireNonNull(recyclerView.getAdapter()).getItemCount() > 0) {
recyclerView.smoothScrollToPosition(recyclerView.getAdapter().getItemCount());
}
//get sent messages from firebase
private void getmessages() {
DatabaseReference reference = database.getReference("Chats");
reference.keepSynced(true);
reference.child(senderId).child(receiver).push();
reference.child(senderId).child(receiver).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
messageSent.clear();
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
if (dataSnapshot.getValue() != null) {
String message = (String) dataSnapshot.child("message").getValue();
long time = (Long) dataSnapshot.child("time").getValue();
String senderId = (String) dataSnapshot.child("id").getValue();
String receiverId = (String) dataSnapshot.child("receiver").getValue();
assert firebaseUser != null;
String user = firebaseUser.getUid();
Messages msg = new Messages(message, time, senderId, receiverId,Messages.SENT_TYPE);
String Uid = msg.getSender();
if (!Uid.isEmpty() && Uid.equals(user)) {
//pass the new message object to messages adapter to fill the list
messageAdapter.addMessageSent(msg);
}
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
EDIT UPDATE
As suggested I have made the necessary changes and code works like magic
I wont update the right changes into the question in case someone makes the same mistake as I have plus the comment marked as answer basically highlights the correct changes,,
NEW PROBLEM
The new problem is, on adding object message to the addMessagesent() previously populated recyclerview items get replaced by the new data.
to make it easy, on receiving a new message, all the previous visible sent messagees disappear and are replaced by the new received messages
here is my getmessageReceived() method
DatabaseReference reference = database.getReference("Chats");
reference.keepSynced(true);
reference.child(receiver).child(senderId).push();
reference.child(receiver).child(senderId).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
messageReceived.clear();
messageAdapter.clearAllMessage();
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
if (dataSnapshot.getValue() != null) {
String message = (String) dataSnapshot.child("message").getValue();
long time = (Long) dataSnapshot.child("time").getValue();
String senderId = (String) dataSnapshot.child("id").getValue();
String receiverId = (String) dataSnapshot.child("receiver").getValue();
assert firebaseUser != null;
String user = firebaseUser.getUid();
Messages msg = new Messages(message, time, senderId, receiverId,Messages.RECEIVED_TYPE);
String Uid = msg.getReceiver();
if (!Uid.isEmpty() && Uid.equals(user)) {
messageAdapter.addMessageSent(msg);
messageAdapter.notifyDataSetChanged();
}
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
You should not clear the data set in the addMessageSent() just add new item to data set as shown below
public void addMessageSent(Messages messages){
dataSet.add(messages);
}
and create a new method to clear the dataset in your adapter
public void clearAllMessage(){
dataSet.clear();
}
And in getmessages() call clearAllMessage() like this
private void getmessages() {
DatabaseReference reference = database.getReference("Chats");
reference.keepSynced(true);
reference.child(senderId).child(receiver).push();
reference.child(senderId).child(receiver).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
messageSent.clear();
clearAllMessage();
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
if (dataSnapshot.getValue() != null) {
String message = (String) dataSnapshot.child("message").getValue();
long time = (Long) dataSnapshot.child("time").getValue();
String senderId = (String) dataSnapshot.child("id").getValue();
String receiverId = (String) dataSnapshot.child("receiver").getValue();
assert firebaseUser != null;
String user = firebaseUser.getUid();
Messages msg = new Messages(message, time, senderId, receiverId,Messages.SENT_TYPE);
String Uid = msg.getSender();
if (!Uid.isEmpty() && Uid.equals(user)) {
//pass the new message object to messages adapter to fill the list
messageAdapter.addMessageSent(msg);
messageAdapter.notifyDataSetChanged(); // Call this also
}
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
I am developing an android app which shows a list of countries affected by Coronavirus , the total number of confirmed cases and total Deaths. I am using a JSON API to get the data and displaying it using a RecyclerView . The app works fine , and i get a list of all the countries with their respective case counts. I want to add a search option so that the users can filter the list and find a specific country. How do i do that? I am new to programming , if someone could help with this that would be awesome.
Here is the code snippet
MainActivity.java
private RecyclerView mRecyclerView;
private Corona_Stats_Adapter mCorona_Stats_Adapter;
private TextView mErrorDisplay;
private ProgressBar mProgressBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.corona_stats);
mRecyclerView = (RecyclerView)findViewById(R.id.Corona_stats_recycler);
mErrorDisplay = (TextView) findViewById(R.id.tv_error_message_display);
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setHasFixedSize(true);
mCorona_Stats_Adapter = new Corona_Stats_Adapter();
mRecyclerView.setAdapter(mCorona_Stats_Adapter);
mProgressBar = (ProgressBar)findViewById(R.id.pb_loading_indicator) ;
loadCoronaData();
}
private void loadCoronaData(){
showCoronaDataView();
//String Country = String.valueOf(mSearchQuery.getText());
new Fetch_data().execute();
}
private void showCoronaDataView(){
mErrorDisplay.setVisibility(View.INVISIBLE);
mRecyclerView.setVisibility(View.VISIBLE);
}
private void showErrorMessage(){
mRecyclerView.setVisibility(View.INVISIBLE);
mErrorDisplay.setVisibility(View.VISIBLE);
}
public class Fetch_data extends AsyncTask<Void,Void,String[]> {
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressBar.setVisibility(View.VISIBLE);
}
#Override
protected String[] doInBackground(Void... voids) {
URL covidRequestURL = NetworkUtils.buildUrl();
try {
String JSONCovidResponse = NetworkUtils.getResponseFromHttpUrl(covidRequestURL);
String[] simpleJsonCovidData = CovidJSON_Utils.getSimpleStringFromJson(MainActivity.this, JSONCovidResponse);
return simpleJsonCovidData;
} catch (IOException | JSONException e) {
e.printStackTrace();
return null;
}
}
#Override
protected void onPostExecute(String[] coronaData) {
mProgressBar.setVisibility(View.INVISIBLE);
if(coronaData !=null){
showCoronaDataView();
mCorona_Stats_Adapter.setCoronaData(coronaData);
} else{
showErrorMessage();
}
}
}
}
RecyclerView Adapter class Corona_stats_Adapter.java
public class Corona_Stats_Adapter extends RecyclerView.Adapter<Corona_Stats_Adapter.Corona_Stats_AdapterViewHolder>
{
private Context context;
// private List<Country> countryList;
// private List<Country> countryListFiltered;
private String[] mCoronaData;
public Corona_Stats_Adapter(){
}
#NonNull
#Override
public Corona_Stats_AdapterViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int viewType) {
Context context = viewGroup.getContext();
int LayoutIdForListItem =R.layout.corona_stats_list_item;
LayoutInflater inflater =LayoutInflater.from(context);
boolean ShouldAttachToParentImmediately = false;
View view = inflater.inflate(LayoutIdForListItem,viewGroup,ShouldAttachToParentImmediately);
return new Corona_Stats_AdapterViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull Corona_Stats_AdapterViewHolder corona_stats_adapterViewHolder, int position) {
String coronaStats = mCoronaData[position];
corona_stats_adapterViewHolder.mCoronaTextView.setText(coronaStats);
}
#Override
public int getItemCount() {
if(null == mCoronaData) return 0;
return mCoronaData.length;
// return countryListFiltered.size();
}
public class Corona_Stats_AdapterViewHolder extends RecyclerView.ViewHolder {
public final TextView mCoronaTextView;
public Corona_Stats_AdapterViewHolder(#NonNull View view) {
super(view);
mCoronaTextView = (TextView) view.findViewById(R.id.tv_corona_data);
}
}
public void setCoronaData(String[] coronaData){
mCoronaData = coronaData;
notifyDataSetChanged();
}
}
Parsing the JSON data in CovidJSON_Utils.java
public final class CovidJSON_Utils {
public static String[] getSimpleStringFromJson(Context context, String codivJsonString)
throws JSONException {
final String COV_COUNTRY = "Countries";
final String COV_CONFIRMED = "confirmed";
final String COV_DEATHS = "deaths";
final String COV_MESSAGE_CODE = "code";
String[] parsedCovidData = null;
JSONObject covidJsonObject = new JSONObject(codivJsonString);
if (covidJsonObject.has(COV_MESSAGE_CODE)) {
int errorCode = covidJsonObject.getInt(COV_MESSAGE_CODE);
switch (errorCode) {
case HttpURLConnection.HTTP_OK:
break;
case HttpURLConnection.HTTP_NOT_FOUND:
return null;
default:
return null;
}
}
JSONArray countryCovidArray = covidJsonObject.getJSONArray(COV_COUNTRY);
parsedCovidData = new String[countryCovidArray.length()];
for (int i = 0; i < countryCovidArray.length(); i++) {
JSONObject countryJSONObject = countryCovidArray.getJSONObject(i);
String Country = countryJSONObject.getString("Country");
String Confirmed = String.valueOf(countryJSONObject.getInt("TotalConfirmed"));
String Deaths = String.valueOf(countryJSONObject.getInt("TotalDeaths"));
parsedCovidData[i] = Country + "- Cases " + Confirmed + "- Deaths " + Deaths;
}
return parsedCovidData;
}
}
The problem is with below initialization in the MainActivity.Oncreate method
mCorona_Stats_Adapter = new Corona_Stats_Adapter(this,countries);
Initialize the adapter in onPostExecute method with updated countries data.
Hope this will help you.
You have to set arraylist to update country data in adapter after getting data from the server.
Public void setCoronaData (Arraylist coronaData) {
countryList = coronaData;
notifyDataSetChanged ();
}
I have a child eventListener class. this is called by a few different activities. but for some reason when i leave one activity and go to the next. my listView keeps hold of the previous data from the listener and also adds the new.
I have tried to add a removeListener to the on back press of my activity but the result is still the same.
this is my Listener Class
public class aimeEnentListener {
private ListView mlv;
private static ArrayList<String> AppNameList = new ArrayList<>();
private ArrayList<String> urlList = new ArrayList<>();
private static ArrayList<String> ApkList = new ArrayList<>();
private static ArrayList<String> Aboutapp = new ArrayList<>();
private static ArrayList<String> appImage = new ArrayList<>();
private static ArrayList<String> Downloadscount = new ArrayList<>();
private static ArrayList<String> DOWNLOADS = new ArrayList<>();
private Context mContext;
private dataListAdapter apkData;
public static String mCurrentPhotoPath;
private static String apkNames;
private Firebase mrootRef;
private String appname;
private String Apptype;
private String counter,url,apkname,about,appimg,tagname;
private com.firebase.client.ChildEventListener eventListener;
String tag;
public aimeEnentListener (ListView mlv,Context context,String AppType,Firebase mrootRef){
this.mContext = context;
this.mlv = mlv;
this.Apptype = AppType;
this.mrootRef = mrootRef;
}
public void setList() {
eventListener = new com.firebase.client.ChildEventListener() {
#Override
public void onChildAdded(com.firebase.client.DataSnapshot dataSnapshot, String s) {
appname = dataSnapshot.child("name").getValue(String.class);
counter = dataSnapshot.child("downloads").getValue(String.class);
url = dataSnapshot.child("url").getValue(String.class);
apkname = dataSnapshot.child("apk").getValue(String.class);
about = dataSnapshot.child("about").getValue(String.class);
appimg = dataSnapshot.child("image").getValue(String.class);
tagname = dataSnapshot.child("tag").getValue(String.class);
DOWNLOADS.add(tagname);
Downloadscount.add(counter);
AppNameList.add(appname);
urlList.add(url);
ApkList.add(apkname);
Aboutapp.add(about);
appImage.add(appimg);
final String[] arr = AppNameList.toArray(new String[AppNameList.size()]);
String[] arr1 = Aboutapp.toArray(new String[Aboutapp.size()]);
String[] arr2 = appImage.toArray(new String[appImage.size()]);
final String[] arr3 = Downloadscount.toArray(new String[Downloadscount.size()]);
apkData = new dataListAdapter(mContext, arr, arr1, arr2, arr3, mrootRef, Apptype);
mlv.setAdapter(apkData);
apkData.notifyDataSetChanged();
mlv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
final Firebase ref = mrootRef.getRef();
tag = DOWNLOADS.get(i).toString();
apkNames = AppNameList.get(i).toString();
DownloadFileFromURL dl = new DownloadFileFromURL(mContext, apkNames, mCurrentPhotoPath);
dl.execute(urlList.get(i));
Count_System count = new Count_System(ref);
count.count();
App_DownLoadCounter(tag);
}
});
}
#Override
public void onChildChanged(com.firebase.client.DataSnapshot dataSnapshot, String s) {
if (dataSnapshot.exists()) {
counter = dataSnapshot.child("downloads").getValue(String.class);
appname = dataSnapshot.child("name").getValue(String.class);
counter = dataSnapshot.child("downloads").getValue(String.class);
url = dataSnapshot.child("url").getValue(String.class);
apkname = dataSnapshot.child("apk").getValue(String.class);
about = dataSnapshot.child("about").getValue(String.class);
appimg = dataSnapshot.child("image").getValue(String.class);
tagname = dataSnapshot.child("tag").getValue(String.class);
apkData.notifyDataSetChanged();
}
}
#Override
public void onChildRemoved(com.firebase.client.DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(com.firebase.client.DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
};
mrootRef.child(Apptype).addChildEventListener(eventListener);
}
public void App_DownLoadCounter(String tag) {
this.tag = tag;
Firebase ref = mrootRef.getRef();
ref.child(Apptype).child(tag).child("downloads").runTransaction(new Transaction.Handler() {
#Override
public Transaction.Result doTransaction(MutableData mutableData) {
if (mutableData.getValue() == null) {
mutableData.setValue(0);
} else {
int count = mutableData.getValue(Integer.class);
mutableData.setValue(count + 1);
}
return Transaction.success(mutableData);
}
#Override
public void onComplete(FirebaseError firebaseError, boolean b, com.firebase.client.DataSnapshot dataSnapshot) {
}
});
}
public void removeListener(){
mrootRef.child(Apptype).removeEventListener(eventListener);
}
}
then i call it from each activity using
mlv = (ListView) findViewById(R.id.lvCastingapps);
listener = new aimeEnentListener(mlv, Casting_Apps.this, Apptype, mrootRef);
listener.setList();
I have even tried adding the removeListener to onBackpress
#Override
public void onBackPressed(){
super.onBackPressed();
Intent i=new Intent(Intent.ACTION_MAIN);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
finish();
listener.removeListener();
}
Edit****
if i make an exact copy of the listener class and use that on one then use the above listener on the next it works correctly. but i really only wan to use one listener
I am populating the recycler view with new data on Activity
result.The problem is the new data is getting append at the end of the
recycler view how do I clear the previous data in the recycler view
and inflate the recycler view with the new data.
#Override
protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
mAdapter.notifyDataSetChanged();
search_info.clear();
book_type.clear();
if (requestCode == 1) {
if (resultCode == RESULT_OK) {
getBookData(data);
if (books_list.size() > 0) {
books_list.clear();
mAdapter.swap(prepareData());
mAdapter.notifyDataSetChanged();
}
updateBooks(recyclerView);
mAdapter.notifyDataSetChanged();
}
}
}
This is the code for getBookData.
private void getBookData(Intent data) {
String singles = data.getStringExtra("singles");
String status_5in1series = data.getStringExtra("status_5in1series");
String special_issues = data.getStringExtra("special_issues");
String special_collection = data.getStringExtra("special_collection");
String status_3in1series = data.getStringExtra("status_3in1series");
String status_2in1 = data.getStringExtra("status_2in1");
String special_packs = data.getStringExtra("special_packs");
String junior = data.getStringExtra("junior");
String character_collections = data.getStringExtra("character_collections");
String single_digest = data.getStringExtra("single_digest");
String double_digest = data.getStringExtra("double_digest");
String toddler = data.getStringExtra("toddler");
String tinkle_treasure = data.getStringExtra("tinkle_treasure");
String ack = data.getStringExtra("ack");
String tinkle = data.getStringExtra("tinkle");
search_info.add(singles);
search_info.add(status_5in1series);
search_info.add(special_issues);
search_info.add(special_collection);
search_info.add(status_3in1series);
search_info.add(status_2in1);
search_info.add(special_packs);
search_info.add(junior);
search_info.add(character_collections);
search_info.add(single_digest);
search_info.add(double_digest);
search_info.add(toddler);
search_info.add(tinkle_treasure);
search_info.removeAll(Collections.singleton(null));
book_type.add(ack);
book_type.add(tinkle);
book_type.removeAll(Collections.singleton(null));
String search_array[] = (String[]) search_info.toArray(new String[search_info.size()]);
String books_array[] = (String[]) book_type.toArray(new String[book_type.size()]);
String books_info = dbHandler.searchForBooks(search_array, books_array).toString();
ParseLocBooks parseLocBooks = new ParseLocBooks(books_info);
parseLocBooks.parseJSON();
title = ParseLocBooks.title;
price = ParseLocBooks.price;
vol_no = ParseLocBooks.vol_no;
status = ParseLocBooks.status;
ISBN = ParseLocBooks.ISBN;
book_id = ParseLocBooks.book_id;
brand = ParseLocBooks.brand;
book_code = ParseLocBooks.book_code;
sku = ParseLocBooks.sku;
lang = ParseLocBooks.lang;
}
This is my code for prepareData.
private ArrayList prepareData() {
for (int i = 0; i < book_id.length; i++) {
BooksInfo booksInfo = new BooksInfo();
booksInfo.setTitle(title[i]);
booksInfo.setPrice(price[i]);
booksInfo.setVol_no(vol_no[i]);
booksInfo.setStatus(status[i]);
booksInfo.setISBN(ISBN[i]);
booksInfo.setBook_id(book_id[i]);
booksInfo.setBrand(brand[i]);
booksInfo.setBook_code(book_code[i]);
booksInfo.setSku(sku[i]);
booksInfo.setLang(lang[i]);
books_list.add(booksInfo);
}
return books_list;
}
And this is my DataAdapter code.
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.ViewHolder> {
private ArrayList<BooksInfo> books;
private Context ctx;
private String qty;
private RecyclerView recyclerView;
public DataAdapter()
{
}
#NonNull
public OnItemCheckListener onItemCheckListener;
public DataAdapter(Context context, ArrayList<BooksInfo> books, RecyclerView recyclerView,String qty, OnItemCheckListener onItemCheckListener) {
this.books = books;
this.ctx = context;
this.qty = qty;
this.onItemCheckListener =onItemCheckListener;
this.recyclerView = recyclerView;
}
public interface OnItemCheckListener {
void onItemCheck(BooksInfo item,ViewHolder viewHolder);
void onItemUncheck(BooksInfo item,ViewHolder viewHolder);
}
public void swap(ArrayList<BooksInfo> datas){
datas = new ArrayList<>();
recyclerView.removeAllViews();
books.clear();
books.addAll(datas);
notifyDataSetChanged();
}
#Override
public DataAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.card_row, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final DataAdapter.ViewHolder viewHolder, int i) {
final BooksInfo booksInfo = (BooksInfo) books.get(i);
viewHolder.tv_title.setText(booksInfo.getTitle());
viewHolder.tv_price.setText(booksInfo.getPrice());
viewHolder.tv_vol_no.setText(booksInfo.getVol_no());
viewHolder.tv_status.setText(booksInfo.getStatus());
viewHolder.tv_isbn.setText(booksInfo.getISBN());
viewHolder.tv_book_id.setText(booksInfo.getBook_id());
viewHolder.tv_brand.setText(booksInfo.getBrand());
viewHolder.tv_sku.setText(booksInfo.getSku());
viewHolder.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
viewHolder.cb_selection.setChecked(!(viewHolder.cb_selection.isChecked()));
if (viewHolder.cb_selection.isChecked()){
onItemCheckListener.onItemCheck(booksInfo,viewHolder);
// viewHolder.tv_qty.setText(qty);
}else{
onItemCheckListener.onItemUncheck(booksInfo,viewHolder);
// viewHolder.tv_qty.setText("0");
}
}
});
}
public void updateNotes(ArrayList notesList) {
books = notesList;
}
public void updateQty(String q)
{
qty =q;
}
#Override
public int getItemCount() {
return books.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView tv_title,tv_price,tv_vol_no,tv_status,tv_isbn,tv_book_id,tv_brand,tv_sku,tv_qty;
public CheckBox cb_selection;
View itemView;
public ViewHolder(View itemView) {
super(itemView);
this.itemView = itemView;
tv_title = (TextView)itemView.findViewById(R.id.tv_title);
tv_price = (TextView) itemView.findViewById(R.id.tv_price);
tv_vol_no = (TextView) itemView.findViewById(R.id.tv_volno);
tv_status = (TextView) itemView.findViewById(R.id.tv_status);
tv_isbn = (TextView) itemView.findViewById(R.id.tv_isbn);
tv_book_id = (TextView) itemView.findViewById(R.id.tv_bookid);
tv_brand = (TextView) itemView.findViewById(R.id.tv_brand);
cb_selection = (CheckBox) itemView.findViewById(R.id.cb_selection);
cb_selection.setClickable(false);
tv_sku = (TextView) itemView.findViewById(R.id.tv_sku);
tv_qty = (TextView) itemView.findViewById(R.id.tv_qty);
}
public void setOnClickListener(View.OnClickListener onClickListener) {
itemView.setOnClickListener(onClickListener);
}
}
}
Any help or suggestion is appreciated.Thank you.
Notify your adapter to reflect the changes
mAdapter.notifyDataSetChanged();
clear your array list before adding object into:
private ArrayList prepareData() {
books_list.clear();
for (int i = 0; i < book_id.length; i++) {
BooksInfo booksInfo = new BooksInfo();
booksInfo.setTitle(title[i]);
booksInfo.setPrice(price[i]);
booksInfo.setVol_no(vol_no[i]);
booksInfo.setStatus(status[i]);
booksInfo.setISBN(ISBN[i]);
booksInfo.setBook_id(book_id[i]);
booksInfo.setBrand(brand[i]);
booksInfo.setBook_code(book_code[i]);
booksInfo.setSku(sku[i]);
booksInfo.setLang(lang[i]);
books_list.add(booksInfo);
}
return books_list;
}
Call this method
removeAllViews() on your recycler before setting a new Adapter.
Just clean your adapter's data, add new data to it and then call notifyDataSetChanged() on your adapter:
yourDataList.clear();
yourDataList.addNewObjects();
adapter.notifyDataSetChanged();