Пользовательский ListView с Date как SectionHeader (используемый пользовательский SimpleCursorAdapter)

Я хочу показать ListView с Date как SectionHeader.

Что у меня есть: я показываю ListView из базы данных sqlite, используя пользовательский SimpleCursorAdapter.

Мой пользовательский SimpleCursorAdapter:

public class DomainAdapter extends SimpleCursorAdapter{ private Cursor dataCursor; private LayoutInflater mInflater; public DomainAdapter(Context context, int layout, Cursor dataCursor, String[] from, int[] to) { super(context, layout, dataCursor, from, to); this.dataCursor = dataCursor; mInflater = LayoutInflater.from(context); } public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = mInflater.inflate(R.layout.todo_row, null); holder = new ViewHolder(); holder.text1 = (TextView) convertView.findViewById(R.id.label);//Task Title holder.text2 = (TextView) convertView.findViewById(R.id.label2);//Task Date holder.img = (ImageView) convertView.findViewById(R.id.task_icon); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } dataCursor.moveToPosition(position); int title = dataCursor.getColumnIndex("title"); String task_title = dataCursor.getString(title); int title_date = dataCursor.getColumnIndex("day"); String task_day = dataCursor.getString(title_date); int description_index = dataCursor.getColumnIndex("priority"); int priority = dataCursor.getInt(description_index); holder.text1.setText(task_title); holder.text2.setText(task_day); if(priority==1) holder.img.setImageResource(R.drawable.redbutton); else if(priority==2) holder.img.setImageResource(R.drawable.bluebutton); else if(priority==3)holder.img.setImageResource(R.drawable.greenbutton); else holder.img.setImageResource(R.drawable.redbuttonchecked); return convertView; } static class ViewHolder { TextView text1; TextView text2; ImageView img; } } 

Результаты Google пока:

MergeAdapter

Джефф Шарки

Удивительный ListView

ВОПРОС

Проблема: я хочу отображать listview с Date в качестве заголовков разделов. Значения даты Ofcourse взяты из базы данных sqlite.

Может ли кто-нибудь направить меня, как я могу достичь этой задачи.

Или Предоставьте мне код примера или точный (например) код, относящийся к тому же.

Отредактировано в соответствии с ответом Грэма Боральда (это прекрасно работает, но это было бы быстрым решением).

 public class DomainAdapter extends SimpleCursorAdapter{ private Cursor dataCursor; private LayoutInflater mInflater; public DomainAdapter(Context context, int layout, Cursor dataCursor, String[] from, int[] to) { super(context, layout, dataCursor, from, to); this.dataCursor = dataCursor; mInflater = LayoutInflater.from(context); } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = mInflater.inflate(R.layout.tasks_row, null); holder = new ViewHolder(); holder.text1 = (TextView) convertView.findViewById(R.id.label);//Task Title holder.text2 = (TextView) convertView.findViewById(R.id.label2);//Task Date holder.img = (ImageView) convertView.findViewById(R.id.taskImage); holder.sec_hr=(TextView) convertView.findViewById(R.id.sec_header); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } dataCursor.moveToPosition(position); int title = dataCursor.getColumnIndex("title"); String task_title = dataCursor.getString(title); int title_date = dataCursor.getColumnIndex("due_date"); String task_day = dataCursor.getString(title_date); int description_index = dataCursor.getColumnIndex("priority"); int priority = dataCursor.getInt(description_index); String prevDate = null; if (dataCursor.getPosition() > 0 && dataCursor.moveToPrevious()) { prevDate = dataCursor.getString(title_date); dataCursor.moveToNext(); } if(task_day.equals(prevDate)) { holder.sec_hr.setVisibility(View.GONE); } else { holder.sec_hr.setText(task_day); holder.sec_hr.setVisibility(View.VISIBLE); } holder.text1.setText(task_title); holder.text2.setText(task_day); if(priority==1) holder.img.setImageResource(R.drawable.redbutton); else if(priority==2) holder.img.setImageResource(R.drawable.bluebutton); else if(priority==3)holder.img.setImageResource(R.drawable.greenbutton); else holder.img.setImageResource(R.drawable.redbuttonchecked); return convertView; } static class ViewHolder { TextView text1; TextView text2; TextView sec_hr; ImageView img; } } 

Отредактировано в соответствии с ответом CommonsWare

 public class DomainAdapter extends SimpleCursorAdapter{ private Cursor dataCursor; private TodoDbAdapter adapter; private LayoutInflater mInflater; boolean header; String last_day; public DomainAdapter(Context context, int layout, Cursor dataCursor, String[] from, int[] to) { super(context, layout, dataCursor, from, to); this.dataCursor = dataCursor; mInflater = LayoutInflater.from(context); header=true; adapter=new TodoDbAdapter(context); } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; TitleHolder title_holder = null; if(getItemViewType(position)==1) { //convertView= mInflater.inflate(R.layout.todo_row, parent, false); if (convertView == null) { convertView = mInflater.inflate(R.layout.todo_row, null); holder = new ViewHolder(); holder.text1 = (TextView) convertView.findViewById(R.id.label);//Task Title holder.text2 = (TextView) convertView.findViewById(R.id.label2);//Task Date holder.img = (ImageView) convertView.findViewById(R.id.task_icon); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } dataCursor.moveToPosition(position); int title = dataCursor.getColumnIndex("title"); String task_title = dataCursor.getString(title); int title_date = dataCursor.getColumnIndex("day"); String task_day = dataCursor.getString(title_date); int description_index = dataCursor.getColumnIndex("priority"); int priority = dataCursor.getInt(description_index); holder.text1.setText(task_title); holder.text2.setText(task_day); if(priority==1) holder.img.setImageResource(R.drawable.redbutton); else if(priority==2) holder.img.setImageResource(R.drawable.bluebutton); else if(priority==3)holder.img.setImageResource(R.drawable.greenbutton); else holder.img.setImageResource(R.drawable.redbuttonchecked); } else { if (convertView == null) { convertView = mInflater.inflate(R.layout.section_header, null); title_holder = new TitleHolder(); title_holder.datee = (TextView) convertView.findViewById(R.id.sec_header);//Task Title convertView.setTag(title_holder); } else { title_holder = (TitleHolder) convertView.getTag(); } dataCursor.moveToPosition(position); int title_date = dataCursor.getColumnIndex("day"); String task_day = dataCursor.getString(title_date); title_holder.datee.setText(task_day); } return convertView; } static class ViewHolder { TextView text1; TextView text2; ImageView img; } static class TitleHolder{ TextView datee; } @Override public int getCount() { return dataCursor.getCount()+1; //just for testing i took no. of headers=1 } @Override public int getViewTypeCount() { return 2; } @Override public int getItemViewType(int position) { dataCursor.moveToPosition(position); **Long id=dataCursor.getLong(position);** Cursor date=adapter.fetchTodo(id); int title_date = date.getColumnIndex("day"); String task_day = date.getString(title_date); Log.i("tag",task_day); if(last_day.equals(task_day)) return 1;//Display Actual Row else { last_day=task_day;//Displaying Header return 0; } } /* @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { final View view; if(getItemViewType(cursor.getPosition())==1) view= mInflater.inflate(R.layout.todo_row, parent, false); else view=mInflater.inflate(R.layout.section_header,parent, false); return view; } @Override public void bindView(View convertView, Context context, Cursor cursor) { long id = cursor.getPosition(); }*/ } 

Я получаю исключение Null Pointer в строке: Cursor date=adapter.fetchTodo(id); Кажется, что курсор не получает никаких данных.

Solutions Collecting From Web of "Пользовательский ListView с Date как SectionHeader (используемый пользовательский SimpleCursorAdapter)"

Безусловно, самый простой способ сделать это – включить представление заголовка даты в каждый элемент . Затем все, что вам нужно сделать в bindView – это сравнить дату предыдущей строки с датой этой строки и скрыть дату, если она будет одинаковой. Что-то вроде этого:

  String thisDate = cursor.getString(dateIndex); String prevDate = null; // get previous item's date, for comparison if (cursor.getPosition() > 0 && cursor.moveToPrevious()) { prevDate = cursor.getString(dateIndex); cursor.moveToNext(); } // enable section heading if it's the first one, or // different from the previous one if (prevDate == null || !prevDate.equals(thisDate)) { dateSectionHeaderView.setVisibility(View.VISIBLE); } else { dateSectionHeaderView.setVisibility(View.GONE); } 

Может ли кто-нибудь направить меня, как я могу достичь этой задачи.

Со значительной болью.

Вам нужно будет создать свой собственный подкласс CursorAdapter (или, возможно, SimpleCursorAdapter ). В этом подклассе вам нужно будет вычислить количество строк заголовка и настроить getCount() для соответствия. Вам нужно будет getViewTypeCount() вернуть правильный номер. Вам нужно будет определить позиции этих строк заголовка и настроить getItemViewType() , newView() и bindView() для работы с вашими строками заголовка, корректируя значение position для строковых строк, чтобы учесть количество заголовков, которые впереди Этой строки, так что вы получите правильную позицию Cursor для работы. Возможно, также потребуются и другие корректировки, но это довольно точно.

Если меня никто не бьет, я, вероятно, напишу один из них в следующем году, как только это понадобится для моего проекта.

Это очень просто для реализации:

 public class ChatAdapter extends NoteBaseAdapter { private Cursor mCursor; /** * List of notes to showToast */ public int getCount() { int count = 0; if (mCursor != null) count = mCursor.getCount(); return count; } public Comment getItem(int position) { mCursor.moveToPosition(position); Comment comment = Comment.fromCursor(mCursor); return comment; } public long getItemId(int position) { return 0; } public View getView(final int position, View convertView, ViewGroup parent) { final Comment comment = getItem(position); CommentCell cellView = null; if (convertView == null) { cellView = new CommentCell(parent.getContext()); cellView.setup(elementsColor, backgroundColor); } else cellView = (CommentCell) convertView; cellView.setComment(comment); boolean showHeader = false; String currentDate = null; if (position > 0 && position < getCount()) { int previousPosition = position - 1; Comment previousComment = getItem(previousPosition); currentDate = comment.headerDate(); String previousDate = previousComment.headerDate(); showHeader = !currentDate.equalsIgnoreCase(previousDate); } else { showHeader = true; currentDate = comment.headerDate(); } cellView.showHeader(showHeader, currentDate); return cellView; } public void update(long itemUniqueId) { mCursor = Comment.fetchResultCursor(itemUniqueId); notifyDataSetChanged(); } 

И показать / скрыть заголовок в пользовательском представлении CommentCell:

  public void showHeader(boolean show, String currentDate) { if (show) { headerTextview.setVisibility(VISIBLE); headerTextview.setText(currentDate); } else { headerTextview.setVisibility(GONE); } } 

Создать дату строки:

 public String headerDate() { String createDateStr = null; if (createDate != Consts.NONE_LONG) createDateStr = TimeUtil.dateToString("dd MMMM", new Date(createDate)); return createDateStr; } public static String dateToString(String format, Date date) { DateFormat dateFormat = new SimpleDateFormat(format, Locale.getDefault()); String text = dateFormat.format(date); return text; }