I am new begginer to android. What I am trying is to make an app that people can share images with each other.(similar to instagram) I am using firebase store and storage for that. Adding a new image on a recyclerview is not a problem and also I would like to remove the item when I longclick on it. But in my case when I longclick the item, not only the item is removed but also the rest of the items are dublicated.I added an example picture here.problem example
But once I restart the app list seems fine without any dublication.
here is my feed screen code;
public class FeedActivity extends AppCompatActivity implements FeedRecyclerAdapter.OnNoteListener {
private FirebaseAuth firebaseAuth;
private FirebaseFirestore firebaseFirestore;
private FirebaseStorage firebaseStorage;
private StorageReference storageReference;
ArrayList<String> userEmailFromFB;
ArrayList<String> usercommentFromFB;
ArrayList<String> userImageFromFB;
FeedRecyclerAdapter feedRecyclerAdapter;
ArrayList<String> dokumanl;
ArrayList<String> namel;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater=getMenuInflater();
menuInflater.inflate(R.menu.insta_options_menu,menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
if (item.getItemId()== R.id.add_post){
Intent intentToUpload=new Intent(FeedActivity.this, UploadActivity.class);
startActivity(intentToUpload);
}else if (item.getItemId()==R.id.signout){
firebaseAuth.signOut();
Intent intentToSignUp=new Intent(FeedActivity.this,SignUpActivity.class);
startActivity(intentToSignUp);
finish();
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_feed);
usercommentFromFB=new ArrayList<>();
userEmailFromFB=new ArrayList<>();
userImageFromFB=new ArrayList<>();
dokumanl =new ArrayList<>();
namel=new ArrayList<>();
firebaseStorage = FirebaseStorage.getInstance();
storageReference= firebaseStorage.getReference();
firebaseAuth=FirebaseAuth.getInstance();
firebaseFirestore=FirebaseFirestore.getInstance();
RecyclerView recyclerView=findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
feedRecyclerAdapter= new FeedRecyclerAdapter(userEmailFromFB,usercommentFromFB,userImageFromFB, this);
recyclerView.setAdapter(feedRecyclerAdapter);
getDataFromFirestore();
}
public void getDataFromFirestore(){
CollectionReference collectionReference=firebaseFirestore.collection("Posts");
collectionReference.orderBy("date", Query.Direction.DESCENDING).addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(#Nullable QuerySnapshot queryDocumentSnapshots, #Nullable FirebaseFirestoreException e) {
if (e != null){
Toast.makeText(FeedActivity.this, e.getLocalizedMessage().toString(), Toast.LENGTH_LONG).show();
}
if( queryDocumentSnapshots != null){
for( DocumentSnapshot snapshot: queryDocumentSnapshots.getDocuments()){
Map<String,Object> data= snapshot.getData();
String comment= (String)data.get("comment");
String userEmail=(String)data.get("useremail");
String downloadUrl= (String)data.get("downloadurl");
String dokuman= snapshot.getId();
String name= (String)data.get("name");
usercommentFromFB.add(comment);
userEmailFromFB.add(userEmail);
userImageFromFB.add(downloadUrl);
dokumanl.add(dokuman);
namel.add(name);
feedRecyclerAdapter.notifyDataSetChanged();
}
}
}
});
}
#Override
public void onNoteClick(int position) {
//System.out.println("position:"+ namel.get(position));
StorageReference desertRef= storageReference.child(namel.get(position));
desertRef.delete();
firebaseFirestore.collection("Posts").document(dokumanl.get(position))
.delete()
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(FeedActivity.this, "Silindi", Toast.LENGTH_LONG).show();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
}
});
usercommentFromFB.remove(position);
userImageFromFB.remove(position);
userEmailFromFB.remove(position);
dokumanl.remove(position);
namel.remove(position);
feedRecyclerAdapter.notifyDataSetChanged();
}
}
Also here is my adapter code;
public class FeedRecyclerAdapter extends RecyclerView.Adapter<FeedRecyclerAdapter.PostHolder> {
private ArrayList<String> userEmailList;
private ArrayList<String> userCommentList;
private ArrayList<String> userImageList;
private OnNoteListener mOnNoteListener;
public FeedRecyclerAdapter(ArrayList<String> userEmailList, ArrayList<String> userCommentList, ArrayList<String> userImageList, OnNoteListener onNoteListener) {
this.userEmailList = userEmailList;
this.userCommentList = userCommentList;
this.userImageList = userImageList;
this.mOnNoteListener= onNoteListener;
}
#NonNull
#Override
public PostHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater=LayoutInflater.from(parent.getContext());
View view=layoutInflater.inflate(R.layout.recycler_row,parent,false);
return new PostHolder(view, mOnNoteListener);
}
#Override
public void onBindViewHolder(#NonNull PostHolder holder, int position) {
holder.userEmailText.setText(userEmailList.get(position));
holder.commentText.setText(userCommentList.get(position));
Picasso.get().load(userImageList.get(position)).into(holder.imageView);
}
#Override
public int getItemCount() {
return userEmailList.size();
}
class PostHolder extends RecyclerView.ViewHolder implements View.OnLongClickListener {
ImageView imageView;
TextView userEmailText;
TextView commentText;
OnNoteListener onNoteListener;
public PostHolder(#NonNull View itemView, OnNoteListener onNoteListener) {
super(itemView);
imageView=itemView.findViewById(R.id.recyclerView_row_imageview);
userEmailText=itemView.findViewById(R.id.recyclerView_row_useremail_text);
commentText=itemView.findViewById(R.id.recyclerView_row_comment_text);
this.onNoteListener=onNoteListener;
itemView.setOnLongClickListener(this);
}
#Override
public boolean onLongClick(View v) {
onNoteListener.onNoteClick(getAdapterPosition());
return false;
}
}
public interface OnNoteListener{
void onNoteClick(int position);
}
}
Try this:
In your onNoteClick(int position) method in your FeedActivity:
Move these lines:
usercommentFromFB.remove(position);
userImageFromFB.remove(position);
userEmailFromFB.remove(position);
dokumanl.remove(position);
namel.remove(position);
feedRecyclerAdapter.notifyDataSetChanged();
Directly in the addOnSuccessListener:
........
........
firebaseFirestore.collection("Posts").document(dokumanl.get(position))
.delete()
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(FeedActivity.this, "Silindi", Toast.LENGTH_LONG).show();
//here..........
}
})
..........
..........
Related
I am using a recyclerview to show cardview elements, and have made an adapter for the same. When I use an Arraylist to store the values, the recyclerview works as expected and the elements show. Howver, I want to use a linked list as items are constantly added and deleted. When I try to use a linked list, the recyclerview doesn't work and the elements don't show. How can I fix this?
My class code:
public class AdminViewAlertsActivity extends AppCompatActivity {
RecyclerView recyclerView;
DatabaseReference database;
AlertAdapter alertAdapter;
ArrayList<AlertModel> list;
LinkedList<AlertModel> list2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_admin_view_alerts);
recyclerView = findViewById(R.id.alerts_list);
database = FirebaseDatabase.getInstance().getReference("Alerts");
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
list = new ArrayList<>();
list2 = new LinkedList<>();
alertAdapter = new AlertAdapter(this,list2);
recyclerView.setAdapter(alertAdapter);
database.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot:snapshot.getChildren()){
AlertModel alertModel = dataSnapshot.getValue(AlertModel.class);
list.add(alertModel);
alertAdapter.notifyDataSetChanged();
}
alertAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
My adapter code:
public class AlertAdapter extends RecyclerView.Adapter<AlertAdapter.AlertViewHolder> {
Context context;
LinkedList<AlertModel> list;
AlertAdapter adapter;
public AlertAdapter(Context context, LinkedList<AlertModel> list) {
this.context = context;
this.list = list;
this.adapter = this;
}
#NonNull
#Override
public AlertViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.alrtitem,parent,false);
return new AlertViewHolder(v);
}
interface Interactions{
public void refreshActivity();
}
#Override
public void onBindViewHolder(#NonNull AlertViewHolder holder, int position) {
AlertModel alertModel = list.get(position);
holder.date_and_time.setText(alertModel.getDate_time());
holder.alert.setText(alertModel.getNotification());
holder.viewOptions.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
PopupMenu popup = new PopupMenu(context, holder.viewOptions);
popup.inflate(R.menu.alertmenu);
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem menuItem) {
switch (menuItem.getItemId()){
case R.id.alertmenu1:
DatabaseReference dataRef = FirebaseDatabase.getInstance().getReference();
dataRef.child("Alerts").child(alertModel.getDate_time()).removeValue().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Toast.makeText(context, "Removed", Toast.LENGTH_SHORT).show();
list.remove(holder.getBindingAdapterPosition());
adapter.notifyDataSetChanged();
}
});
default:
return false;
}
}
});
popup.show();
}
});
}
#Override
public int getItemCount() {
return list.size();
}
public static class AlertViewHolder extends RecyclerView.ViewHolder{
TextView date_and_time, alert, viewOptions;
public AlertViewHolder(#NonNull View itemView) {
super(itemView);
date_and_time = itemView.findViewById(R.id.date_and_time);
alert = itemView.findViewById(R.id.Alert);
viewOptions = itemView.findViewById(R.id.viewOptions);
}
}
}
Any help is appreciated!
I am having trouble with shuffling images in home screen in a wallpaper app. i want like when ever a person opens my app the images in the home screen should be shuffled . i tried using Collections.shuffle() method, in using that what is happening is the images are getting duplicated and when i click on the shuffled image to open in fullscreen some other image opens
suppose in a list A(0,1,2,3) when i shuffle it only the display changes but when i open it itopens according to the index of list A
please help me with the code as to where and how i have to use the Collections.shuffle method
here is my code .
I am troubled for many days and not getting the solution so please help
Homescreen.java
public class Homescreen extends AppCompatActivity {
RecyclerView recyclerView;
List<WallpaperModel> list;
private WallpaperAdapter adapter;
DatabaseReference reference;
public static final String TAG = Homescreen.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_homescreen);
init();
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new GridLayoutManager(this,3));
list = new ArrayList<>();
adapter.shuffle();
adapter.notifyDataSetChanged();
adapter = new WallpaperAdapter(list);
recyclerView.setAdapter(adapter);
reference = FirebaseDatabase.getInstance().getReference().child("Wallpapers");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
list.clear();
for (DataSnapshot dataSnapshot : snapshot.getChildren()){
WallpaperModel model = dataSnapshot.getValue(WallpaperModel.class);
list.add(model);
}
adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Log.e(TAG,error.getMessage());
}
});
}
private void
init(){
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
recyclerView = findViewById(R.id.recyclerView);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu,menu);
return true;
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
int id = item.getItemId();
if (id == R.id.favourite){
startActivity(new Intent(Homescreen.this, FavouriteActivity.class));
}
return true;
}
}
and this is my wallpaperAdapter class
public class WallpaperAdapter extends
RecyclerView.Adapter<WallpaperAdapter.WallpaperHolder> {
private static List<WallpaperModel> list;
public WallpaperAdapter(List<WallpaperModel> list) {
WallpaperAdapter.list = list;
}
#NonNull
#Override
public WallpaperHolder onCreateViewHolder(#NonNull ViewGroup parent, int
viewType) {
View view =
LayoutInflater.from(parent.getContext())
.inflate(R.layout.wallpaper_items,parent,false);
return new WallpaperHolder(view);
}
#Override
public void onBindViewHolder(#NonNull
WallpaperAdapter.WallpaperHolder holder, int position) {
Random random = new Random();
int color = Color.rgb(0,0,0);
Glide.with(holder.itemView.getContext().getApplicationContext())
.load(list.get(position).getImage())
.timeout(7500)
.into(holder.imageView);
holder.setClickListener();
}
#Override
public int getItemCount() {
return list.size();
}
public void shuffle() {
Collections.shuffle(list,new Random(System.currentTimeMillis()));
}
static class WallpaperHolder extends RecyclerView.ViewHolder{
private ImageView imageView;
public WallpaperHolder(#NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.imageView);
}
void setClickListener(){
//set on click listener on wallpaper image
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position = getAdapterPosition();
Intent intent = new Intent(itemView.getContext().getApplicationContext(),
SwiperActivity.class);
intent.putExtra("position",position);
itemView.getContext().startActivity(intent);
}
});
}
}
}
After implementing all the Recyclerview codes, i still end up with this Error :E/RecyclerView: No adapter attached; skipping layout.
Im not sure if it is because of the layout or where it is placed...
I changed the location of it multiple times and i had to revert back to an older version as some of the solutions i found on the internet caused it to crash.
public class MainMenu extends AppCompatActivity implements
IFirebaseLoadListener {
private Context context;
private List<ItemData> itemDataList;
private List<ItemGroup> dataList;
AlertDialog dialog;
IFirebaseLoadListener iFirebaseLoadListener;
RecyclerView my_recycler_view;
DatabaseReference myData;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_menu);
myData = FirebaseDatabase.getInstance().getReference("Data");
dialog = new SpotsDialog.Builder().setContext(this).build();
iFirebaseLoadListener = this;
//View
my_recycler_view = (RecyclerView)findViewById(R.id.my_recyclr_view);
my_recycler_view.setHasFixedSize(true);
my_recycler_view.setLayoutManager(new LinearLayoutManager(this));
getFirebaseData();
}
private void getFirebaseData () {
dialog.show();
myData.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange (#NonNull DataSnapshot dataSnapshot) {
List<ItemGroup> itemGroups =new ArrayList<>();
for(DataSnapshot groupSnapShot:dataSnapshot.getChildren()){
ItemGroup itemGroup = new ItemGroup();
itemGroup.setHeaderTitle(groupSnapShot.child("headerTitle").getValue (String.class));
GenericTypeIndicator<ArrayList<ItemData>> genericTypeIndicator =new GenericTypeIndicator<ArrayList<ItemData>>(){};
itemGroup.setListItem(groupSnapShot.child("listItem").getValue(genericTypeIndicator));
itemGroups.add(itemGroup);
}
iFirebaseLoadListener.onFirebaseLoadSuccess(itemGroups);
}
#Override
public void onCancelled (#NonNull DatabaseError databaseError) {
iFirebaseLoadListener.onFirebaseLoadFailed(databaseError.getMessage());
}
});
}
#Override
public void onFirebaseLoadSuccess(List<ItemGroup> itemGroupList) {
MyItemGroupAdapter adapter = new
MyItemGroupAdapter(this,itemGroupList);
my_recycler_view.setAdapter(adapter);
dialog.dismiss();
}
#Override
public void onFirebaseLoadFailed(String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
dialog.dismiss();
}
}
I have 2 other pages for my Adapters, "MyItemAdapter" and "MyItemGroupAdapter"
but im not sure why it isnt able to call them
My Adapters:
public class MyItemAdapter extends RecyclerView.Adapter<MyItemAdapter.MyViewHolder> {
private Context context;
private List<ItemData> itemDataList;
public MyItemAdapter(Context context, List<ItemData> itemDataList) {
this.context = context;
this.itemDataList = itemDataList;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View itemView = LayoutInflater.from(context).inflate(R.layout.layout_item,viewGroup,false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder myViewHolder, final int i) {
myViewHolder.txt_item_title.setText(itemDataList.get(i).getName());
Picasso.get().load(itemDataList.get(i).getArt()).into(myViewHolder. img_item);
myViewHolder.setiItemClickListener(new IItemClickListener() {
#Override
public void onItemClickListener(View view, int position) {
Toast.makeText(context, ""+itemDataList.get(i).getName(), Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {return (itemDataList != null ? itemDataList.size() : 0);
}
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView txt_item_title;
ImageView img_item;
IItemClickListener iItemClickListener;
public void setiItemClickListener(IItemClickListener iItemClickListener) {
this.iItemClickListener = iItemClickListener;
}
public MyViewHolder(#NonNull View itemView) {
super(itemView);
txt_item_title = itemView.findViewById(R.id.name);
img_item = itemView.findViewById(R.id.art);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
iItemClickListener.onItemClickListener(view,getAdapterPosition());
}
}
}
There's no data for your RecyclerView to display when the view is created.
Inside of your onCreate you should create your adapter with empty or null data then call setAdapter() on your RecyclerView using the empty adapter. Later, you can update the adapter with new data and call notifyDataSetChanged() on your adapter to refresh it.
Currently I can display all of the items in my RecyclerView. What I wish to do is calculate how many of these items there are. My items are saved in CardView. I don't want to calculate or sum any particular field, just the number of actual items. Here is my code and I have tried to set it up using getItemCount() method and attach this to a TextView and display outside of RecyclerView. This is not working for me:
public class COM800s1 extends AppCompatActivity {
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private CollectionReference attendanceRef = db.collection("Attendance");
private AttendanceAdapter adapter;
private Context context;
private TextView attendanceNumbers;
private int counter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_com800s1);
attendanceNumbers = findViewById(R.id.attendanceNums);
FloatingActionButton floatingActionButton = findViewById(R.id.button_add_session);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(COM800s1.this,NewAttendanceRecord.class));
}
});
setUpRecyclerView();
}
private void setUpRecyclerView() {
final Query query = attendanceRef.whereEqualTo("sessionID", "5I0PLcpgmwdcjKLYLgkU").orderBy("userEmail", Query.Direction.ASCENDING);
FirestoreRecyclerOptions<Attendance> options = new FirestoreRecyclerOptions.Builder<Attendance>()
.setQuery(query, Attendance.class).build();
adapter = new AttendanceAdapter(options);
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
//counter = adapter.getItemCount();
//attendanceNumbers.setText("Currently " +counter+ " students have attended this session");
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0,
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
adapter.deleteItem(viewHolder.getAdapterPosition());
}
}).attachToRecyclerView(recyclerView);
adapter.setSetOnItemClickListener(new AttendanceAdapter.OnItemClickListener() {
#Override
public void onItemClick(Attendance documentSnapshot, int position) {
}
});
}
#Override
protected void onStart () {
super.onStart();
adapter.startListening();
}
#Override
protected void onStop(){
super.onStop();
adapter.stopListening();
}
}
Here is my Adapter code:
public class AttendanceAdapter extends FirestoreRecyclerAdapter<Attendance, AttendanceAdapter.AttendanceHolder>{
private AttendanceAdapter.OnItemClickListener listener;
public AttendanceAdapter(#NonNull FirestoreRecyclerOptions<Attendance> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull AttendanceHolder holder, int position, #NonNull Attendance model) {
holder.textViewStudent.setText(model.getUserEmail());
holder.textViewTime.setText(model.getSignInTime());
holder.textViewSession.setText(model.getSessionID());
holder.textViewUserUID.setText(model.getUserUID());
}
#NonNull
#Override
public AttendanceHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.attendance_item, parent, false);
return new AttendanceAdapter.AttendanceHolder(v);
}
public void deleteItem(int position){
getSnapshots().getSnapshot(position).getReference().delete();
}
public int countItems(){
return getItemCount();
}
class AttendanceHolder extends RecyclerView.ViewHolder {
TextView textViewStudent;
TextView textViewTime;
TextView textViewSession;
TextView textViewUserUID;
public AttendanceHolder(View itemView){
super(itemView);
textViewStudent = itemView.findViewById(R.id.text_view_student_name);
textViewTime = itemView.findViewById(R.id.text_view_course);
textViewSession = itemView.findViewById(R.id.text_view_student_ID);
textViewUserUID = itemView.findViewById(R.id.text_view_user_UID);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION && listener != null){
listener.onItemClick(getSnapshots().get(position),position);
}
}
});
}
}
public interface OnItemClickListener{
void onItemClick(Attendance documentSnapshot, int position);
}
public void setSetOnItemClickListener(AttendanceAdapter.OnItemClickListener listener){
this.listener = listener;
}
Here is my updates code which returns null pointer object on the onClickListener:
public class COM800s1 extends AppCompatActivity {
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private CollectionReference attendanceRef = db.collection("Attendance");
private AttendanceAdapter adapter;
private TextView attendanceNumbers;
private TextView attendanceNumbs;
private Button attendanceButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_com800s1);
attendanceNumbs = findViewById(R.id.attendanceNums);
attendanceButton = findViewById(R.id.calculateAttendance);
FloatingActionButton floatingActionButton = findViewById(R.id.button_add_session);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(COM800s1.this,NewAttendanceRecord.class));
}
});
setUpRecyclerView();
attendanceButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
attendanceRef.whereEqualTo("sessionID", "5I0PLcpgmwdcjKLYLgkU").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
int count = 0;
for (DocumentSnapshot document : task.getResult()) {
count++;
attendanceNumbs = findViewById(R.id.attendanceNums);
attendanceNumbs.setText(count);
}
Log.d("TAG", count + "");
} else {
}
}
});
}
});
}
private void setUpRecyclerView() {
final Query query = attendanceRef.whereEqualTo("sessionID", "5I0PLcpgmwdcjKLYLgkU").orderBy("userEmail", Query.Direction.ASCENDING);
FirestoreRecyclerOptions<Attendance> options = new FirestoreRecyclerOptions.Builder<Attendance>()
.setQuery(query, Attendance.class).build();
adapter = new AttendanceAdapter(options);
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0,
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
adapter.deleteItem(viewHolder.getAdapterPosition());
}
}).attachToRecyclerView(recyclerView);
adapter.setSetOnItemClickListener(new AttendanceAdapter.OnItemClickListener() {
#Override
public void onItemClick(Attendance documentSnapshot, int position) {
}
});
}
#Override
protected void onStart () {
super.onStart();
adapter.startListening();
}
#Override
protected void onStop(){
super.onStop();
adapter.stopListening();
}
}
If you want to get the list of your recyclerView just create a static method in your recyclerView's adapter and just return your list in that.
for example:
public static List<modelOfYourList> getCount(){
return yourAdapterList;
}
Perhaps add something like this to your AttendanceAdapter class?
I took a look at the FirestoreRecyclerOptionsclass, which exposes a getSnapshots() method. This returns a ObservableSnapshotArray, which in turn extends from Base ObservableSnapshotArray, which exposes a size() method.
class AttendanceAdapter extends FirestoreRecyclerAdapter<Attendance, AttendanceAdapter.AttendanceHolder>{
{
private FirestoreRecyclerOptions<Attendance> options;
public AttendanceAdapter(#NonNull FirestoreRecyclerOptions<Attendance> options)
{
super(options);
this.options = options;
}
#Override
public int getItemCount()
{
final int count = options.getSnapshots() != null
? options.getSnapshots().size()
: 0;
return count;
}
Sources:
FirestoreRecyclerOptions
ObservableSnapshotArray
BaseObservableSnapshotArray
Update: I see that the FirestoreRecyclerAdapter already has a getItemCount method already and you are calling it. Perhaps the data has not yet returned? What are you seeing for the count when you print it?
If you are trying to make the counter variable as a global variable and use it outside the callback it will always be null because as #Vinnie mentioned in his answer, the data has not finished loading yet. What's really happening is that you are trying to get the data from the database and immediately use it it while the counter variable has the initial value of 0. Then, when getting the data from the database completes, it changes counter's value, but it's never read again. To solve this, the use result of your getItemCount() method inside your adapter class to set it's value to the TextView.
If you want to count the number of documents beneath a collection, please also see my answer from this post.
I tried to change the database in the console firebase but the data in my adapter unchanged, recylerview was only changed when the application is closed and opened again
MainActivity.java
public class MainActivity extends AppCompatActivity {
private List<ModelDB> dbList = new ArrayList<>();
private AdapterDB adapter;
private RecyclerView recyclerView;
FirebaseDatabase database;
DatabaseReference reference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFirebase();
getData();
initRecylerView();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu,menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.add_person:
Intent intent = new Intent(getApplicationContext(),RegisterActivity.class);
startActivity(intent);
break;
default:
Toast.makeText(getApplicationContext(),"lalalala",Toast.LENGTH_LONG).show();
break;
}
return super.onOptionsItemSelected(item);
}
private void initFirebase(){
database = FirebaseDatabase.getInstance();
reference = database.getReference("user");
}
private void initRecylerView(){
recyclerView = (RecyclerView)findViewById(R.id.rv_list);
recyclerView.setHasFixedSize(true);
adapter = new AdapterDB(dbList);
recyclerView.setAdapter(adapter);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
}
private void getData() {
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//loop data all user
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
//instance object to get and set data
ModelDB modelDB = postSnapshot.getValue(ModelDB.class);
//adding data list from object
dbList.add(modelDB);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
AdapterDB.java
public class AdapterDB extends RecyclerView.Adapter<AdapterDB.MyViewHolder> {
private List<ModelDB> modelDBList;
public AdapterDB(List<ModelDB> modelDBList) {
this.modelDBList = modelDBList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_data,parent,false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
ModelDB modelDB = modelDBList.get(position);
holder.tv_nama.setText(modelDB.getNama());
holder.tv_alamat.setText(modelDB.getAlamat());
}
#Override
public int getItemCount() {
return modelDBList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView tv_nama, tv_alamat;
public MyViewHolder(View itemView) {
super(itemView);
tv_nama = (TextView) itemView.findViewById(R.id.tv_nama);
tv_alamat = (TextView) itemView.findViewById(R.id.tv_alamat);
}
}
}
You need to kind of let the adapter know that the data has changed and that the UI has to be refreshed or whatever. The OnDataChange in your code should be like this (check the last line within the method) -
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//loop data all user
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
//instance object to get and set data
ModelDB modelDB = postSnapshot.getValue(ModelDB.class);
//adding data list from object
dbList.add(modelDB);
adapter.notifyDataSetChanged();
}
}
This should do the trick assuming there are no other bugs in some other parts of your code