BufferedReader hl = new BufferedReader(new InputStreamReader(getResources().openRawResource(R.raw.lines)));
while(hl.ready()){
showLines.append(hl.readLine()+"\n");
showLines.invalidate();
Thread.sleep(10);
}
这是我的代码,但是当我告诉它时它不会重绘。它应该在添加到textview的每一行之后重绘,但它仍然只在最后重绘?有人可以帮助我,我无法弄清楚。
答案 0 :(得分:2)
这是因为你的invalidate()在循环中的一个线程中被占用,所以可以说,直到循环结束,而且只是它绘制...
在循环中使用Thread.sleep()时遇到了同样的问题。您可以使用后延迟方法绘制每一行,在本例中为每秒一行:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
BufferedReader hl = new BufferedReader(new InputStreamReader(getResources().openRawResource(R.raw.text)));
TextView showLines = (TextView) findViewById(R.id.textView1);
appendLines(hl, showLines);
}
public void appendLines(final BufferedReader br, final TextView tv){
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
try {
if(br.ready()){
try {
tv.append(br.readLine()+"\n");
} catch (IOException e) {
e.printStackTrace();
}
tv.invalidate();
appendLines(br, tv);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}, 1000);
}
答案 1 :(得分:1)
当你打电话时,这是我的代码,但是当我告诉它时它不会重绘。
invalidate()
不会立即发生。 invalidate()
与append()
以及涉及UI的任何其他内容一样,会在消息队列中放置一条消息,一旦您允许,它将由主应用程序线程处理。由于您在主要应用程序线程的循环中浪费用户在无意义的sleep()
调用中的时间,加上执行闪存I / O,因此主应用程序线程无法处理消息队列上的消息。它将在您的循环结束后处理所有invalidate()
和append()
调用,并且您可以从您所处的任何回调中将控制权返回给Android。
应该在添加到textview的每一行之后重绘
不,不是。
但它最后只会重绘一次?
正确。
简单的解决方案是让您摆脱invalidate()
和Thread.sleep(10)
,只需在一次通话中将整个文件内容加载到TextView
。
更好的解决方案是让您通过AsyncTask
阅读整个文件,然后在TextView
的一次通话中将文字附加到onPostExecute()
。如果需要,请使用ProgressDialog
或其他内容让用户在此过程中受理。