2010-10-13 63 views
1

请帮忙!我尝试了一切! :(Android:我如何使用CursorAdapter将孩子添加到我的自定义ViewGroup中?

我有一个时间表类,它只是一个自定义的ViewGroup(带自定义的onMeasure()和onLayout()),它使我能够将Layouts/Row开头的childs(= events)列/行结束孩子的数量和他们的LayoutParams取决于数据库条目

现在我想从我的数据库添加孩子(事件)我必须使用光标适配器,所以我的日程安排类必须扩展ListView,对吗?我试过了,但是适配器的newView()方法从来没有被调用过,为什么不呢? 我的自定义ListView没有向适配器请求孩子,也没有添加孩子。如果我从AdapterView扩展,手动添加childs调用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.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); 

光标光标= dbManager.getEvents(天); MySimpleCurserAdapter adapter = ...? // schedule.setAdapter无法正常工作...

如何使用游标中的数据向计划添加事件?

回答

2

你不应该需要扩展ListView。你只是想将一个ListView的实例添加到你的布局中。

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

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

+0

感谢您的回复。但是,如何为不扩展ListView的ViewGroup设置适配器?不允许调用setAdapter()。 – cody 2010-10-13 16:54:04

+0

我不确定为什么你有一个自定义的ViewGroup。您是否阅读了ListView教程?您需要一个布局文件来描述每个项目的布局。然后,在你的主布局中你有一个ListView。你在onCreate中通过ID获得listView,并在那里设置适配器。 – 2010-10-13 18:41:42

+0

我添加了代码。我无法弄清楚如何将自定义的ViewGroup和一个ListView组合到项目(= events)中。我不明白为什么我的ViewGroup不能直接成为ListView。 – cody 2010-10-13 19:35:40

相关问题