1
我正在使用GridView在4列表中顯示單詞列表。我的自定義適配器的getView方法會檢查單詞的寬度,如果不合適,會將其縮小。它使用遞歸檢查來執行此操作,該檢查不斷縮放文本,直到它適合。Android:從While循環內的適配器更新UI
private void shrinkText(final TextView wv, final String word) {
wv.setTextSize(defaultTextSize);
new Thread(new Runnable() {
@Override
public void run() {
while (wv.getWidth()>0 && wv.getPaint().measureText(word) > wv.getWidth()) {
Logg.d("word too big. Shrink from " + wv.getTextSize()/density + " to " + (wv.getTextSize()/density-1.0f));
wv.setTextSize(wv.getTextSize()/density - 1.0f);
}
}
}).start();
}
因爲我使用的是一個while循環,所以我使用了一個新的線程來保護ANR,避免出現無限循環的情況。這是奇怪的事情:有時它很好。然後有時我得到以下錯誤:
09-26 14:25:31.389 6427-7765/com.myapp.debug E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-7789
Process: com.myapp.debug, PID: 6427
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
我試着把setTextSize一個runOnUiThread語句中,但我不能讓它在適配器內部工作。最終我只是想要這個工作。我覺得我的選擇是:
- 保持while循環在UI線程並以某種方式保護它(如何?)
- 移動setTextSize調用UI線程
- 其他的東西(如何?)?
感謝您的幫助!
UPDATE:根據Rustam的回答,我用wv.post寫入UI。然而,需要使用while循環意味着setTextSize必須在與while條件本身相同的線程中完成。我從評估TextView.getTextSize切換到Paint.getTextSize,因爲我可以設置Paint的文本大小而不影響UI,因此可以在分支線程內部進行設置。傑裏操縱,但它似乎工作。
private void shrinkText(final TextView wv, final String word) {
wv.setTextSize(defaultTextSize);
final Paint mPaint = new Paint(wv.getPaint());
new Thread(new Runnable() {
@Override
public void run() {
while (wv.getWidth()>0 && mPaint.measureText(word) > wv.getWidth()) {
Logg.d("word too big. Shrink from " + mPaint.getTextSize()/density + " to " + (mPaint.getTextSize()/density-1.0f));
mPaint.setTextSize(mPaint.getTextSize() - 1.0f);
}
if (wv.getWidth()>0 && wv.getPaint().measureText(word) > wv.getWidth()) {
wv.post(new Runnable() {
@Override
public void run() {
Logg.d(word + " final size=" + mPaint.getTextSize()/density);
wv.setTextSize(mPaint.getTextSize()/density);
}
});
}
}
}).start();
}
只是去嘗試......如此看來,setTextSize需要在同一個線程while條件。它停止崩潰,但它也不會迭代 - 只是不斷重新運行,從14更改爲13,然後由於某種原因完全消失。 – Scott 2014-09-26 19:21:01
那可能是計算問題.. – Rustam 2014-09-26 19:27:15
我想我解決了這個問題。當然,我不能在while循環中使用wv.post方法,因爲while條件受setTextSize影響。我最終做的是在TextView中製作一個Paint對象的副本並對其進行評估 - 它不需要我寫入UI。然後,在完成while循環之後,我使用該Paint對象在Post方法中設置TextView的TextSize屬性。 – Scott 2014-09-27 00:54:41