So I've an adapter which takes its data from an ArrayList And I'm trying to filter the ArrayList by a few parameters that the user chooses, but the adapter doesn't update, and even makes it look like the ArrayList is empty, Any Suggestion how to fix it?
Code Below:
if (task.isSuccessful())
{
updatelist(task.getResult(), dateStr, time);
zoneAdapter.notifyDataSetChanged();
}
(Thats inside a OnCompleteListener)
updatelist:
zones.clear();
int count = 0;
for (QueryDocumentSnapshot document : result) {
zoneid = document.get(AssignmentFirebase.ZoneId).toString();
dateAssignment = document.get(AssignmentFirebase.date).toString();
timeAssignment = document.get(AssignmentFirebase.TimeSlot).toString();
if (timeAssignment.equals(time) && dateAssignment.equals(dateStr))
{
for (int i =0; i< allZones.size(); i++)
{
if (allZones.get(i).getId().equals(zoneid))
allZones.remove(i);
}
zones = (ArrayList) allZones.clone();
}
The adapter is connected to the zones ArrayList
I've used a debugger to check it in detail, seems like it deletes the zones that needs to be deleted so its probably the clone or the adapter itself, i would appreciate any help, Cheers.
Related
I have a list of users, and I want to hide every user with admin role when show it in recycleview. Tried to use for method, but the app ended up crash. here is the code that I tried to use
public void setUserList(List<UserModel> userList) {
this.userList = userList;
//userList.remove(0);
for(int i=0;i<=userList.size();i++)
{
if(userList.get(i).getRole().equals("admin")) {
userList.remove(i);
}
}
//userList.removeIf(userModel -> userModel.getRole().matches("admin"));
notifyDataSetChanged();
}
For now, because the user with role admin always located at first index of array, I use userList.remove(0); but if any of you have better approach, I really apreciate it. Thank you.
Edit:
Get the answer, need to use access iterator directly.
Use Iterator
int position = 0;
Iterator<User> iter = list.iterator();
while (iter.hasNext()) {
if(iter.next().getRole().equals("admin")){
iter.remove()
}
position++
}
and in adapter
adapter.notifyItemRemoved(position)
Normal for loop should be used on collections for read only
You also need to update the Adapter. Use something like this:
for (int i = userList.size() - 1; i <= userList.size(); ++i) {
if(userList.get(i).getRole().equals("admin"))
userList.remove(i);
adapter.notifyItemRemoved(i)
}
if you getting error like this
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at beginner.HelloWorldApp.main(HelloWorldApp.java:18)
Then you can use an iterator to remove element by this way
for(Iterator<Model> iter = userList.iterator(); iter.hasNext(); ){
Model student = iter.next();
if(student.getName().equalsIgnoreCase("admin"){
iter.remove();
}
}
adapter.notifydatasetchange();
I try to send several lists to other activity so I wrote the following code:
ArrayList<String> sections = new ArrayList<String>();
for(int i=1; i<=last; i++)
{
sections.clear();
for(j = 0; j < size; j++)
{
sections.add(someText);
}
ourIntent.putStringArrayListExtra("sections_"+i, sections);
}
As you can see for every loop cycle of i, the name I give to the sent list is different (sections_1, sections_2, ...).
The sections list is cleared in each loop cycle. And in debug mode I can see that in every loop cycle the sections have the right list.
The problem is in the next activity. When I take the list, with the following code:
sections1 = extras.getStringArrayList("sections_1");
sections2 = extras.getStringArrayList("sections_2");
sections1 and sections2 get the same list, which is the last list that was inserted in putStringArrayListExtra.
Anyone can explain this behavior?
I believe this is because it's storing a reference to your ArrayList, and not a copy of the current "state" of the list on each iteration of your loop.
For example, you first insert a reference to your ArrayList when it contains 1 item. Next, you insert a reference to your ArrayList when it contains 2 items. Both are just references, so when you actually transition to the next Activity, it copies the full ArrayList.
To fix this, you could actually make a local copy of the ArrayList each time you loop.
ArrayList<String> sections = new ArrayList<String>();
for(int i=1; i<=last; i++) {
sections.clear();
for(j = 0; j < size; j++){
sections.add(someText);
}
// Creating a new local copy of the current list.
ArrayList<String> newList = newArrayList<>(sections);
// Inserting the local copy instead.
ourIntent.putStringArrayListExtra("sections_"+i, newList);
}
I created a listview that connects to a database. I want to show some of the newest items (maybe 10 newest items) that will add in a random time? How can I accomplish this? This what I have tried:
int i = String.valueOf(mKondisiList));
for(i = 0; i<=5 ; i++ ){
mKondisiList = myDbHelper.getListKondisi();
adapterKondisi = new ListKondisiAdapter(this, mKondisiList);
lvKondisi.setAdapter(adapterKondisi);
Collections.reverse(mKondisiList);
}
But this doesn't work.
Sorry but, this code block makes no sense.
int i = String.valueOf(mKondisiList));
for(i = 0; i<=5 ; i++ ){
mKondisiList = myDbHelper.getListKondisi();
adapterKondisi = new ListKondisiAdapter(this, mKondisiList);
lvKondisi.setAdapter(adapterKondisi);
Collections.reverse(mKondisiList);
}
To explain what you have did;
you are getting the list from your database
initializing the list adapter
setting adapter to list
then reverse your order of the list (but you are not notifying the adapter)
You are doing this in a loop exactly 5 times.
What you need to do is:
get your list from database
then reverse your order of the list
initialize the list adapter
set adapter to list
I should look like this:
mKondisiList = myDbHelper.getListKondisi();
Collections.reverse(mKondisiList);
adapterKondisi = new ListKondisiAdapter(this, mKondisiList);
lvKondisi.setAdapter(adapterKondisi);
If you want to show only limited number of items, you can do something like below:
ArrayList<Object> fullList = new ArrayList<>();
fullList = myDbHelper.getListKondisi();
Collections.reverse(fullList);
//Add first 10 item to your mKondisiList
for (int i = 0; i < 10; i++) {
mKondisiList.add(fullList.get(i));
}
adapterKondisi = new ListKondisiAdapter(this, mKondisiList);
lvKondisi.setAdapter(adapterKondisi);
I created a loop that will get the data from my cursor, however I noticed that even though it is looping(with the correct count) it only shows the first value.
int vv = 0;
if ((CR3.moveToFirst()) || CR3.getCount() !=0){
while (CR3.isAfterLast() == false) {
vendoName[vv] = CR3.getString(0);
vendoEsch[vv] = CR3.getString(1);
vendoAsch[vv] = CR3.getString(2);
vendoTag[vv] = CR3.getString(3);
vv++;
CR3.moveToNext();
}}
and when I call all my data( I only need the first three records)
ArrayList<SearchResults2> results2 = new ArrayList<SearchResults2>();
SearchResults2 sr2 = new SearchResults2();
for(int j = 0;j < 3;j++)
{
sr2.setName(vendoName[j]);
sr2.setEsch(vendoEsch[j]);
sr2.setAsch(vendoAsch[j]);
sr2.setTag(vendoTag[j]);
results2.add(sr2);
}
I am putting inside a listview, when I check, it is showing always the first data.
This is an example I used as a reference to my code(It's almost the same except that I used an array to put my data from)
http://geekswithblogs.net/bosuch/archive/2011/01/31/android---create-a-custom-multi-line-listview-bound-to-an.aspx
Am I doing something wrong which is why it is only getting the first piece of data?
Is it not easier to do something like this (if you don't need more than 3 results):
ArrayList<SearchResults2> results2 = new ArrayList<SearchResults2>();
CR3.moveToFirst();
for (i = 0; i < 3; i++) {
SearchResults2 sr2 = new SearchResults2();
sr2.setName(CR3.getString(0));
sr2.setEsch(CR3.getString(1));
sr2.setAsch(CR3.getString(2));
sr2.setTag(CR3.getString(3));
results2.add(sr2);
CR3.moveToNext();
}
I think that maybe the cursor doesn't iterate properly through your results in your while-loop and that's why you become one and the same result for the three items
I am trying to display the Android ListView as shown below using multiple ArrayList<PatientAppointmentList> and ArrayList<TimeSlot>. But am unable to achieve this structure. ArrayList<PatientAppointmentList> is been populated from database and Array<TimeSlot> is locally created ArrayList. How I can match the time in ArrayList<PatientAppointmentList> and time in ArrayList<TimeSlots> is the issue.
Please refer the image below for more details and help me.
By the way, the text Available is not from database. If there is no appointment for the particular slot, I want to display the slot as available programatically.
Thanks in Advance.
Use ArrayList HashMap to combine both list data.
ArrayList<HashMap<String,Object>> list = new ArrayList<HashMap<String, Object>>();
TimeSlot[] timeSlotList;
for (int i=0;i<timeSlotList.length;i++){
HashMap<String,Object> row = new HashMap<String, Object>();
row.put("slot_time",timeSlotList[i]);
// try to get data from your database base on TimeSlot and check if data is not available for this time slot put available static string other wise add data which are came from database.
ArrayList<PatientAppointmentList> appointmentList = getAppointmentFromDatabase(timeSlotList.get(i));
if(appointmentList != null && appointmentList.size() > 0){
row.put("appointment_status",getAppointmentFromDatabase(timeSlotList.get(i)));
}else{
row.put("appointment_status","Available");
}
list.add(row);
}
Try using Object ArrayList Appointment that contains ArrayList PatientAppointmentList and ArrayList TimeSlot
Appointment structure:
public class Appointment {
TimeSlot timeSlot;
PatientAppointmentList patientAppointmentList;
public Appointment(TimeSlot timeslot, AppointmentList appointmentList) {
this.timeSlot = timeSlot;
this.appointmentList = appointmentList;
}
}
Add timeslots for eachPatientAppointmentList:
ArrayList<Appointment> appointments = new ArrayList<>();
for (int i = 0; i < patientAppointmentList.size(); i++) {
appointments.add(new Appointment(new TimeSlot, new PatientAppointmentList));
}