I am making a time sheet program where a user inputs his in- and out-punches. I have a ListView that I am populating from an array of calendar objects. I would like each row to show the day and date then on a new line the time, but I only want to display the day and date if it is different from the previous element.
Currently, I am setting visibility in the BaseAdapter based on comparisons using position vs position-1 (which are used as indices to the array). This only works if the whole list fits on the screen. If it extends beyond the screen and the user scrolls around the results are unpredictable.
To further confuse things, I am setting the color of the times, based on the position, to alternate between green and red (in/out) and it works as expected, scrolling or not.
How does Android handle the ListView position when scrolling or what could I do differently to show/hide the day and date?
public class TimeSheetActivity extends Activity {
SQLiteDatabase timesDatabase;
Cursor punchCursor;
private static Calendar[] allPunches;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.timesheet);
} //end onCreate()
@Override
public void onResume() {
super.onResume();
//Open database
timesDatabase = openOrCreateDatabase(
"times_database.db",
SQLiteDatabase.CREATE_IF_NECESSARY,
null);
timesDatabase.setLocale(Locale.getDefault());
timesDatabase.setLockingEnabled(true);
timesDatabase.setVersion(1);
punchCursor = timesDatabase.query("Timepunches", null, null, null, null, null, "punch ASC;");
updateTimeSheet();
} //end onResume()
@Override
public void onPause() {
super.onPause();
timesDatabase.close();
} //end onResume()
private static class EfficientAdapter extends BaseAdapter {
private LayoutInflater mInflater;
public EfficientAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
public int getCount() {
return allPunches.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.time_list_row, null);
holder = new ViewHolder();
holder.text1 = (TextView) convertView.findViewById(R.id.day_textview);
holder.text2 = (TextView) convertView.findViewById(R.id.date_textview);
holder.text3 = (TextView) convertView.findViewById(R.id.times_this_day_textview);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
String dayNames[] = new DateFormatSymbols().getWeekdays();
//Initialize first list element
if (position < 1) {
holder.text1.setText(dayNames[allPunches[position].get(Calendar.DAY_OF_WEEK)]);
holder.text2.setText(formatDate(allPunches[position]));
}
else {
holder.text1.setText(dayNames[allPunches[position].get(Calendar.DAY_OF_WEEK)]);
holder.text2.setText(formatDate(allPunches[position]));
holder.text1.setVisibility(View.VISIBLE);
holder.text2.setVisibility(View.VISIBLE);
//Hide day and date if same as last
if (formatDate(allPunches[position]).contentEquals(formatDate(allPunches[position-1]))) {
holder.text1.setVisibility(View.GONE);
holder.text2.setVisibility(View.GONE);
}
}
holder.text3.setText(formatTime(allPunches[position], true) + " " + position);
//Color in/out punches
if (position%2 == 0) {
holder.text3.setTextColor(Color.GREEN);
}
else {
holder.text3.setTextColor(Color.RED);
}
return convertView;
} //end getView()
static class ViewHolder {
public TextView text1;
TextView text2;
TextView text3;
}
} //end EfficientAdapter
public void updateTimeSheet() {
punchCursor = timesDatabase.query("Timepunches", null, null, null, null, null, "punch ASC;");
allPunches = new Calendar[punchCursor.getCount()];
int i = 0; //for indexing allPunches
Calendar nextDay = Calendar.getInstance();
nextDay.setLenient(true);
//populate allPunches
for (punchCursor.moveToFirst(); !punchCursor.isAfterLast(); punchCursor.moveToNext()) {
allPunches[i] = Calendar.getInstance();
allPunches[i].setTimeInMillis(punchCursor.getLong(0));
++i;
} //end for
final ListView timeSheetListView = (ListView)findViewById(R.id.timesheet_listview);
timeSheetListView.setAdapter(new EfficientAdapter(this));
timeSheetListView.setOnItemClickListener(new OnItemClickListener() {...}); //end click listener for list item
} //end updateTimeSheet()
public static String formatTime(Calendar thisTime, boolean showAMPM) {...}
public static String formatDate(Calendar thisDate) {
String formattedDate = "";
formattedDate += thisDate.get(Calendar.MONTH) +"-"+ thisDate.get(Calendar.DAY_OF_MONTH) +"-"+ thisDate.get(Calendar.YEAR);
return formattedDate;
} //end formatDate()
} //end TimeSheet Activity