2013-02-13 65 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); 
} 
相關問題