过去两个月我一直在自学如何编码,并决定尝试制作一个计时应用程序。我检查了这段代码中的所有地方,我运行了日志,我什至询问了 chatGPT,我一生都无法弄清楚为什么这些时间不会填充 RecyclerViews。
我没有足够的空间来粘贴 .xml 文件,但如果需要,可以将其放在其他地方,或者我可以看看是否可以只使用相关部分。
以下是相关文件:
TimeClockActivity.java
package com.codecademy.workapp3;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Switch;
import android.widget.TextView;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.sql.Time;
import java.util.ArrayList;
import java.util.Calendar;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class TimeClockActivity extends AppCompatActivity {
//declare Home Page Activity member variables (7txt_views, 3btn, 2edit_txt)
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;
// @SuppressLint("MissingInflatedId")
@SuppressLint("MissingInflatedId")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_time_clock);
initializeViews();
initializeDateAndTime();
initializeRecyclerViews();
setClickListeners();
}
// apply basic page instances
private void initializeViews() {
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)
};
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)
};
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);
}
});
}
// 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);
}
// Update the RecyclerView adapters and notify them of the data change
if (isClockIn) {
clockedInAdapter.notifyDataSetChanged();
} else {
clockedOutAdapter.notifyDataSetChanged();
}
if (isClockIn) {
// User is clocking in
timeEntry.addClockInTime(currentTime);
clockInButton.setText("Clock In"); // Change the button text
} else {
// User is clocking out
timeEntry.addClockOutTime(currentTime);
clockInButton.setText("Clock Out"); // Change the button text
}
isClockIn = !isClockIn;
}
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
package com.codecademy.workapp3;
import android.util.Log;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
public class TimeEntry {
private String day;
private String clockInTime;
private String clockOutTime;
private List<String> clockInTimes;
private List<String> clockOutTimes;
private String dayOfWeek;
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
package com.codecademy.workapp3;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
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;
}
@Override
public TimeEntryViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// Inflate your custom item layout here
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.time_entry_item, parent, false);
return new TimeEntryViewHolder(itemView);
}
@Override
public void onBindViewHolder(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 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);
}
}
}
我只想按“上班打卡”/“下班打卡”按钮,并让它填充正确日期的正确 Recyler 视图,以及是否是上班时间或下班时间。我让它在 TextViews 上工作得很好,然后决定“如果有人在同一天打卡上下班两次怎么办”。现在我正在对着电脑说废话。预先感谢,如果需要更多信息,请告诉我。
您永远不会更新适配器内的内部数组列表 ->
private List<TimeEntry> timeEntries;
在适配器中添加这样的功能。
public void addEntry(TimeEntry entry) {
timeEntries.add(entry);
//This is a bad solution, but for your code structure and experience it will do.
notifyDataSetChanged();
}
该数组列表就是回收器显示的内容,如果您从未添加到它,它永远不会改变。
如果您按星期几分隔视图,那么您会遇到另一个问题,每个回收器都需要一个适配器,您不能重复使用相同的适配器,因为它包含所显示内容的列表。如果每个 recyclerView 需要显示的内容不同,则它们不能是相同的适配器。
即你不能这样做
for (int i = 0; i < clockedInRecyclerViews.length; i++) {
clockedInRecyclerViews[i].setLayoutManager(new LinearLayoutManager(this));
clockedInRecyclerViews[i].setAdapter(clockedInAdapter); //<-- Bad
}