我正在制作一个时间表程序,用户输入他的输入和输出。我有一个ListView,我从一组日历对象填充。我希望每一行显示日期和日期然后在新行上显示时间,但我只想显示日期和日期,如果它与前一个元素不同。
目前,我正在使用position vs position-1(用作数组的索引)进行比较,在BaseAdapter中设置可见性。这仅在整个列表适合屏幕时才有效。如果它超出屏幕范围并且用户滚动,则结果是不可预测的。
为了进一步混淆事物,我根据位置设置时间的颜色,在绿色和红色之间交替(输入/输出),它按预期工作,滚动或不滚动。
Android在滚动时如何处理ListView位置,或者我可以采用哪些方式来显示/隐藏日期和日期?
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()
} //结束时间表活动
答案 0 :(得分:0)
滚动时会重复使用ListView中的视图。这可能会导致您看到的奇怪行为。重写getView时要记住的重要事项是每次都明确设置行为。不要依赖于处于默认状态的视图,因为您可能正在重用已经更改的视图。
在您的特定情况下,请确保始终将visiblity明确设置为true或已消失。
另外,您是否直接复制粘贴此代码?我相信你错过了第二个其他声明的结束括号。
答案 1 :(得分:0)
我似乎在错误的地方设置了VISIBLE。这是getView()的代码,似乎已经修复了它!
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();
holder.text1.setVisibility(View.VISIBLE);
holder.text2.setVisibility(View.VISIBLE);
//Initialize list
if (position < 1) {
holder.text1.setText(dayNames[allPunches[position].get(Calendar.DAY_OF_WEEK)]);
holder.text2.setText(formatDate(allPunches[position]));
}
else {
//Show day and date if not same as last
holder.text1.setText(dayNames[allPunches[position].get(Calendar.DAY_OF_WEEK)]);
holder.text2.setText(formatDate(allPunches[position]));
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));
//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