Android:如何使用CursorAdapter将子项添加到我的自定义ViewGroup?

时间:2010-10-13 16:20:54

标签: android

请帮忙!我尝试了一切! :(

我有一个计划类,它只是一个自定义的ViewGroup(使用自定义的onMeasure()和onLayout()),这使我能够使用LayoutParams为列/行开始和列/行放置子(=事件)结束。子项的数量及其LayoutParams取决于数据库条目。

现在我正在尝试从我的数据库添加子(事件)。我必须使用游标适配器,所以我的调度类必须扩展ListView,对吧?我尝试过,但永远不会调用适配器的newView()方法。为什么不?? 我的自定义ListView不会向适配器询问子项,也不会添加子项。如果我从AdapterView扩展,我也无法手动调用schedule.addView()来添加子项。

如果有人可以提供帮助,我真的非常高兴。

此致 科迪

这是我的自定义ViewGroup:

public class Schedule extends ViewGroup {
private int columns;
private int rows;
private float preferredCellWidth;
private float preferredCellHeight;
private String[] rowTimes;
private Paint paint;

public Schedule(Context context, int columns, int rows, float preferredCellWidth, float preferredCellHeight, String[] rowTimes) {
    super(context);
    this.columns = columns;
    this.rows = rows;
    this.preferredCellWidth = preferredCellWidth;
    this.preferredCellHeight = preferredCellHeight;
    this.rowTimes = rowTimes;
    init(context);
}

private void init(Context context) {
    Log.i("Schedule", "initSchedule...");
    setPaint();
    setWillNotDraw(false);
}

private void setPaint() {
    paint = new Paint();
    paint.setTextSize(preferredCellHeight*2/3);
    paint.setStyle(Paint.Style.STROKE);
    paint.setColor(getResources().getColor(R.color.white));
}

public Schedule(Context context, AttributeSet attrs) {
    super(context, attrs);
    readAttr(context, attrs);
    init(context);
}

public Schedule(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    readAttr(context, attrs);
    init(context);
}

private void readAttr(Context c, AttributeSet attrs) {
    android.content.res.TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.ScheduleLayout);
    this.columns = a.getInt(R.styleable.ScheduleLayout_columns, 1);
    this.rows = a.getInt(R.styleable.ScheduleLayout_rows, 1);
    this.preferredCellWidth = a.getDimension(R.styleable.ScheduleLayout_preferredCellWidth, 1);
    this.preferredCellHeight = a.getDimension(R.styleable.ScheduleLayout_preferredCellHeight, 1);
    a.recycle();
}

@Override
protected void onDraw(Canvas canvas) {
    //Log.i(this.toString(),"onDraw ..."+" this.getLeft()="+this.getLeft()+", this.getWidth()="+this.getWidth());
    super.onDraw(canvas);
    for (int i = 0; i < rows; i++) {
        int line = (int) Math.round(this.getTop()+ (i+1) * preferredCellHeight);
        canvas.drawText(this.rowtimes[i], this.getLeft()+5, line-3, paint);
        canvas.drawLine(this.getLeft(), line, this.getWidth(), line, paint);
    }
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    Log.i("Schedule", "onMeasure...");
    float width = (MeasureSpec.getSize(widthMeasureSpec) - getPaddingLeft() - getPaddingRight()) / columns;
    float height = (MeasureSpec.getSize(heightMeasureSpec) - getPaddingTop() - getPaddingBottom()) / rows;
    float cellWidth = preferredCellWidth;
    float cellHeight = preferredCellHeight;

    if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) {
        cellWidth = width;
    } else if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.AT_MOST) {
        cellWidth = Math.min(preferredCellWidth, width);
    }

    if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY) {
        cellHeight = height;
    } else if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) {
        cellHeight = Math.min(preferredCellHeight, height);
    }

    for (int i = 0; i < getChildCount(); i++) {
        View child = getChildAt(i);
        if (child.getVisibility() != GONE) {
            LayoutParams lp = (LayoutParams) child.getLayoutParams();
            int cwidth = (int) Math.round(cellWidth * lp.getWidth());
            int cheight = (int) Math.round(cellHeight * lp.getHeight());
            child.measure(
                    MeasureSpec.makeMeasureSpec(cwidth, MeasureSpec.EXACTLY),
                    MeasureSpec.makeMeasureSpec(cheight, MeasureSpec.EXACTLY)
            );
        }
    }
    setMeasuredDimension(
            (int) Math.round(cellWidth * columns + getPaddingLeft() + getPaddingRight()),
            (int) Math.round(cellHeight    * rows + getPaddingTop() + getPaddingBottom())
    );
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    if (!changed)
        return;

    int cellWidth = ((r-l) - getPaddingLeft() - getPaddingRight()) / columns;
    int cellHeight = ((b-t) - getPaddingTop() - getPaddingBottom()) / rows;

    for (int i = 0; i < getChildCount(); i++) {
        View child = getChildAt(i);

        if (child.getVisibility() != GONE) {
            LayoutParams lp = (LayoutParams) child.getLayoutParams();
            int cl = (int) Math.round(getPaddingLeft() + lp.columnStart    * cellWidth);
            int cr = (int) Math.round(getPaddingLeft() + lp.columnEnd * cellWidth);
            int ct = (int) Math.round(getPaddingTop() + lp.rowStart    * cellHeight);
            int cb = (int) Math.round(getPaddingTop() + lp.rowEnd * cellHeight);
            child.layout(cl, ct, cr, cb);
        }
    }
}

protected boolean checkLayoutParams(android.view.ViewGroup.LayoutParams p) {
    Log.i("Schedule", "checkLayoutParams...");
    if (p instanceof LayoutParams) {
        LayoutParams lp = (LayoutParams) p;
        if (lp.columnEnd > columns || lp.columnStart < 0)
            return false;
        if (lp.rowEnd > rows || lp.rowStart < 0)
            return false;
        return lp.columnEnd > lp.columnStart && lp.rowEnd > lp.rowStart;
    } else
        return false;
}

public android.widget.AbsListView.LayoutParams generateLayoutParams(AttributeSet attrs) {
    return new android.widget.AbsListView.LayoutParams(getContext(), attrs);
}

public static class LayoutParams extends android.view.ViewGroup.LayoutParams {
    public int columnStart;
    public int columnEnd;
    public int rowStart;
    public int rowEnd;

    public LayoutParams(int columnStart, int rowStart, int columnEnd, int rowEnd) {
        super(WRAP_CONTENT, WRAP_CONTENT);
        this.columnStart = columnStart;
        this.columnEnd = columnEnd;
        this.rowStart = rowStart;
        this.rowEnd = rowEnd;
    }

    public LayoutParams(Context c, AttributeSet attrs) {
        super(WRAP_CONTENT, WRAP_CONTENT);
        android.content.res.TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.EventLayout);
        this.columnStart = a.getInt(R.styleable.EventLayout_event_columnStart, 0);
        this.columnEnd = a.getInt(R.styleable.EventLayout_event_columnEnd,    this.columnStart + 1);
        this.rowStart = a.getInt(R.styleable.EventLayout_event_rowStart, 0);
        this.rowEnd = a.getInt(R.styleable.EventLayout_event_rowEnd, this.rowStart + 1);
        a.recycle();
    }

    public int getWidth() {
        return columnEnd - columnStart;
    }

    public int getHeight() {
        return rowEnd - rowStart;
    }
}

这是event-layout - event.xml:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="vertical"
android:gravity="center" >

    <TextView android:id="@+id/text_event_name"
    style="@style/Event_TextView1" />

    <TextView android:id="@+id/text_event_name2"
    style="@style/Event_TextView2" />

</LinearLayout>

<TextView android:id="@+id/text_event_weeks"
style="@style/Event_TextView2"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true" />

<TextView android:id="@+id/text_event_room"
style="@style/Event_TextView2"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true" />

在我的活动中我得到了那段代码:

Schedule schedule = new Schedule(this, 4, rowTimes.length, 15, 15, rowTimes);

Cursor cursor = dbManager.getEvents(day); MySimpleCurserAdapter适配器= ...... ?? // schedule.setAdapter无效...

如何使用光标中的数据向活动添加事件?

1 个答案:

答案 0 :(得分:2)

您不需要扩展ListView。您只想将ListView实例添加到布局中。

听起来您可能想要使用SimpleCursorAdaptor,您可以将自定义视图中的项目映射到您希望它们显示的数据模型对象。

有关使用适配器和ListView的正确方法的一些示例,请参阅Binding to Data with AdapterHello ListView