2011-06-07 72 views
25

我想显示ListView与日期为SectionHeader。自定义ListView与日期as SectionHeader(使用自定义SimpleCursorAdapter)

我有什么: 我使用自定义SimpleCursorAdapter从sqlite数据库显示ListView。

我的自定义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; 
} 
} 

谷歌到目前为止结果:

MergeAdapter

​​

Amazing ListView

SO Question

问题:我想显示带有日期的列表视图作为节标题。当然日期值来自sqlite数据库。

任何人都可以请指导我如何实现这一任务。

或者为我提供一个样本代码或与之相关的确切(如)代码。

编辑据格雷厄姆Borald的回答(这工作得很好。但是,这是一个速战速决。)

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(); 

}*/ 
} 

我越来越空指针异常 at line:Cursor date=adapter.fetchTodo(id); 似乎光标没有得到数据。

+0

https://github.com/emilsjolander/StickyListHea ders – Mertuarez 2013-02-07 21:37:46

回答

51

到目前为止,最简单的方法是在每个项目中嵌入日期标题视图。然后,您需要在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); 
    } 
+0

感谢您的快速fix.This工作。但我想按照CommonsWare的答案去。你能帮助实施吗? – 2011-06-09 11:18:17

+2

我不认为这是一个快速解决方案。我认为这是一个非常简洁而紧凑的解决方案。我在生产代码中使用了这种方法,并且它提供了非常好的结果。你不满意什么方面? – 2011-06-09 11:54:27

+0

问题:当我长时间点击第一个项目(其中还包含标题)时,该项目的整个视图变为黄色。我不想那样。 – 2011-06-09 12:15:08

4

任何人都可以请指导我如何完成这项任务。

伴随着巨大的痛苦。

您需要创建自己的子类CursorAdapter(或可能的SimpleCursorAdapter)。在该子类中,您将需要计算标题行的数量并调整getCount()以匹配。你将需要有getViewTypeCount()返回正确的数字。您需要确定这些标题行的位置,然后调整getItemViewType(),newView()bindView()以处理标题行,调整position值以获取详细信息行,以考虑该行之前的标题数量,以便您获得合适的Cursor职位。可能还需要进行其他调整,但这些调整是相当确定的。

如果没有人打我,我可能会在明年写下其中的一篇,一旦我的项目需要它。

+0

感谢您的高超回应。真的很感谢你的回答和努力。但是我想确认一下我的理解。 – 2011-06-07 11:53:45

+0

1. getCount()应返回项目数(行)或总项目数(行+标题)? – 2011-06-07 11:55:19

+0

@Kartik:行+标题。更确切地说,'getCount()'返回应该在'ListView'中的行数,与'Cursor'中的“行数”有些相似,但在你的情况下也需要考虑任何您将添加到混音中的标题或其他行。 – CommonsWare 2011-06-07 12:08:22

1

它是实现非常简单:

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; 
} 
+0

你能解释一下你的解决方案吗?这是很多代码。 – 2016-02-27 20:49:59