Please help! I tried everything! :(
I've got a schedule Class, which is simply a custom ViewGroup (with custom onMeasure() and onLayout()), which enables me to place childs(=events) with LayoutParams for column/row start and column/row end. The number of childs and their LayoutParams depend on database entries.
Now I'm trying to add childs (events) from my database. I'd have to use a Cursor Adapter, so my schedule Class has to extend ListView, right? I tried that but the newView() method of the adapter is never called. Why not?? My custom ListView doesn't ask the adapter for childs, no childs are added. I also can't add the childs by hand calling schedule.addView() if I extend from AdapterView.
I'd be really (really) happy if someone could help!
Regards, cody
This is my custom 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;
}
}
And this is the 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" />
In my Activity I've got that code:
Schedule schedule = new Schedule(this, 4, rowTimes.length, 15, 15, rowTimes);
Cursor cursor = dbManager.getEvents(day); MySimpleCurserAdapter adapter = ... ?? // schedule.setAdapter not working...
How can I add events to the schedule with the data from the cursor?