I want to display ListView with Date as SectionHeader.
What i have : I am displaying ListView from sqlite database using custom SimpleCursorAdapter.
My Custom SimpleCursorAdapter is :
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 Results so far :
MergeAdapter
Jeff Sharkey
Amazing ListView
SO Question
Problem : I want to display listview with Date as section headers. Ofcourse Date values come from sqlite database.
Can anyone please guide me how can i achieve this task.
Or Provide me a Sample Code or Exact(like) Code related to the same.
Edited According to Graham Borald's Answer (This works fine. However it was a quick fix.)
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;
}
}
Edited According to CommonsWare's Answer
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();
}*/
}
I am getting Null Pointer Exception at line : Cursor date=adapter.fetchTodo(id);
Seems that Cursor is not getting any data.
By far the simplest way to do this is to embed the date header view in every item. Then, all you need to do in bindView
is compare the previous row's date to this row's date, and hide the date if it's the same. Something like this:
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); }
Can anyone please guide me how can i achieve this task.
With substantial pain.
You will need to create your own subclass of CursorAdapter
(or possibly SimpleCursorAdapter
). In that subclass, you will need to calculate the number of header rows and adjust getCount()
to match. You will need to have getViewTypeCount()
return the right number. You will need to identify the positions of those header rows and adjust getItemViewType()
, newView()
, and bindView()
to deal with your header rows, adjusting the position
value for detail rows to take into account the number of headers that are ahead of that row, so you get the right Cursor
position to work with. There may need to be other adjustments as well, but those are fairly certain.
If nobody beats me to it, I will probably write one of these in the next year, once it's needed for a project of mine.
it is very simple for implementation:
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();
}
and show/hide header in custom CommentCell view:
public void showHeader(boolean show, String currentDate) {
if (show) {
headerTextview.setVisibility(VISIBLE);
headerTextview.setText(currentDate);
} else {
headerTextview.setVisibility(GONE);
}
}
create string date:
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With