2012-01-13 52 views
0

在過去的幾個小時裏這讓我瘋狂。
我有一個FrameLayout,它有一個單一的按鈕。 當你點擊按鈕時,我想繪製一個新單詞,並得到它的測量值,這樣我就可以在它周圍繪製一個矩形。TextView測量,頂部,左側沒有被更新

這是一個運行當你點擊「下一步」按鈕的代碼:

private OnClickListener m_onClickNext = new OnClickListener() 
{ 
    public void onClick(View v) 
    { 
     TextView tv = new TextView(context);     
     tv.setTextColor(0xFF000000); 
     tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 100);     
     tv.setText("TEXTSTRING"); 

     m_frameLayout.addView(tv, new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, Gravity.CENTER)); 

     //tv.measure(0, 0); 
     int left = tv.getLeft(); 
     int top = tv.getTop(); 
     int right = left + tv.getMeasuredWidth(); 
     int bottom = top + tv.getMeasuredHeight(); 
    } 
}; 

左邊和頂部爲0(零)。
添加tv.measure(0, 0)至少更新寬度和高度。

我嘗試撥打invalidaterequestLayout,tvm_frameLayout,但沒有成功。

我知道佈局還沒有完成繪圖..但爲什麼?

回答

0

我知道佈局還沒有完成繪圖..但是,爲什麼?

佈局未完成繪圖的原因是因爲您使用的是UI繪圖使用的相同線程。除非您使用AsyncTask或其他線程指定,否則您所做的每件事都使用單個線程(UI線程)。 Invalidate()不是強制立即重繪的函數。 Invalidate()標記一切,這樣當UI線程空閒時,它將重繪任何無效的內容。如果你持續給出UI線程指令,那麼重畫就沒有機會發生。

換句話說,Invalidate不會改變它的數字,直到繪圖有機會運行,並且因爲在你詢問它的數字之前沒有機會運行,它不可能給你正確的數字。爲了使其行爲符合要求,需要發生以下幾件事:

  1. 您必須允許佈局繪製。這可以通過三種方式完成:a)你可以在不同的線程上運行你的點擊,但是這並不能保證它什麼時候完成,只是它會。 b)您可以覆蓋invalidate(),以便它執行回調以通知您添加矩形。 c)您可以實現一個偵聽器,以便在TextView的大小發生更改時運行您的代碼。

  2. 在佈局重新繪製之後,您可以應用特殊的矩形。通過使用上面的方法c),你可以基本上馬上做到這一點。但是,您必須確保您再次失效(),導致處理中出現潛在的循環。所以,確保有一個指示器告訴你,你已經畫出矩形,而不是第三次失效()。

希望這有助於

FuzzicalLogic

+0

謝謝,我實現了'OnLayoutChangeListener' – Itsik 2012-01-14 08:16:59

相關問題