javaandroiddatetimeandroid-recyclerviewandroid-button

How do I get the current time to populate in the RecyclerView when I press the clockInOut button?


Ive been teaching myself how to code for the last 2 months and decided I would attempt to make a time keeping app. Ive checked everywhere in this code, I ran Logs, I even asked chatGPT, and for the life of me I cannot figure out why these times will not populate the RecyclerViews.

I do not have enough space to paste the .xml file but can put it somewhere else if necessary or I can see if I can get away with just the relevant parts.

Here are the relevant files:

TimeClockActivity.java

public class TimeClockActivity extends AppCompatActivity {

    //declare Home Page Activity member variables (7txt_views, 3btn, 2edit_txt)

    private Button toTimeEntryItemButton;
    private Button backHomeButton;
    private TextView timeClockTitleTextView;
    private TextView hoursWorkedTodayTextView;
    private TextView totalHoursWorkedTodayTextView;
    private TextView hoursWorkedThisWeekTextView;
    private TextView totalHoursWorkedWeekTextView;
    private TextView projectedPayTextView;
    private TextView totalProjectedPayTextView;
    private TextView dateTimeDisplay;
    private Calendar calendar;
    private SimpleDateFormat dateFormat;
    private SimpleDateFormat timeFormat;
    private String date;
    private Button clockInButton;
    private Button clockInAtButton;
    private TextView[] clockedInTextViews;
    private TextView[] clockedOutTextViews;
    private Switch[] lunchSwitches;
    private boolean isClockIn = false;
    private Map<String, TimeEntry> dayToTimeEntry = new HashMap<>();
    private RecyclerView[] recyclerViews;
    //    private TimeEntryAdapter[] adapters;
    private TimeEntryAdapter clockedInAdapter;
    private TimeEntryAdapter clockedOutAdapter;

    List<TimeEntry> mondayTimeEntries = new ArrayList<>();
    List<TimeEntry> tuesdayTimeEntries = new ArrayList<>();
    List<TimeEntry> wednesdayTimeEntries = new ArrayList<>();
    List<TimeEntry> thursdayTimeEntries = new ArrayList<>();
    List<TimeEntry> fridayTimeEntries = new ArrayList<>();
    List<TimeEntry> saturdayTimeEntries = new ArrayList<>();
    List<TimeEntry> sundayTimeEntries = new ArrayList<>();




    //    @SuppressLint("MissingInflatedId")
    @SuppressLint("MissingInflatedId")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_time_clock);


        initializeViews();
        initializeDateAndTime();
        initializeRecyclerViews();
        setClickListeners();

        // Initialize adapters for each day of the week
        TimeEntryAdapter mondayAdapter = new TimeEntryAdapter(mondayTimeEntries, "Monday");
        TimeEntryAdapter tuesdayAdapter = new TimeEntryAdapter(tuesdayTimeEntries, "Tuesday");
        TimeEntryAdapter wednesdayAdapter = new TimeEntryAdapter(wednesdayTimeEntries, "Wednesday");
        TimeEntryAdapter thursdayAdapter = new TimeEntryAdapter(thursdayTimeEntries, "Thursday");
        TimeEntryAdapter fridayAdapter = new TimeEntryAdapter(fridayTimeEntries, "Friday");
        TimeEntryAdapter saturdayAdapter = new TimeEntryAdapter(saturdayTimeEntries, "Saturday");
        TimeEntryAdapter sundayAdapter = new TimeEntryAdapter(sundayTimeEntries, "Sunday");

        // Set the adapters on their respective RecyclerViews
        RecyclerView recyclerMondayClockedIn = findViewById(R.id.recycler_monday_clocked_in);
        RecyclerView recyclerTuesdayClockedIn = findViewById(R.id.recycler_tuesday_clocked_in);
        RecyclerView recyclerWednesdayClockedIn = findViewById(R.id.recycler_wednesday_clocked_in);
        RecyclerView recyclerThursdayClockedIn = findViewById(R.id.recycler_thursday_clocked_in);
        RecyclerView recyclerFridayClockedIn = findViewById(R.id.recycler_friday_clocked_in);
        RecyclerView recyclerSaturdayClockedIn = findViewById(R.id.recycler_saturday_clocked_in);
        RecyclerView recyclerSundayClockedIn = findViewById(R.id.recycler_sunday_clocked_in);

        recyclerMondayClockedIn.setLayoutManager(new LinearLayoutManager(this));
        recyclerTuesdayClockedIn.setLayoutManager(new LinearLayoutManager(this));
        recyclerWednesdayClockedIn.setLayoutManager(new LinearLayoutManager(this));
        recyclerThursdayClockedIn.setLayoutManager(new LinearLayoutManager(this));
        recyclerFridayClockedIn.setLayoutManager(new LinearLayoutManager(this));
        recyclerSaturdayClockedIn.setLayoutManager(new LinearLayoutManager(this));
        recyclerSundayClockedIn.setLayoutManager(new LinearLayoutManager(this));

        recyclerMondayClockedIn.setAdapter(mondayAdapter);
        recyclerTuesdayClockedIn.setAdapter(tuesdayAdapter);
        recyclerWednesdayClockedIn.setAdapter(wednesdayAdapter);
        recyclerThursdayClockedIn.setAdapter(thursdayAdapter);
        recyclerFridayClockedIn.setAdapter(fridayAdapter);
        recyclerSaturdayClockedIn.setAdapter(saturdayAdapter);
        recyclerSundayClockedIn.setAdapter(sundayAdapter);

        Log.d("TimeClockActivity", "Sunday Time Entries count: " + sundayTimeEntries.size());
    }



    // apply basic page instances
    private void initializeViews() {

        toTimeEntryItemButton = findViewById(R.id.btn_to_time_entry_item);
        backHomeButton = findViewById(R.id.btn_to_home);
        hoursWorkedTodayTextView = findViewById(R.id.tv_hours_worked_today_text);
        totalHoursWorkedTodayTextView = findViewById(R.id.tv_hours_worked_today);
        hoursWorkedThisWeekTextView = findViewById(R.id.tv_hours_worked_this_week_text);
        totalHoursWorkedWeekTextView = findViewById(R.id.tv_hours_worked_this_week);
        projectedPayTextView = findViewById(R.id.tv_projected_paycheck_text);
        totalProjectedPayTextView = findViewById(R.id.tv_projected_paycheck);
        dateTimeDisplay = findViewById(R.id.tv_date_and_time);
        clockInButton = findViewById(R.id.btn_clock_in);
        clockInAtButton = findViewById(R.id.btn_clock_in_at);
        timeClockTitleTextView = findViewById(R.id.tv_time_clock_title);
        lunchSwitches = new Switch[]{
                findViewById(R.id.switch_monday_lunch),
                findViewById(R.id.switch_tuesday_lunch),
                findViewById(R.id.switch_wednesday_lunch),
                findViewById(R.id.switch_thursday_lunch),
                findViewById(R.id.switch_friday_lunch),
                findViewById(R.id.switch_saturday_lunch),
                findViewById(R.id.switch_sunday_lunch)
        };
    }

    private void initializeDateAndTime() {
        //apply the instances created for calendar and time
        calendar = Calendar.getInstance();
        dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm aa");
        timeFormat = new SimpleDateFormat("HH:mm - E");
        updateDateTimeDisplay();
    }
    private void updateDateTimeDisplay() {
//        date = dateFormat.format(calendar.getTime());
        String date = timeFormat.format(new Date());
        dateTimeDisplay.setText(date);
    }
    private void initializeRecyclerViews() {
        RecyclerView[] clockedInRecyclerViews = new RecyclerView[]{
                findViewById(R.id.recycler_monday_clocked_in),
                findViewById(R.id.recycler_tuesday_clocked_in),
                findViewById(R.id.recycler_wednesday_clocked_in),
                findViewById(R.id.recycler_thursday_clocked_in),
                findViewById(R.id.recycler_friday_clocked_in),
                findViewById(R.id.recycler_saturday_clocked_in),
                findViewById(R.id.recycler_sunday_clocked_in)
        };

        LinearLayoutManager[] layoutManagerArrayClockedIn = new LinearLayoutManager[]{
                new LinearLayoutManager(this),
                new LinearLayoutManager(this),
                new LinearLayoutManager(this),
                new LinearLayoutManager(this),
                new LinearLayoutManager(this),
                new LinearLayoutManager(this),
                new LinearLayoutManager(this)
        };

        for (int i = 0; i < clockedInRecyclerViews.length; i++) {
            clockedInRecyclerViews[i].setLayoutManager(layoutManagerArrayClockedIn[i]);
        }

        RecyclerView[] clockedOutRecyclerViews = new RecyclerView[]{
                findViewById(R.id.recycler_monday_clocked_out),
                findViewById(R.id.recycler_tuesday_clocked_out),
                findViewById(R.id.recycler_wednesday_clocked_out),
                findViewById(R.id.recycler_thursday_clocked_out),
                findViewById(R.id.recycler_friday_clocked_out),
                findViewById(R.id.recycler_saturday_clocked_out),
                findViewById(R.id.recycler_sunday_clocked_out)
        };

        LinearLayoutManager[] layoutManagerArrayClockedOut = new LinearLayoutManager[]{
                new LinearLayoutManager(this),
                new LinearLayoutManager(this),
                new LinearLayoutManager(this),
                new LinearLayoutManager(this),
                new LinearLayoutManager(this),
                new LinearLayoutManager(this),
                new LinearLayoutManager(this)
        };

        for (int i = 0; i < clockedOutRecyclerViews.length; i++) {
            clockedOutRecyclerViews[i].setLayoutManager(layoutManagerArrayClockedOut[i]);
        }

        clockedInAdapter = new TimeEntryAdapter(new ArrayList<>(), "clockedIn");
        clockedOutAdapter = new TimeEntryAdapter(new ArrayList<>(), "clockedOut");

        for (int i = 0; i < clockedInRecyclerViews.length; i++) {
            clockedInRecyclerViews[i].setLayoutManager(new LinearLayoutManager(this));
            clockedInRecyclerViews[i].setAdapter(clockedInAdapter);
        }

        for (int i = 0; i < clockedOutRecyclerViews.length; i++) {
            clockedOutRecyclerViews[i].setLayoutManager(new LinearLayoutManager(this));
            clockedOutRecyclerViews[i].setAdapter(clockedOutAdapter);
        }
    }

    private void setClickListeners() {

//      set button click ability for the 'back home' button
        backHomeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackHomeClick(v);
            }
        });
//      set button click ability for the 'clock in' button
        clockInButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onClockInButtonClick(v);
            }
        });
//        set button click ability for the 'to time entry item' button
        toTimeEntryItemButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onToTimeEntryItemButtonClick(v);
            }
        });

    }

    private void onToTimeEntryItemButtonClick(View view) {
        Intent intent = new Intent(this, TimeEntry.class);
        startActivity(intent);
    }


    //  give the 'back home' button some functionality
    private void onBackHomeClick(View v) {
        Intent intent = new Intent(this, HomePageActivity.class);
        startActivity(intent);
    }

    // give the clock in button some functionality
    public void onClockInButtonClick(View view) {
        // Determine the current day

        int dayOfTheWeek = calendar.get(Calendar.DAY_OF_WEEK);
        String day = getDayName(dayOfTheWeek);

        Log.d("Time ClockActivity", "Clicked on day: " + day);

        // Get or create a TimeEntry for the current day
        TimeEntry timeEntry = dayToTimeEntry.get(day);
        if (timeEntry == null) {
            timeEntry = new TimeEntry(day);
            dayToTimeEntry.put(day, timeEntry);
            Log.d("TimeClockActivity", "Created new TimeEntry for day: " + day);
        }

        // Add clock-in or clock-out time
        String currentTime = timeFormat.format(new Date());
        Log.d("TimeClockActivity", "Current time: " + currentTime);
        if (isClockIn) {
            timeEntry.addClockInTime(currentTime);
        } else {
            timeEntry.addClockOutTime(currentTime);
        }
        
        clockedInAdapter.setTimeEntries(getClockedInTimeEntries());
        clockedOutAdapter.setTimeEntries(getClockedOutTimeEntries());
        clockedInAdapter.notifyDataSetChanged();
        clockedOutAdapter.notifyDataSetChanged();
        // After updating the data
        Log.d("TimeClockActivity", "Clocked in time entries: " + getClockedInTimeEntries().size());
        Log.d("TimeClockActivity", "Clocked out time entries: " + getClockedOutTimeEntries().size());


        toggleClockInOutButtonText();
        isClockIn = !isClockIn;
    }

    private List<TimeEntry> getClockedInTimeEntries() {
        List<TimeEntry> clockedInTimeEntries = new ArrayList<>();
        for (TimeEntry timeEntry : dayToTimeEntry.values()) {
            if (timeEntry.hasClockInTime() && !timeEntry.hasClockOutTime()) {
                clockedInTimeEntries.add(timeEntry);
            }
        }
        return clockedInTimeEntries;
    }

    private List<TimeEntry> getClockedOutTimeEntries() {
        List<TimeEntry> clockedOutTimeEntries = new ArrayList<>();
        for (TimeEntry timeEntry : dayToTimeEntry.values()) {
            if (timeEntry.hasClockOutTime()) {
                clockedOutTimeEntries.add(timeEntry);
            }
        }
        return clockedOutTimeEntries;
    }

    private void toggleClockInOutButtonText() {
        if (isClockIn) {
            clockInButton.setText("Clock In");

        } else {
            clockInButton.setText("Clock Out");

        }
    }

    private String getDayName(int dayOfTheWeek) {
        String day;
        switch (dayOfTheWeek) {
            case Calendar.SUNDAY:
                day = "Sunday";
                break;
            case Calendar.MONDAY:
                day = "Monday";
                break;
            case Calendar.TUESDAY:
                day = "Tuesday";
                break;
            case Calendar.WEDNESDAY:
                day = "Wednesday";
                break;
            case Calendar.THURSDAY:
                day = "Thursday";
                break;
            case Calendar.FRIDAY:
                day = "Friday";
                break;
            case Calendar.SATURDAY:
                day = "Saturday";
                break;
            default:
                day = "Unknown";
                break;
        }
        return day;
    }

TimeEntry.java

public TimeEntry() {

    }
    public TimeEntry(String day) {
        this.day = day;
        this.clockInTime = null;
        this.clockOutTime = null;
        this.clockInTimes = new ArrayList<>();
        this.clockOutTimes = new ArrayList<>();
        setDayOfWeek();
    }

    public void setDayOfWeek() {
        SimpleDateFormat inputFormat = new SimpleDateFormat("EEEE", Locale.getDefault());
        SimpleDateFormat outputFormat = new SimpleDateFormat("EEEE", Locale.getDefault());
        try {
            Date date = inputFormat.parse(day);
            dayOfWeek = outputFormat.format(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }


    public String getClockInTime() {
        return clockInTime;
    }

    public void setClockInTime(String clockInTime) {
        this.clockInTime = clockInTime;
    }

    public String getClockOutTime() {
        return clockOutTime;
    }

    public void setClockOutTime(String clockOutTime) {
        this.clockOutTime = clockOutTime;
    }

    public boolean hasClockInTime() {
        return clockInTime != null;
    }

    public boolean hasClockOutTime() {
        return clockOutTime != null;
    }

    public List<String> getClockInTimes() {
        return clockInTimes;
    }

    public List<String> getClockOutTimes() {
        return clockOutTimes;
    }

    public String getDayOfWeek() {
        return dayOfWeek;
    }

    public void addClockInTime(String clockInTime) {
        Log.d("TimeEntry", "Added clock-in time: " + clockInTime);
        clockInTimes.add(clockInTime);
    }

    public void addClockOutTime(String clockOutTime) {
        Log.d("TimeEntry", "Added clock-out time: " + clockOutTime);
        clockOutTimes.add(clockOutTime);
    }

    public void setDayOfWeek(String dayOfWeek) {
        this.dayOfWeek = dayOfWeek;
    }
}

TimeEntryAdapter.java

public class TimeEntryAdapter extends RecyclerView.Adapter<TimeEntryAdapter.TimeEntryViewHolder> {
    private List<TimeEntry> timeEntries;
    private String entryType;

    // Constructor for the adapter
    public TimeEntryAdapter(List<TimeEntry> timeEntries, String entryType) {
        this.timeEntries = timeEntries;
        this.entryType = entryType;
    }
    @NonNull
    @Override
    public TimeEntryViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.time_entry_item, parent, false);
        return new TimeEntryViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull TimeEntryViewHolder holder, int position) {
        TimeEntry timeEntry = timeEntries.get(position);

        // Get references to the views within the item layout
        TextView dayOfWeekTextView = holder.dayOfWeekTextView;
        TextView clockedInTimeTextView = holder.clockedInTimeTextView;
        TextView clockedOutTimeTextView = holder.clockedOutTimeTextView;

        // Set data for the views based on the TimeEntry
        dayOfWeekTextView.setText(timeEntry.getDayOfWeek()); // Set the day dynamically
        clockedInTimeTextView.setText("Clock In: " + timeEntry.getClockInTime()); // Set clock-in time dynamically
        clockedOutTimeTextView.setText("Clock Out: " + timeEntry.getClockOutTime()); // Set clock-out time dynamically
    }

    @Override
    public int getItemCount() {
        return timeEntries.size();
    }

    public static class TimeEntryViewHolder extends RecyclerView.ViewHolder {
        TextView dayOfWeekTextView;
        TextView clockedInTimeTextView;
        TextView clockedOutTimeTextView;

        public TimeEntryViewHolder(View itemView) {
            super(itemView);
            dayOfWeekTextView = itemView.findViewById(R.id.dayOfWeekTextView);
            clockedInTimeTextView = itemView.findViewById(R.id.clockedInTimeTextView);
            clockedOutTimeTextView = itemView.findViewById(R.id.clockedOutTimeTextView);
        }
    }
    public void setTimeEntries(List<TimeEntry> timeEntries) {
        this.timeEntries = timeEntries;
        notifyDataSetChanged();
    }
    public void addEntry(TimeEntry entry) {
        timeEntries.add(entry);
        notifyDataSetChanged();
    }

I simply want to press the Clock In / Clock Out button and have it populate the correct Recyler View for the correct day and whether or not it is a clock in time or a clock out time. I had it working just fine for TextViews, then decided "well what if someone clocks in and out twice in the same day". And now I am talking crap to my computer. Thanks in advance, let me know if more information is needed.


Solution

  • You never update the internal array list within the adapters -> private List<TimeEntry> timeEntries;

    Add function like this to the adapter.

    public void addEntry(TimeEntry entry) {
        timeEntries.add(entry);
        //This is a bad solution, but for your code structure and experience it will do.
        notifyDataSetChanged(); 
    }
    

    That array list is what the recycler is showing if you never add to it, it never changes.

    With that you have another problem if you are separating the views by day of the week, you need an adapter per recycler you can't reuse the same one, because it contains the list of what it is showing. If what it needs to show is different per recyclerView they can't be the same adapter.

    i.e. You can't do this

            for (int i = 0; i < clockedInRecyclerViews.length; i++) {
                clockedInRecyclerViews[i].setLayoutManager(new LinearLayoutManager(this));
                clockedInRecyclerViews[i].setAdapter(clockedInAdapter); //<-- Bad
            }