Подтвердить что ты не робот

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

Я хочу отобразить ListView с Date как SectionHeader.

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

My Custom 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

Джефф Шарки

Amazing ListView

SO Вопрос

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

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

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

Отредактировано. Согласно Graham Borald Answer (Это прекрасно работает, но это было быстро исправить.)

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); Кажется, что курсор не получает никаких данных.

4b9b3361

Ответ 1

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

    String thisDate = cursor.getString(dateIndex);
    String prevDate = null;

    // get previous item date, for comparison
    if (cursor.getPosition() > 0 && cursor.moveToPrevious()) {
        prevDate = cursor.getString(dateIndex);
        cursor.moveToNext();
    }

    // enable section heading if it the first one, or 
    // different from the previous one
    if (prevDate == null || !prevDate.equals(thisDate)) {
        dateSectionHeaderView.setVisibility(View.VISIBLE);
    } else {
        dateSectionHeaderView.setVisibility(View.GONE);
    }

Ответ 2

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

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

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

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

Ответ 3

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

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