2013-02-13 37 views
3

我有一个使用自定义LinearLayout的小应用程序,名为LinearlayoutOutlined。我想绘制不同大小和颜色的盒子。它还有两个文本标签,表示时间间隔。布局必须在某些用户操作后重新绘制。因此,我不刷新布局是为什么onDraw()不断调用?

slotPanel.setDayBoundariesInMinutes(db, dw); 
TimeSlot[] tSlots = nextDaysSlots.getGaps(dayOfWeek); 
slotPanel.setItems(tSlots); 
slotPanel.invalidate(); 

其中slotpanelLinearLayoutOutlined实例。

我检测到onDraw方法是不断调用的。在特定的循环次数之后不会停止呼叫。

这里是整个LinearLayoutOutlined类:

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

请给我一些想法,我该怎么办? Thanx提前


我不明白为什么我不能添加评论我自己的问题?!​​?

@Romain Guy: 谢谢!好的,我明白了。但我必须将setText()与drawin框一起使用。文本标签覆盖,它们是最上面的。我该怎么办?

回答

8

每当您通过TextView调用setText()时,UI工具包需要重新布局并重新绘制UI。既然你每次都在调用onDraw(),你基本上已经创建了一个无限的绘图循环。

,我们在您绘制方法等问题,以及:你不应该做一个findViewById()每一次,你不应该创建一个新的SimpleDateFormat每一次,你不应该创建新Date对象每次等

0

如果仅在文本发生更改时才在onDraw()中调用setText,则可以避免无限循环。 使用此方法代替setText:

void setTextIfChanged(TextView tv, CharSequence text) { 
    if (!text.equals(tv.getText())) 
     tv.setText(text); 
} 
相关问题