I've a small application which uses customized LinearLayout, called LinearlayoutOutlined. I want to draw different sized and coloured boxes in it. It has also two text labels indicating time intervals. The layout has to be redraw after some user action. Therefore I do refresh the layout as is
slotPanel.setDayBoundariesInMinutes( db, dw );
TimeSlot[] tSlots = nextDaysSlots.getGaps( dayOfWeek );
slotPanel.setItems( tSlots );
slotPanel.invalidate();
where slotpanel is the LinearLayoutOutlined instance.
I detected that the onDraw method is called constantly. It is not stops calling after particular number of cycles.
Here is the whole LinearLayoutOutlined class:
package com.widgets;
public class LinearLayoutOutlined extends LinearLayout {
private int workingTimeBeginsInMinutes;
private int workingTimeFinishesInMinutes;
private TimeSlot[] items;
private Rect outline;
private Paint strokePaint = new Paint();
SimpleDateFormat formatter;
public LinearLayoutOutlined( Context context ) {
super( context );
setWillNotDraw( false );
}
public LinearLayoutOutlined( Context context, AttributeSet attrs ) {
super( context, attrs );
setWillNotDraw( false );
}
public void setWorkingTimeBeginsInMinutes( int m ) {
this.workingTimeBeginsInMinutes = m;
}
public void setWorkingTimeFinishesInMinutes( int m ) {
this.workingTimeFinishesInMinutes = m;
}
public void setDayWidthInMinutes( int dayWidthInMinutes ) {
this.workingTimeFinishesInMinutes = this.workingTimeBeginsInMinutes + dayWidthInMinutes;
}
public void setDayBoundariesInMinutes( int daybeginInMinutes, int dayWidthInMinutes ) {
setWorkingTimeBeginsInMinutes( daybeginInMinutes );
setDayWidthInMinutes( dayWidthInMinutes );
}
private int getWorkingTimeBeginsInMinutes() {
return workingTimeBeginsInMinutes;
}
public int getWorkingTimeFinishesInMinutes() {
return workingTimeFinishesInMinutes;
}
public void setItems( TimeSlot[] items ) {
this.items = items;
}
@SuppressLint("DrawAllocation")
@Override
protected void onDraw( Canvas canvas ) {
if( items == null ) return;
// time labels
TextView tvFrom = ( TextView )findViewById( R.id.lblStartingTime ), tvTo = ( TextView )findViewById( R.id.lblFinishingTime );
formatter = new SimpleDateFormat( "HH:mm", Locale.getDefault() );
tvFrom.setText( formatter.format( new Date( getWorkingTimeBeginsInMinutes() * 60000L ) ) );
tvTo.setText( formatter.format( new Date( getWorkingTimeFinishesInMinutes() * 60000L ) ) );
strokePaint.setStyle( Paint.Style.STROKE );
strokePaint.setStrokeWidth( 1 );
strokePaint.setStyle( Style.FILL );
outline = canvas.getClipBounds();
Convert.setDayBoundaries( getWorkingTimeBeginsInMinutes(), getWorkingTimeFinishesInMinutes(), outline );
for( TimeSlot slotItem: items ) {
RectTouchable rect = Convert.ToRect( slotItem );
if( slotItem.isFree() )
strokePaint.setARGB( 255, 0, 255, 0 );
else
strokePaint.setARGB( 255, 255, 0, 0 );
canvas.drawRect( rect.getRect(), strokePaint );
}
}
}
Please give me some idea, what should I do? Thanx in advance
I don't understand why I cannot add comment to my own question?!?
@Romain Guy: Thank you! OK I understand. But I have to setText() together with drawin boxes. The textlabels are overlayed, they are the topmost. What should I do?
Every time you call setText()
on a TextView
the UI toolkit needs to relayout and repaint the UI. Since you are doing this every time onDraw()
is called you've basically created an infinite drawing loop.
There are other issues in your draw method as well: you should not do a findViewById()
every time, you should not create a new SimpleDateFormat
every time, you should not create new Date
objects every time, etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With