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