I'm building a small application using Firebase Real Time Database.
The app lists shifts per given date.
Each shift is displayed as a group item and every employee that is registered to this shift is displayed as a child in that group.
I used an ArrayList of ParentHeader class for the group-items and an ArrayList of Strings for the children-items (to list the employee's name) - This may change in the future for a more complex object.
This is my code:
The ParentHeader class which stores data on each group-item.
and finally the Shift class which stores data for every shift.
First Problem
Removing a group item from an ExpandableListAdapter on button click on the parent-item.
As you can see above I'm calling parents.remove and then notifyDataSetChanged in my getGroupView method, but the list does not get refreshed.
It does however work if I reload the activity or by moving to another activity and then back to this one.
I wish for it to work dynamically.
Second Problem
Adding a child to a group on button click of the parent-item.
My database is structured as follows:
When a new shift has been added to a date by the Admin.
Now I wish for every User to be able to assign themselves to one of the shifts and for their name to be displayed as a child-item for that group-item shift.
After they click their chosen group-item shift, their data should be stored in Firebase like so:
I wish for every name stored under employees to be displayed as a child-item under its corresponding group-item shift. Dynamically of course.
I'd appreciate help in solving these two problems. I'm new to Android developement and do not have much experience with it.
Thank you.
The app lists shifts per given date.
Each shift is displayed as a group item and every employee that is registered to this shift is displayed as a child in that group.
I used an ArrayList of ParentHeader class for the group-items and an ArrayList of Strings for the children-items (to list the employee's name) - This may change in the future for a more complex object.
This is my code:
Code:
public class DateActivity extends ExpandableListActivity {
// date, isAdmin and name are passed to this activity using shared preferences
private String date, name;
private boolean isAdmin;
// Adapter declaration
private CustomExpandableListAdapter mAdapter;
// ArrayList to store group items
private ArrayList<ParentHeader> parents = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_date);
// initialize date, isAdmin, name here
// Fetch all shifts for selected date from Firebase
Validator.fetchShiftsPerDayFromDB(date, new Callback()
{
@Override
void shiftsCallback(ArrayList<Shift> shifts)
{
super.shiftsCallback(shifts);
if (shifts == null)
return;
for(Shift shift : shifts){
parents.add(new ParentHeader(shift));
}
mAdapter = new CustomExpandableListAdapter();
setListAdapter(mAdapter);
}
});
}
private class CustomExpandableListAdapter extends BaseExpandableListAdapter
{
private LayoutInflater inflater;
public CustomExpandableListAdapter()
{
// Create Layout Inflator
inflater = LayoutInflater.from(DateActivity.this);
}
@Override
public int getGroupCount()
{
return parents.size();
}
@Override
public int getChildrenCount(int groupPosition)
{
int size = 0;
if(parents.get(groupPosition).getEmployeesList() != null)
size = parents.get(groupPosition).getEmployeesList().size();
return size;
}
@Override
public Object getGroup(int groupPosition)
{
return parents.get(groupPosition);
}
@Override
public Object getChild(int groupPosition, int childPosition)
{
return parents.get(groupPosition).getEmployeesList().get(childPosition);
}
@Override
public long getGroupId(int groupPosition)
{
return groupPosition;
}
@Override
public long getChildId(int groupPosition, int childPosition)
{
return childPosition;
}
@Override
public boolean hasStableIds()
{
return true;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parentView)
{
final ParentHeader parentHeader = parents.get(groupPosition);
// Inflate group_row.xml file for group rows
convertView = inflater.inflate(R.layout.group_row, parentView, false);
// Get group_row.xml file elements and set values here
//Add User to selected shift
convertView.findViewById(R.id.add).setOnClickListener(v -> {
//TODO insert constraints
Validator.addUserToShiftInDB(parentHeader.getShift().getKey(), date, name, new Callback() {
@Override
void onUserAssignedToShiftCallback() {
super.onUserAssignedToShiftCallback();
// TODO attach as child-item to chosen group-item
}
});
});
convertView.findViewById(R.id.delete).setOnClickListener(v -> {
if(isAdmin){
//TODO open confirmation window
Validator.deleteShiftFromDateInDB(parentHeader.getShift().getKey(), date, new Callback() {
@Override
void onDeletedShiftCallback() {
super.onDeletedShiftCallback();
// shift gets deleted in Firebase but the expandable list does not refresh
parents.remove(groupPosition);
mAdapter.notifyDataSetChanged();
}
});
}
else{
Toast.makeText(getApplicationContext(),"Admin privileges required", Toast.LENGTH_SHORT).show();
}
});
return convertView;
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parentView)
{
final ParentHeader parentHeader = parents.get(groupPosition);
final String childString = parentHeader.getEmployeesList().get(childPosition);
// Inflate child_row.xml file for child rows
convertView = inflater.inflate(R.layout.child_row, parentView, false);
// Get child_row.xml file elements and set values here
return convertView;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition)
{
return true;
}
@Override
public boolean areAllItemsEnabled()
{
return true;
}
@Override
public boolean isEmpty()
{
return ((parents == null) || parents.isEmpty());
}
@Override
public void notifyDataSetChanged()
{
// Refresh List rows
super.notifyDataSetChanged();
}
}
}
The ParentHeader class which stores data on each group-item.
Code:
public class ParentHeader {
private Shift shift;
private boolean isDeleteButtonClicked, isAddButtonClicked, isHeaderClicked;
// Array to store child objects
private ArrayList<String> employeesList = new ArrayList<>();
public ParentHeader() { }
public ParentHeader(Shift shift) {
this.shift = shift;
}
// Getters/Setters here
}
and finally the Shift class which stores data for every shift.
Code:
public class Shift {
private String startTime, endTime, name, key;
private Integer wage, numOfEmps, employees;
public Shift(){}
public Shift(String name, String startTime, String endTime, Integer wage, Integer numOfEmps, Integer employees) {
this.startTime = startTime;
this.endTime = endTime;
this.name = name;
this.wage = wage;
this.numOfEmps = numOfEmps;
this.employees = employees;
// key field is assigned a value when fetching each shift from firebase using .getKey() method
}
//Getters/Setters here
}
First Problem
Removing a group item from an ExpandableListAdapter on button click on the parent-item.
As you can see above I'm calling parents.remove and then notifyDataSetChanged in my getGroupView method, but the list does not get refreshed.
It does however work if I reload the activity or by moving to another activity and then back to this one.
I wish for it to work dynamically.
Second Problem
Adding a child to a group on button click of the parent-item.
My database is structured as follows:
Code:
"20190528" : {
"-LfvCgavw5bYUJzULE6E" : {
"employees" : 0,
"endTime" : "00:00",
"name" : "test1",
"numOfEmps" : 2,
"startTime" : "00:00",
"wage" : 2
}
}
When a new shift has been added to a date by the Admin.
Now I wish for every User to be able to assign themselves to one of the shifts and for their name to be displayed as a child-item for that group-item shift.
After they click their chosen group-item shift, their data should be stored in Firebase like so:
Code:
"20190528" : {
"-LfvCgavw5bYUJzULE6E" : {
"employees" : {
"generatedKey1" : "John Smith",
"generatedKey2" : "Jane Doe"
},
"endTime" : "00:00",
"name" : "test1",
"numOfEmps" : 2,
"startTime" : "00:00",
"wage" : 2
}
}
I wish for every name stored under employees to be displayed as a child-item under its corresponding group-item shift. Dynamically of course.
I'd appreciate help in solving these two problems. I'm new to Android developement and do not have much experience with it.
Thank you.