无效不会重绘屏幕。 Android的

时间:2011-02-22 00:15:50

标签: android scroll textview redraw invalidation

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的每一行之后重绘,但它仍然只在最后重绘?有人可以帮助我,我无法弄清楚。

2 个答案:

答案 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或其他内容让用户在此过程中受理。