Reputation: 185
I'm using a custom adapter to show objects of the type RequestDetails in listView. Each listView item has an accept and deny button. On clicking the buttons, the appropriate changes are made to the (Firebase) database - in both cases, the request is deleted from the database, but I don't know how to refresh the listView to reflect the change made in the database. I read up on notifyDataSetChanged(), but I'm not too sure how to use it in my case.
Here's the code segment for the onClickListeners for the buttons in the custom Adapter (RequestAdapter) I created :
acceptButton = (Button) listItemView.findViewById(R.id.accept_request_button);
denyButton = (Button) listItemView.findViewById(R.id.deny_request_button);
acceptButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DatabaseReference requestsRef = FirebaseDatabase.getInstance().getReference().child("Requests");
if(mIsOCRequest){
HashMap<String,Object> tournamentStatus = new HashMap<String, Object>();
tournamentStatus.put("isOrganizing",true);
tournamentStatus.put("isParticipating",false);
Toast.makeText(getContext(),"Requested Accepted",Toast.LENGTH_SHORT).show();
userRef.child("tournamentStatuses").child(request.getTournamentId()).updateChildren(tournamentStatus);
}
else if(mIsParticipantRequest){
HashMap<String,Object> tournamentStatus = new HashMap<String, Object>();
tournamentStatus.put("isOrganizing",false);
tournamentStatus.put("isParticipating",true);
Toast.makeText(getContext(),"Requested Accepted",Toast.LENGTH_SHORT).show();
userRef.child("tournamentStatuses").child(request.getTournamentId()).updateChildren(tournamentStatus);
//TODO: create a child in the user called sports which will have the tournamentID followed by the sport(s)
}
requestsRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
for(DataSnapshot requestLooper : dataSnapshot.getChildren()){
RequestDetails retrievedRequest = requestLooper.getValue(RequestDetails.class);
if(retrievedRequest.equals(request)){
requestLooper.getRef().removeValue();
Log.d("Removing at",requestLooper.getRef().toString());
notifyDataSetChanged();
}
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
denyButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DatabaseReference requestsRef = FirebaseDatabase.getInstance().getReference().child("Requests");
requestsRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()) {
for (DataSnapshot requestLooper : dataSnapshot.getChildren()) {
RequestDetails requestDetails = requestLooper.getValue(RequestDetails.class);
if (requestDetails.equals(request)) {
requestLooper.getRef().removeValue();
Log.d("Deny Button", "Request Removed");
Log.d("Removing at",requestLooper.getRef().toString());
notifyDataSetChanged();
break;
}
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
For some reason, on clicking the Deny button, a copy of the item I 'deleted' is appended to the listView..
I'm sure I'm not using the notifyDataSetChanged() method correctly, because in the other posts that I've read it's always invoked by an 'adapter' object. If i try doing that, I get an error where 'adapter' can't be resolved.
If it's of any use, here's the activity onCreate() code where I set my adapter :
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_requests);
requestsRef = FirebaseDatabase.getInstance().getReference().child("Requests");
final ArrayList<RequestDetails> requestDetailsArrayList = new ArrayList<>();
requestsRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()) {
for (DataSnapshot request : dataSnapshot.getChildren()) {
RequestDetails requestDetails = request.getValue(RequestDetails.class);
requestDetailsArrayList.add(requestDetails);
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
RequestAdapter requestAdapter = new RequestAdapter(this, requestDetailsArrayList);
ListView requestsListView = (ListView) findViewById(R.id.requests_list);
requestsListView.setAdapter(requestAdapter);
}
Can anyone help me out?
Thanks in advance!
Upvotes: 0
Views: 68
Reputation: 337
The way adapters work is that it takes an arraylist as a parameter, and converts it into a "representable" list to be viewed in a ListView. The way "notifyDataSetChanged" works, is that it "is" called on an adapter (that is true), however since you are calling it inside your adapter class then the compiler is reading it this way [ this.notifyDataSetChanged ] , where (this here resembles the adapter).
Now for your question. Every time you accept or deny an item, you apply the appropriate changes to the Firebase database, why this issue is arising is that as I said earlier all that notifyDataSetChanged does is that it checks the changes in the ArrayList and "Refreshes" itself and the listView basically to apply these changes. Try to access the ArrayList that is passed in the constructor of your custom array adapter, and in the denyButton click listener, when you remove the request from the request looper, also remove it from the arrayList.
Upvotes: 1