I use firebase database and recycler view.
I add a list of items to firebase using the push (); command.
While using push(); , firebase creating a unique id for each added item.
Now, i want delete item on click delete button, but when i try removeValue(); function to my DB ref, it delete the all repository and not just the item.
That what i have now:
Fragment that read data from firebase
users.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull final DataSnapshot dataSnapshot) {
notes.clear();
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
note = dataSnapshot1.getValue(Note.class);
notes.add(note);
}
adapter = new NotesAdapter(notes, getActivity());
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getActivity(), 3);
RVNotesList.setLayoutManager(layoutManager);
RVNotesList.setAdapter(adapter);
adapter.setOnNoteClickListener(new NotesAdapter.OnNoteClickListener() {
#Override
public void onNoteClick(final int position) {
users.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
//TODO delete pressed item.
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
});
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
My onClick buttons
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.saveNoteBTN:
String title = ETnoteTitle.getText().toString().trim();
String desc = ETnoteDesc.getText().toString().trim();
String date = ETnoteLastDate.getText().toString().trim();
if (title.isEmpty() || desc.isEmpty() || date.isEmpty()) {
return;
}
note = new Note(title, desc, date);
users.push().setValue(note).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d("NoteAdded", "true");
getFragmentManager().beginTransaction().
remove(getFragmentManager().findFragmentById(R.id.bottom_container)).commit();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d("NoteAdded", "false");
}
});
break;
case R.id.deleteNoteBTN:
getFragmentManager().beginTransaction().
remove(getFragmentManager().findFragmentById(R.id.bottom_container)).commit();
break;
}
}
Adapter
package com.enjoyapp.eventmanagement.Adapters;
import android.app.Dialog;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import com.enjoyapp.eventmanagement.Models.Note;
import com.enjoyapp.eventmanagement.R;
import java.util.ArrayList;
public class NotesAdapter extends RecyclerView.Adapter<NotesAdapter.NotesViewHolder> {
private ArrayList<Note> notes;
private Context context;
private OnNoteClickListener onNoteClickListener;
public NotesAdapter(ArrayList<Note> notes, Context context) {
this.notes = notes;
this.context = context;
}
public interface OnNoteClickListener {
void onNoteClick(int position);
}
public void setOnNoteClickListener(OnNoteClickListener onNoteClickListener) {
this.onNoteClickListener = onNoteClickListener;
}
#NonNull
#Override
public NotesViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.note_list_item, parent, false);
return new NotesAdapter.NotesViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final NotesViewHolder holder, final int position) {
final Note note = notes.get(position);
holder.mNoteTitle.setText(notes.get(position).getmTitle());
holder.mNoteDesc.setText(notes.get(position).getmDescription());
String lastDayToConfirmNote = (notes.get(position).getmDay() + "/"
+ notes.get(position).getmMonth() + "/" + notes.get(position).getmYear());
holder.mLastDay.setText(lastDayToConfirmNote);
#Override
public int getItemCount() {
return notes.size();
}
public class NotesViewHolder extends RecyclerView.ViewHolder {
private TextView mNoteTitle;
private TextView mNoteDesc;
private TextView mLastDay;
private CardView note_card;
public NotesViewHolder(#NonNull View itemView) {
super(itemView);
mNoteTitle = itemView.findViewById(R.id.note_title);
mNoteDesc = itemView.findViewById(R.id.note_description);
mLastDay = itemView.findViewById(R.id.note_last_date);
note_card = itemView.findViewById(R.id.note_card);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (onNoteClickListener!=null){
onNoteClickListener.onNoteClick(getAdapterPosition());
}
}
});
}
}
public void removeItem(ArrayList arrayList, int position) {
arrayList.remove(arrayList.get(position));
notifyItemRemoved(position);
notifyItemRangeChanged(position, arrayList.size());
}
}
According to your code, it seems that users is your parent root and you want to delete one of the child of users. For that, you will need the id of that child. You can get id and save it in ArrayList like
ArrayList<String> ids = new ArrayList
users.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull final DataSnapshot dataSnapshot) {
notes.clear();
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
note = dataSnapshot1.getValue(Note.class);
notes.add(note);
ids.add(dataSnapshot1.getKey());//saving id of each child
}
adapter = new NotesAdapter(notes, getActivity());
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getActivity(), 3);
RVNotesList.setLayoutManager(layoutManager);
RVNotesList.setAdapter(adapter);
adapter.setOnNoteClickListener(new NotesAdapter.OnNoteClickListener() {
#Override
public void onNoteClick(final int position) {
users.child(ids.get(position)).removeValue();
}
});
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
NOTE : You have to update ids arraylist when you will update notes arraylist.
Related
This is a list of qna in the firebase. I want to print this out.
But my output list doesn't show anything.
https://i.stack.imgur.com/6ctRB.png
QNA Activity
public class QnaActivity extends AppCompatActivity {
private RecyclerView qnaRv;
private ArrayList<ModelQna> qnaList;
private AdapterQna adapterQna;
private ImageButton writeBtn;
private ImageButton backbtn;
private TextView tabQnaTv;
private RelativeLayout QnaRl;
private FirebaseAuth firebaseAuth;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_qna);
getSupportActionBar().hide();
qnaRv = findViewById(R.id.qnaRv);
tabQnaTv = findViewById(R.id.tabQnaTv);
QnaRl = findViewById(R.id.QnaRl);
backbtn = findViewById(R.id.backBtn);
writeBtn = findViewById(R.id.writeBtn);
firebaseAuth = FirebaseAuth.getInstance();
loadAllQna();
showQnaUI();
backbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onBackPressed();
}
});
writeBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(), AddQnaActivity.class);
startActivity(intent);
}
});
tabQnaTv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//load products
}
});
}
private void loadAllQna() {
qnaList = new ArrayList<>();
adapterQna = new AdapterQna(this, qnaList);
qnaRv.setAdapter(adapterQna);
//get all products
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Employees");
reference.child(firebaseAuth.getUid()).child("Qna").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
//before getting reset List
qnaList.clear();
for (DataSnapshot dataSnapshot : snapshot.getChildren()){
ModelQna modelQna = dataSnapshot.getValue(ModelQna.class);
qnaList.add(modelQna);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseerror) {
}
});
}
private void showQnaUI() {
//show orders ui and hide products ui
QnaRl.setVisibility(View.GONE);
}
}
Model
public class ModelFaq {
private String faqId,faqTitle,faqContent, timestamp,uid,faqCategory;
public ModelFaq() {
}
public ModelFaq(String faqId, String faqTitle, String faqContent, String timestamp, String uid, String faqCategory) {
this.faqId = faqId;
this.faqTitle = faqTitle;
this.faqContent = faqContent;
this.timestamp = timestamp;
this.uid = uid;
this.faqCategory = faqCategory;
}
public String getFaqId() {
return faqId;
}
public void setFaqId(String faqId) {
this.faqId = faqId;
}
public String getFaqTitle() {
return faqTitle;
}
public void setFaqTitle(String faqTitle) {
this.faqTitle = faqTitle;
}
public String getFaqContent() {
return faqContent;
}
public void setFaqContent(String faqContent) {
this.faqContent = faqContent;
}
public String getTimestamp() {
return timestamp;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getFaqCategory() {
return faqCategory;
}
public void setFaqCategory(String faqCategory) {
this.faqCategory = faqCategory;
}
}
Qna Adapter
public class AdapterQna extends RecyclerView.Adapter<AdapterQna.HolderQna> {
private Context context;
public ArrayList<ModelQna> qnaList;
public AdapterQna(Context context, ArrayList<ModelQna> qnaList) {
this.context = context ;
this.qnaList = qnaList ;
}
#NonNull
#Override
public HolderQna onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
//inflate layout
View view = LayoutInflater.from(context).inflate(R.layout.qna_item, parent, false);
return new HolderQna(view);
}
#Override
public void onBindViewHolder(#NonNull HolderQna holder, int position) {
ModelQna modelQna = qnaList.get(position);
String id = modelQna.getQnaId();
String uid = modelQna.getUid();
String qnaContent = modelQna.getQnaContent();
String qnaTitle = modelQna.getQnaTitle();
String timestamp = modelQna.getTimestamp();
//set data
holder.titleTextView.setText(qnaTitle);
holder.ContentTextView.setText(qnaContent);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//handle item clicks, show item details
}
});
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//handle item clicks, show item details
}
});
}
#Override
public int getItemCount() {
return qnaList.size();
}
class HolderQna extends RecyclerView.ViewHolder{
/*holds views of recyclerview*/
private TextView titleTextView, ContentTextView;
public HolderQna(#NonNull View itemView) {
super(itemView);
titleTextView = itemView.findViewById(R.id.item_post_title);
ContentTextView = itemView.findViewById(R.id.item_post_content);
}
}
}
Can you please change the code in your HolderQna to:
class HolderQna extends RecyclerView.ViewHolder{
/*holds views of recyclerview*/
private TextView titleTextView, ContentTextView;
public HolderQna(#NonNull View itemView) {
super(itemView);
titleTextView = itemView.findViewById(R.id.item_post_title);
ContentTextView = itemView.findViewById(R.id.item_post_content);
}
public void bind(qna: ModelQna){
titleTextView.setText(qna.qnaTitle);
ContentTextView.setText(qna.qnaContent);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//handle item clicks, show item details
}
});
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//handle item clicks, show item details
}
});
}
}
And your onBindViewHolder override of the AdapterQna to:
#Override
public void onBindViewHolder(#NonNull HolderQna holder, int position) {
ModelQna modelQna = qnaList.get(position);
String id = modelQna.getQnaId();
String uid = modelQna.getUid();
String qnaContent = modelQna.getQnaContent();
String qnaTitle = modelQna.getQnaTitle();
String timestamp = modelQna.getTimestamp();
//set data
holder.bind(modelQna);
}
Finally change your loadQna() function declaration as follows:
private void loadAllQna() {
qnaList = new ArrayList<>();
//get all products
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Employees");
reference.child(firebaseAuth.getUid()).child("Qna").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
//before getting reset List
qnaList.clear();
for (DataSnapshot dataSnapshot : snapshot.getChildren()){
ModelQna modelQna = dataSnapshot.getValue(ModelQna.class);
qnaList.add(modelQna);
}
adapterQna = new AdapterQna(this, qnaList);
qnaRv.setAdapter(adapterQna);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseerror) {
Log.e("QnaActivity", databaseError.toString());
}
});
}
As far as I can see in your screenshot, the Qna node it's not nested under any UID, but directly under the Employees node. So when you attach a listener to the following node:
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Employees");
reference.child(firebaseAuth.getUid()).child("Qna").addValueEventListener(/*...*/);
You will not be able to get any results, because such a reference doesn't exist. To solve this, you either create a reference that points exactly to "Qna":
DatabaseReference db = FirebaseDatabase.getInstance().getReference();
DatabaseReference qnaRef = db.child("Employees").child("Qna");
qnaRef.addValueEventListener(/*...*/);
Or you move the "Qna" node under the UID of the user, and leave the code unchanged.
Besides that, there is also another problem. The name of the fields in your ModelFaq class are different than the name of the properties in your database. You have in your ModelFaq class four fields called faqId, faqTitle, faqContent, faqCategory, all starting with faq while in the database I see that the names are different, qnaId, qnaTitle, qnaContent, qnaCategory, all are starting wiht qna, and this is not correct. So in order to be able to map a node into an object of type ModelFaq, the names must match. The only two fields that match are the timestamp and the uid.
In this case, you have two solutions. The first one would to change the name of your fieds in the ModelFaq class according to what it already exists in the database or you can use the PropertyName annotation in front of the getters like this:
#PropertyName("qnaId")
public String getFaqId() {
return faqId;
}
I'm currently making a booking app for some football fields. I have two recycler views: active bookings and cancelled bookings. I also have a custom recycler view adapter. Both of the recycler views use the same adapter.
What I want to do: if I click on a button inside my active bookings recycler view, I want to remove the booking from the active bookings and put it into my cancelled bookings. I'm gonna leave my custom adapter with the mention that I use Firebase in order to get my booking status (active or cancelled).
public class RecyclerViewAdapterRezervare extends RecyclerView.Adapter<RecyclerViewAdapterRezervare.RecycleViewHolder> {
private List<Rezervare> rezervari;
private Context context;
private LayoutInflater inflater;
private String numeUtilizator;
private String status;
private Rezervare rezervare = new Rezervare();
private DatabaseReference reff;
public RecyclerViewAdapterRezervare(List<Rezervare> rezervari, Context context, String numeUtilizator) {
this.rezervari = rezervari;
this.context = context;
this.numeUtilizator = numeUtilizator;
this.inflater = LayoutInflater.from(context);
}
#NonNull
#Override
public RecycleViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.rezervari_layout, parent, false);
return new RecycleViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull RecycleViewHolder holder, int position) {
rezervare = rezervari.get(position);
reff = FirebaseDatabase.getInstance().getReference();
List<String> listaOre = rezervare.getOre();
Map<String, Object> mapOre = new HashMap<>();
for(String ora : listaOre){
mapOre.put(ora, false);
}
// this will return the status ("activa" is the booking is active, or "anulata" is it's cancelled)
getStatus(rezervare, new StatusCallback() {
#Override
public void onCallback(String value) {
status = value;
holder.btn_anuleaza.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.v("status", status);
new AlertDialog.Builder(view.getContext()).setTitle("Anulare rezervare").setMessage("Sunteti sigur ca doriti anularea rezervarii?")
.setPositiveButton(R.string.da, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
// if the cancel button is clicked, i update my database so the status of the booking will be "anulata" - cancelled reff.child("Users").child(numeUtilizator).child("rezervari").child(rezervare.getData()).child(rezervare.getNumeTeren()).child("status").setValue("anulata");
reff.child("Rezervari").child(rezervare.getData()).child("Fotbal").child(rezervare.getNumeTeren()).updateChildren(mapOre);
rezervare.setEsteAnulata(false);
Toast.makeText(view.getContext(), "Anulare cu succes!", Toast.LENGTH_LONG).show();
}
}).setNegativeButton(R.string.nu, null).show();
}
});
}
});
}
#Override
public int getItemCount() {
return rezervari.size();
}
// i have updated my code with the delete and insert a booking
public void stergeRezervare(int position){
rezervari.remove(position);
notifyDataSetChanged();
}
public void adaugaRezervare(Rezervare rezervare){
rezervari.add(rezervare);
notifyDataSetChanged();
}
This is the function that gets me the bookings from firebase
i have 3 separate lists for active bookings, cancelled and past bookings.
public interface RezervariListCallback {
void onCallback(List<Rezervare> rezervariActuale, List<Rezervare> rezervariTrecute, List<Rezervare> rezervariAnulate);
}
public void getRezervari(String nume, RezervariListCallback myCallback){
reff.child("Users").child(nume).child("rezervari").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for(DataSnapshot data : snapshot.getChildren()){
String dataRezervare = data.getKey();
dateRezervari.add(dataRezervare);
reff.child("Users").child(nume).child("rezervari").child(dataRezervare).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for(DataSnapshot data : snapshot.getChildren()){
String numeTeren = data.getKey();
reff.child("Users").child(nume).child("rezervari").child(dataRezervare).child(numeTeren).child("ore").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
List<String> ore = new ArrayList<>();
for(DataSnapshot data : snapshot.getChildren()){
String ora = data.getKey();
ore.add(ora);
}
getAdresa(nume, dataRezervare, numeTeren, new AdresaCallback() {
#Override
public void onCallbackAdresa(String value) {
Rezervare rezervare = new Rezervare(numeTeren, ore, dataRezervare, value);
String dataAzi = getDataAzi();
reff.child("Users").child(nume).child("rezervari").child(dataRezervare).child(numeTeren).child("status").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
String status = (String) snapshot.getValue();
if(comparaData(dataAzi, rezervare.getData())){
if(status.equals("activa")){
rezervariActive.add(rezervare);
} else {
rezervariAnulate.add(rezervare);
}
} else {
rezervariTrecute.add(rezervare);
}
myCallback.onCallback(rezervariActive, rezervariTrecute, rezervariAnulate);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
});
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
and this is where i set the adapters
public void updateRezervari(View view, RecyclerView activeBookingsRecycler, RecyclerView pastBookingsRecycler, RecyclerView cancelledBookingsRecycler){
AsyncTask.execute(new Runnable() {
#Override
public void run() {
getRezervari(numeUtilizator, new RezervariListCallback() {
#Override
public void onCallback(List<Rezervare> rezervariActuale, List<Rezervare> rezervariTrecute, List<Rezervare> rezervariAnulate) {
if(rezervariActuale.size()>0){
tvFaraRezervariActive.setEnabled(false);
tvFaraRezervariAnulate.setEnabled(false);
tvFaraRezervariTrecute.setEnabled(false);
}
Log.v("rezAc", rezervariActuale.toString());
Log.v("rezTr", rezervariTrecute.toString());
RecyclerViewAdapterRezervare adapter = new RecyclerViewAdapterRezervare(rezervariActuale, view.getContext(), numeUtilizator);
activeBookingsRecycler.setAdapter(adapter);
adapter = new RecyclerViewAdapterRezervare(rezervariTrecute, view.getContext(), numeUtilizator);
pastBookingsRecycler.setAdapter(adapter);
adapter = new RecyclerViewAdapterRezervare(rezervariAnulate, view.getContext(), numeUtilizator);
cancelledBookingsRecycler.setAdapter(adapter);
}
});
}
});
}
Can you give me a few tips on how to move from one recycler view to another? Thank you!
Since you are using Firebase to fetch status of a booking, you can update the status to cancelled in your firebase database and then you will get a callback from your firebase listener where you can update your arraylists and call notifyDataSetChanged().
my java LogCat has this error:
E/RecyclerView: No adapter attached; skipping layout.
I tried all the solutions online but to no avail. When I click on a button in the recyclerview(list item) this Error will appear and my header do not change according to the database set. My database is working fine. can someone help me with this? I need to get this done in five days. Your help would be greatly appreciated.
public class contactsPage extends AppCompatActivity {
RecyclerView recyclerView;
AdapterUsers adapterUsers;
DatabaseReference ref;
FirebaseDatabase database;
List<ModelUser>userList;
FirebaseAuth firebaseAuth;
private void checkUserStatus() {
//get current user
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
}
else {
startActivity(new Intent(this, login.class));
finish();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contacts_page);
recyclerView = findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
//init user list
userList = new ArrayList<>();
//getall user
getAllUsers();
}
private void getAllUsers () {
//get current user
final FirebaseUser fUser = FirebaseAuth.getInstance().getCurrentUser();
//get path of database named users
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Users");
//get all data from path
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
userList.clear();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
ModelUser modelUser = ds.getValue(ModelUser.class);
//get all users except currently signed in user
if (!modelUser.getEmail().equals(fUser.getEmail())) {
userList.add(modelUser);
}
//adapter
adapterUsers = new AdapterUsers(contactsPage.this, userList);
//set adapter to recycler view
recyclerView.setAdapter(adapterUsers);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
My adapter class are as follow:
package com.example.black.adapters;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import com.example.whereareu.ChatActivity;
import com.example.whereareu.R;
import com.example.whereareu.models.ModelUser;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
public class AdapterUsers extends RecyclerView.Adapter<AdapterUsers.MyHolder>{
Context context;
List<ModelUser> userList;
//constructor
public AdapterUsers(Context context, List<ModelUser> userList) {
this.context = context;
this.userList = userList;
}
#NonNull
#Override
public MyHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
//inflate layout(row_users.xml)
View view = LayoutInflater.from(context).inflate(R.layout.row_users, parent, false);
return new MyHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyHolder holder, int position) {
//get data
final String hisUID = userList.get(position).getUid();
final String userName = userList.get(position).getName();
String userEmail = userList.get(position).getEmail();
//set data
holder.userName.setText(userName);
holder.userEmail.setText(userEmail);
//handle item click
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, ChatActivity.class);
intent.putExtra("hisUID", hisUID);
context.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return userList.size();
}
//view holder class
class MyHolder extends RecyclerView.ViewHolder{
TextView userName, userEmail;
public MyHolder(#NonNull View itemView) {
super(itemView);
//init views
userName = itemView.findViewById(R.id.userName);
userEmail = itemView.findViewById(R.id.userEmail);
}
}
}
Try to write adapter codes out of the for-loop.
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
userList.clear();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
ModelUser modelUser = ds.getValue(ModelUser.class);
//get all users except currently signed in user
if (!modelUser.getEmail().equals(fUser.getEmail())) {
userList.add(modelUser);
}
}
//adapter
adapterUsers = new AdapterUsers(contactsPage.this, userList);
//set adapter to recycler view
recyclerView.setAdapter(adapterUsers);
}
You are setting the adapter only when the data is finished loading in the background.
You need to call recyclerView.setAdapter(yourAdapter) before the layout finishes loading. I suggest you do something like:
public class ContactsPageActivity extends AppCompatActivity {
// ...
AdapterUsers adapterUsers = new AdapterUsers(this);
List<ModelUser> userList = = new ArrayList<>();
// ...
#Override
protected void onCreate(Bundle savedInstanceState) {
// ...
recyclerView = findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(adapterUsers);
getAllUsers();
}
private void getAllUsers () {
// ...
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
// ...
adapterUsers.update(userList); // You need to create this method in your adapter. Call "notifyDatasetChanged" in it.
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
Also it needs to be out of the loop, like #Sinan Dönmez said
I am using RecyclerView to show data that is fetching from firebase Realtime Database. When I am opening recycler view activity it is showing nothing but when I go to previous activity come again then it is showing.
THIS IS THE ACTIVITY IN WHICH DATA HAS TO BE SHOWN-
public class BrakesItemActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private FloatingActionButton floatingActionButton;
private FirebaseDatabase database;
private DatabaseReference BrakestransactionDb, brakesDb;
private FirebaseRecyclerOptions<Transaction> options;
private FirebaseRecyclerAdapter<Transaction, TransactionViewHolder> adapter;
int sumofbrakescost = 0;
String sumofbrakescostvalue;
BottomAppBar bottomAppBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_last2);
bottomAppBar = findViewById(R.id.bottom_app_bar);
recyclerView = findViewById(R.id.recycler_view);
floatingActionButton = findViewById(R.id.floating_button);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
setSupportActionBar(bottomAppBar);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(BrakesItemActivity.this, BInputActivity.class);
startActivity(intent);
}
});
database = FirebaseDatabase.getInstance();
BrakestransactionDb = database.getReference().child("Brakes Items Transaction");
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(BrakesItemActivity.this));
BrakestransactionDb.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
Map<String, Object> map = (Map<String, Object>) ds.getValue();
Object totalcost = map.get("totalcoststring");
int totalcostvalue = Integer.parseInt(String.valueOf(totalcost));
sumofbrakescost += totalcostvalue;
sumofbrakescostvalue = String.valueOf(sumofbrakescost);
}
brakesDb = database.getReference().child("Department").child("Brakes").child("Cost");
brakesDb.setValue(sumofbrakescostvalue);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
showTask();
}
private void showTask() {
options = new FirebaseRecyclerOptions.Builder<Transaction>().setQuery(BrakestransactionDb, Transaction.class).build();
adapter = new FirebaseRecyclerAdapter<Transaction, TransactionViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull TransactionViewHolder holder, int position, #NonNull Transaction model) {
holder.item_name_card.setText(model.getNameofitemstring());
holder.bought_by_card.setText(model.getBoughtbystring());
holder.bought_from_card.setText(model.getBoughtfromstring());
holder.date_card.setText(model.getDatestring());
holder.time_card.setText(model.getTimestring());
holder.cost_of_one_item_card.setText(model.getCostofoneitemstring());
holder.number_of_items_card.setText(model.getNumberofitemstring());
holder.total_cost_card.setText(model.getTotalcoststring());
}
#NonNull
#Override
public TransactionViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.transaction_row, parent, false);
return new TransactionViewHolder(itemView);
}
};
recyclerView.setAdapter(adapter);
}
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
#Override
public boolean onContextItemSelected(#NonNull MenuItem item) {
if (item.getTitle().equals("Delete")) {
deleteTransaction(adapter.getRef(item.getOrder()).getKey());
}
return super.onContextItemSelected(item);
}
private void deleteTransaction(String key) {
BrakestransactionDb.child(key).removeValue();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.bottommenu, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
if (item.getItemId() == R.id.delete_all) {
BrakestransactionDb.removeValue();
}
if (item.getItemId() == R.id.home_button) {
Intent intent = new Intent(this, NavActivity.class);
finish();
startActivity(intent);
if (item.getItemId() == R.id.back_item_activity) {
Intent intent1 = new Intent(this, Department.class);
finish();
startActivity(intent1);
}
}
return super.onOptionsItemSelected(item);
}
}
THIS IS THE MODEL CLASS I MADE-
package com.example.android.zfr.Model;
public class Transaction {
private String nameofitemstring,boughtbystring,boughtfromstring,costofoneitemstring,datestring,
timestring,totalcoststring,numberofitemstring;
public String getNameofitemstring() { return nameofitemstring; }
public void setNameofitemstring(String nameofitemstring) { this.nameofitemstring = nameofitemstring; }
public String getBoughtbystring() {return boughtbystring; }
public void setBoughtbystring(String bought string) {
this.boughtbystring = boughtbystring;
}
public String getBoughtfromstring() { return boughtfromstring; }
public void setBoughtfromstring(String boughtfromstring) { this.boughtfromstring = boughtfromstring; }
public String getCostofoneitemstring() {
return costofoneitemstring;
}
public void setCostofoneitemstring(String costofoneitemstring) { this.costofoneitemstring = costofoneitemstring; }
public String getDatestring() { return datestring; }
public void setDatestring(String datestring) { this.datestring = datestring; }
public String getTimestring() { return timestring; }
public void setTimestring(String timestring) { this.timestring = timestring; }
public String getTotalcoststring() { return totalcoststring; }
public void setTotalcoststring(String totalcoststring) { this.totalcoststring = totalcoststring; }
public String getNumberofitemstring() { return numberofitemstring; }
public void setNumberofitemstring(String numberofitemstring) { this.numberofitemstring = numberofitemstring; }
public Transaction() { }
public Transaction(String nameofitemstring,String boughtbystring,String boughtfromstring,String costofoneitemstring, String timestring,
String datestring ,String totalcoststring , String numberofitemstring ){
this.nameofitemstring=nameofitemstring;
this.boughtbystring=boughtbystring;
this.boughtfromstring=boughtfromstring;
this.costofoneitemstring=costofoneitemstring;
this.datestring=datestring;
this.timestring=timestring;
this.numberofitemstring=numberofitemstring;
this.totalcoststring=totalcoststring;
}
}
THIS THE VIEWHOLDER CLASS-
package com.example.android.zfr.ViewHolder;
import android.view.ContextMenu;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.android.zfr.R;
import com.facebook.shimmer.ShimmerFrameLayout;
public class TransactionViewHolder extends RecyclerView.ViewHolder implements
View.OnCreateContextMenuListener{
public TextView item_name_card,bought_by_card,bought_from_card,date_card,
time_card,cost_of_one_item_card,number_of_items_card,total_cost_card;
public TransactionViewHolder(#NonNull View itemView) {
super(itemView);
item_name_card=itemView.findViewById(R.id.item_name_card);
bought_by_card=itemView.findViewById(R.id.bought_by_card);
bought_from_card=itemView.findViewById(R.id.bought_from_card);
date_card=itemView.findViewById(R.id.date_card);
time_card=itemView.findViewById(R.id.time_card);
cost_of_one_item_card=itemView.findViewById(R.id.cost_of_one_item_card);
number_of_items_card=itemView.findViewById(R.id.number_of_items_card);
total_cost_card=itemView.findViewById(R.id.total_cost_card);
itemView.setOnCreateContextMenuListener(this);
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo)
{ menu.add(0,0,getAdapterPosition(),"Delete"); }
}
Please help.
you need to realize that Firebase is Asynchronous, meaning that your showTask() gets called even before your database is able to send you the data. To avoid this issue, you need to put your showTask() inside your addValueEventListener. Try this:
BrakestransactionDb.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
Map<String, Object> map = (Map<String, Object>) ds.getValue();
Object totalcost = map.get("totalcoststring");
int totalcostvalue = Integer.parseInt(String.valueOf(totalcost));
sumofbrakescost += totalcostvalue;
sumofbrakescostvalue = String.valueOf(sumofbrakescost);
}
brakesDb = database.getReference().child("Department").child("Brakes").child("Cost");
brakesDb.setValue(sumofbrakescostvalue);
showTask();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
It worked by putting
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(BrakesItemActivity.this));
in onDatachange method like this:
BrakestransactionDb.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
Map<String, Object> map = (Map<String, Object>) ds.getValue();
Object totalcost = map.get("totalcoststring");
int totalcostvalue = Integer.parseInt(String.valueOf(totalcost));
sumofbrakescost += totalcostvalue;
sumofbrakescostvalue = String.valueOf(sumofbrakescost);
}
brakesDb = database.getReference().child("Department").child("Brakes").child("Cost");
brakesDb.setValue(sumofbrakescostvalue);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(BrakesItemActivity.this));
}
I'm making a voting system in an android app that uses firebase as it's backend. I'm in the process of getting the user's vote status from their history, updating the view accordingly, and responding to vote touches on the buttons. The problem I'm having is that when a user clicks on the up or down vote buttons it redraws the listview, sometimes omitting two of the options, and always moving the scrolling of the view back up to the top. Can I update the data inside of a listview without completely redrawing that listview? If so, how?
MovieActivity.java
public class MovieActivity extends AppCompatActivity {
private static final String KEY_IMDB = "KEY_IMDB";
private ImageView mPosterImageView;
private TextView mTitleTextView;
private TextView mYearTextView;
private TextView mSummaryTextView;
private ListView triggerListView;
private ArrayList<Trigger> mTriggerPrefList;
private Movie mMovie;
private LinkedList<Trigger> resultList;
DatabaseReference movieDB;
DatabaseReference userDB;
DatabaseReference thisMovieDB;
DatabaseReference triggerDB;
DatabaseReference adminDB;
FirebaseAuth mFirebaseAuth;
FirebaseUser mUser;
ArrayList<Trigger> mTriggerList;
String imdbID;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_movie);
mPosterImageView = (ImageView) findViewById(R.id.posterImageView);
mTitleTextView = (TextView) findViewById(R.id.titleTextView);
mYearTextView = (TextView) findViewById(R.id.yearTextView);
mSummaryTextView = (TextView) findViewById(R.id.summaryTextView);
triggerListView = (ListView) findViewById(R.id.triggerListView);
mFirebaseAuth = FirebaseAuth.getInstance();
mUser = mFirebaseAuth.getCurrentUser();
movieDB = FirebaseDatabase.getInstance().getReference("movies");
userDB = FirebaseDatabase.getInstance().getReference("users");
adminDB = FirebaseDatabase.getInstance().getReference("admin");
Intent intent = getIntent();
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
imdbID = intent.getStringExtra("ID_KEY");
final String keyTitle = intent.getStringExtra("TITLE_KEY");
final String keyYear = intent.getStringExtra("YEAR_KEY");
final String keyPoster = intent.getStringExtra("POSTER_KEY");
try {
getMovieDetails(imdbID, new Runnable() {
#Override
public void run() {
CheckForTriggerValues(new Runnable() {
#Override
public void run() {
populateTriggers(new Runnable() {
#Override
public void run() {
populatePrefs(new Runnable() {
#Override
public void run() {
reOrderList(new Runnable() {
#Override
public void run() {
Movie passMovie = new Movie();
passMovie.setImdbID(imdbID);
passMovie.setPosterURL(keyPoster);
passMovie.setYear(keyYear);
passMovie.setTitle(keyTitle);
TriggerAdapter adapter = new TriggerAdapter(MovieActivity.this, resultList, passMovie, imdbID );
triggerListView.setAdapter(adapter);
}
});
}
});
}
});
}
});
}
});
} catch (JSONException e) {
e.printStackTrace();
}
thisMovieDB = movieDB.child(imdbID);
triggerDB = thisMovieDB.child("Triggers");
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(KEY_IMDB, imdbID);
}
#Override
protected void onStart() {
super.onStart();
Intent intent = getIntent();
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
imdbID = intent.getStringExtra("ID_KEY");
}
private void getMovieDetails(String imdbID, Runnable runnable) throws JSONException {
String apiKey = OMITTED;
String theURL = "http://www.omdbapi.com/?i=" + imdbID + "&apikey=" + apiKey;
final OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(theURL).build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
final String jsonData = response.body().string();
if (response.isSuccessful()) {
runOnUiThread(new Runnable() {
#Override
public void run() {
try {
Movie movie = parseMovieDetails(jsonData);
updateMovieUI(movie);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
}
});
runnable.run();
}
private Movie parseMovieDetails(String jsonData) throws JSONException {
JSONObject jsonObject = new JSONObject(jsonData);
Movie movie = new Movie();
movie.setPosterURL(jsonObject.getString("Poster"));
movie.setTitle(jsonObject.getString("Title"));
movie.setYear(jsonObject.getString("Year"));
movie.setSummary(jsonObject.getString("Plot"));
mMovie = movie;
return movie;
}
private void updateMovieUI(Movie movie){
Context mContext = getApplicationContext();
mSummaryTextView.setText(movie.getSummary());
mYearTextView.setText(movie.getYear());
mTitleTextView.setText(movie.getTitle());
Picasso.with(mContext).load(movie.getPosterURL()).into(mPosterImageView);
}
private void populatePrefs(final Runnable runnable) {
mTriggerPrefList = new ArrayList<>();
mFirebaseAuth = FirebaseAuth.getInstance();
mUser = mFirebaseAuth.getCurrentUser();
movieDB = FirebaseDatabase.getInstance().getReference("movies");
userDB = FirebaseDatabase.getInstance().getReference("users");
adminDB = FirebaseDatabase.getInstance().getReference("admin");
thisMovieDB = movieDB.child(imdbID);
thisMovieDB.child("Details").setValue(mMovie);
triggerDB = thisMovieDB.child("Triggers");
userDB.child(mUser.getUid()).child("preferences").child("trigger").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot triggerSnapshot : dataSnapshot.getChildren()) {
String name = String.valueOf(triggerSnapshot.child("triggerName").getValue());
Trigger trigger = new Trigger();
trigger.setTriggerName(name);
trigger.setTriggerVotesTotal(0);
trigger.setTriggerVotesYes(0);
mTriggerPrefList.add(trigger);
}
Intent intent = getIntent();
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
imdbID = intent.getStringExtra("ID_KEY");
runnable.run();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void populateTriggers(final Runnable runnable) {
mTriggerList = new ArrayList<>();
mFirebaseAuth = FirebaseAuth.getInstance();
mUser = mFirebaseAuth.getCurrentUser();
movieDB = FirebaseDatabase.getInstance().getReference("movies");
userDB = FirebaseDatabase.getInstance().getReference("users");
adminDB = FirebaseDatabase.getInstance().getReference("admin");
thisMovieDB = movieDB.child(imdbID);
thisMovieDB.child("Details").setValue(mMovie);
triggerDB = thisMovieDB.child("Triggers");
triggerDB.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
mTriggerList.clear();
for (DataSnapshot triggerSnapshot : dataSnapshot.getChildren()) {
Trigger trigger = triggerSnapshot.getValue(Trigger.class);
mTriggerList.add(trigger);
}
runnable.run();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void reOrderList(Runnable runnable) {
resultList = new LinkedList<>();
for (Trigger triggerA : mTriggerList) {
boolean found = false;
for (Trigger triggerB : mTriggerPrefList) {
if (triggerB.getTriggerName().equals(triggerA.getTriggerName())) {
found = true;
}
}
if (found) {
resultList.add(triggerA);
}
}
mTriggerList.removeAll(resultList);
resultList.addAll(mTriggerList);
runnable.run();
}
private void CheckForTriggerValues(final Runnable runnable) {
adminDB.child("triggerList").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
GenericTypeIndicator<Map<String, Object>> genericTypeIndicator = new GenericTypeIndicator<Map<String, Object>>() {};
final Map<String, Object> triggerList = dataSnapshot.getValue(genericTypeIndicator);
triggerDB.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (Map.Entry<String, Object> entry : triggerList.entrySet())
{
if (dataSnapshot.hasChild(entry.getKey())){
}
else {
Trigger trigger1 = new Trigger(entry.getKey(), 0, 0);
triggerDB.child(trigger1.getTriggerName()).setValue(trigger1);
}
}
runnable.run();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
int isTrue(Boolean boolDown, Boolean boolUp) {
int x = 0;
if (boolUp) {
x = 1;
}
if (boolDown) {
x = -1;
}
return x;
}
}
TriggerAdapter.java
package me.paxana.cwnet.Adapters;
import android.app.Activity;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Typeface;
import android.os.Build;
import android.provider.ContactsContract;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.TextView;
import com.andremion.counterfab.CounterFab;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.MutableData;
import com.google.firebase.database.Transaction;
import com.google.firebase.database.ValueEventListener;
import java.util.List;
import me.paxana.cwnet.Model.Movie;
import me.paxana.cwnet.Model.Trigger;
import me.paxana.cwnet.R;
import me.paxana.cwnet.ui.AdminPanelActivity;
import me.paxana.cwnet.ui.MovieActivity;
/**
* Created by paxie on 10/11/17.
*/
public class TriggerAdapter extends BaseAdapter {
private Context mContext;
private List<Trigger> mTriggers;
private Movie mMovie;
private String mImdbID;
private String mTitle;
private String mYear;
private String mPosterURL;
private DatabaseReference movieDB;
private DatabaseReference userDB;
private DatabaseReference triggerDB;
private DatabaseReference adminDB;
public TriggerAdapter(Context context, List<Trigger> triggerList, Movie movie, String imdbID){
mContext = context;
this.mTriggers = triggerList;
mMovie = movie;
mImdbID = imdbID;
mTitle = movie.getTitle();
mYear = movie.getYear();
mPosterURL = movie.getPosterURL();
};
public TriggerAdapter(Context context, List<Trigger> triggerList) {
mContext = context;
this.mTriggers = triggerList;
}
#Override
public int getCount() {
return this.mTriggers.size();
}
#Override
public Object getItem(int i) {
return mTriggers.get(i);
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int i, View view, final ViewGroup viewGroup) {
final ViewHolder holder;
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
FirebaseUser user = firebaseAuth.getCurrentUser();
movieDB = FirebaseDatabase.getInstance().getReference("movies");
userDB = FirebaseDatabase.getInstance().getReference("users");
adminDB = FirebaseDatabase.getInstance().getReference("admin");
final String mUserId = user.getUid();
final Trigger trigger = mTriggers.get(i);
if (view == null) {
view = LayoutInflater.from(mContext).inflate(R.layout.trigger_list_item, null);
holder = new ViewHolder();
holder.triggerName = view.findViewById(R.id.triggerName);
holder.upButton = view.findViewById(R.id.mTriggerButtonUp);
holder.downButton = view.findViewById(R.id.mTriggerButtonDown);
holder.total = view.findViewById(R.id.triggerCounter);
view.setTag(holder);
}
else {
holder = (ViewHolder) view.getTag();
}
holder.triggerName.setText(trigger.getTriggerName());
if (mContext instanceof AdminPanelActivity) {
holder.upButton.setVisibility(View.INVISIBLE);
holder.downButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
adminDB.child("triggerList").child(trigger.getTriggerName()).removeValue();
int i = mTriggers.indexOf(trigger);
mTriggers.remove(i);
TriggerAdapter.this.notifyDataSetChanged();
}
});
}
if (mContext instanceof MovieActivity) {
userDB.child(mUserId).child("changes").child(mImdbID).child("triggers").child(trigger.getTriggerName()).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.getValue() != null) {
int userVote = dataSnapshot.getValue(Integer.class);
if (userVote == 0) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
holder.upButton.setBackgroundTintList(mContext.getResources().getColorStateList(R.color.colorAccent, null));
holder.downButton.setBackgroundTintList(mContext.getResources().getColorStateList(R.color.colorAccent, null));
}
else {
holder.upButton.setBackgroundTintList(mContext.getResources().getColorStateList(R.color.colorAccent));
holder.downButton.setBackgroundTintList(mContext.getResources().getColorStateList(R.color.colorAccent));
}
neitherButtonIsSelected(holder, trigger, mUserId);
}
if (userVote == 1) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
holder.upButton.setBackgroundTintList(mContext.getResources().getColorStateList(R.color.votebuttons, null));
holder.downButton.setBackgroundTintList(mContext.getResources().getColorStateList(R.color.colorAccent, null));
}
else {
holder.upButton.setBackgroundTintList(mContext.getResources().getColorStateList(R.color.votebuttons));
holder.downButton.setBackgroundTintList(mContext.getResources().getColorStateList(R.color.colorAccent));
}
upButtonIsSelected(holder, trigger, mUserId);
}
if (userVote == -1) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
holder.upButton.setBackgroundTintList(mContext.getResources().getColorStateList(R.color.colorAccent, null));
holder.downButton.setBackgroundTintList(mContext.getResources().getColorStateList(R.color.votebuttons, null));
}
else {
holder.upButton.setBackgroundTintList(mContext.getResources().getColorStateList(R.color.colorAccent));
holder.downButton.setBackgroundTintList(mContext.getResources().getColorStateList(R.color.votebuttons));
}
downButtonIsSelected(holder, trigger, mUserId);
}
}
else {
userDB.child(mUserId).child("changes").child(mImdbID).child("triggers").child(trigger.getTriggerName()).setValue(0);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
holder.total.setText(String.valueOf(trigger.getTriggerVotesYes()));
holder.upButton.setCount(trigger.getTriggerVotesYes());
if (trigger.getTriggerVotesTotal() != 0){
holder.total.setText(String.valueOf(trigger.getTriggerVotesTotal()));
int downButtonCount = (trigger.getTriggerVotesTotal() - trigger.getTriggerVotesYes());
holder.downButton.setCount(downButtonCount);
}
return view;
}
private static class ViewHolder {
TextView triggerName;
CounterFab upButton;
CounterFab downButton;
TextView total;
}
private void neitherButtonIsSelected(final ViewHolder holder, final Trigger trigger, final String mUserId) {
holder.upButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
triggerDB = movieDB.child(mImdbID).child("Triggers").child(trigger.getTriggerName());
triggerDB.child("triggerVotesYes").runTransaction(new Transaction.Handler() {
#Override
public Transaction.Result doTransaction(MutableData mutableData) {
int count = mutableData.getValue(Integer.class);
mutableData.setValue(count + 1);
return Transaction.success(mutableData);
}
#Override
public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) {
}
});
triggerDB.child("triggerVotesTotal").runTransaction(new Transaction.Handler() {
#Override
public Transaction.Result doTransaction(MutableData mutableData) {
int count = mutableData.getValue(Integer.class);
mutableData.setValue(count + 1);
userDB.child(mUserId).child("changes").child(mImdbID).child("triggers").child(trigger.getTriggerName()).setValue(1);
return Transaction.success(mutableData);
}
#Override
public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) {
}
});
userDB.child(mUserId).child("changes").child(mImdbID).child("triggers").child(trigger.getTriggerName()).setValue(1);
}
});
holder.downButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View view) {
triggerDB.child("triggerVotesTotal").runTransaction(new Transaction.Handler() {
#Override
public Transaction.Result doTransaction(MutableData mutableData) {
int count = mutableData.getValue(Integer.class);
mutableData.setValue(count + 1);
userDB.child(mUserId).child("changes").child(mImdbID).child("triggers").child(trigger.getTriggerName()).setValue(1);
return Transaction.success(mutableData);
}
#Override
public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) {
}
});
userDB.child(mUserId).child("changes").child(mImdbID).child("triggers").child(trigger.getTriggerName()).setValue(1);
}
});
}
private void upButtonIsSelected(final ViewHolder holder, final Trigger trigger, final String mUserId) {
holder.upButton.setOnClickListener(null);
holder.downButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View view) {
triggerDB = movieDB.child(mImdbID).child("Triggers").child(trigger.getTriggerName());
triggerDB.child("triggerVotesYes").runTransaction(new Transaction.Handler() {
#Override
public Transaction.Result doTransaction(MutableData mutableData) {
int count = mutableData.getValue(Integer.class);
mutableData.setValue(count - 1);
userDB.child(mUserId).child("changes").child(mImdbID).child("triggers").child(trigger.getTriggerName()).setValue(-1);
return Transaction.success(mutableData);
}
#Override
public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) {
holder.downButton.getBackground().setAlpha(127);
}
});
}
});
}
private void downButtonIsSelected(final ViewHolder holder, final Trigger trigger, final String mUserId) {
holder.downButton.setOnClickListener(null);
holder.upButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View view) {
triggerDB = movieDB.child(mImdbID).child("Triggers").child(trigger.getTriggerName());
triggerDB.child("triggerVotesYes").runTransaction(new Transaction.Handler() {
#Override
public Transaction.Result doTransaction(MutableData mutableData) {
int count = mutableData.getValue(Integer.class);
mutableData.setValue(count + 1);
userDB.child(mUserId).child("changes").child(mImdbID).child("triggers").child(trigger.getTriggerName()).setValue(1);
return Transaction.success(mutableData);
}
#Override
public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) {
holder.downButton.getBackground().setAlpha(127);
}
});
}
});
}
}
Following things might help you.
Use android:stackFromBottom="true" in the xml of your ListView
Instead of using mTriggerList.clear(); when updating, do not clear it and add the item to list only if the item does not already exist in the list.
Eg.
for(Trigger trigger: triggerSnapShot...){
if (!mTriggerList.contains(trigger)){
mTriggerList.add(trigger);
}
}
You may need to override the equals method in the Trigger class in order to make the method contains work properly.