ListView元素的动态显示部分工作

时间:2010-07-26 20:21:28

标签: java android listview

我正在制作一个时间表程序,用户输入他的输入和输出。我有一个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()

} //结束时间表活动

2 个答案:

答案 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