Пользовательский ListView с датой в виде SectionHeader (используется пользовательский SimpleCursorAdapter) - PullRequest
25 голосов
/ 07 июня 2011

Я хочу отобразить ListView с датой в виде 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

SO Вопрос

Проблема: Я хочу отобразить представление списка с датой в качестве заголовков разделов.Значения Ofcourse Date поступают из базы данных 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();

}*/
}

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

Ответы [ 3 ]

53 голосов
/ 08 июня 2011

Самый простой способ сделать это - встроить заголовок даты в каждый элемент . Затем все, что вам нужно сделать в 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);
    }
4 голосов
/ 07 июня 2011

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

С существенной болью.

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

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

2 голосов
/ 27 февраля 2016

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

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;
}
...