无效并不是重画屏幕。安卓

发布于 2024-10-18 14:49:46 字数 405 浏览 9 评论 0原文

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 的每一行之后重绘,但它仍然只在最后重绘?有人可以帮我吗,我想不通。

BufferedReader hl  = new BufferedReader(new InputStreamReader(getResources().openRawResource(R.raw.lines)));
                while(hl.ready()){
                    showLines.append(hl.readLine()+"\n");
                    showLines.invalidate();
                    Thread.sleep(10);
                }

That is my code but it is not redrawing when I tell it to. It is supposed to redraw after every line that is added to textview, but it still only redraws at the end? Can someone please help me, I can't figure it out.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

〃温暖了心ぐ 2024-10-25 14:49:46

这是因为你的 invalidate() 位于一个线程 while 循环中,并且正在累积,可以这么说,直到循环结束,并且只有它绘制...

我在循环中使用 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); 
     }

That is bacause your invalidate() is in a thread while loop and is being acummulated, so to speak, until the loop ends, and only than it draws...

I had the same problem when using Thread.sleep() within a loop. You can use a post delayed method to draw each line, which in this case is one line per second:

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); 
     }
听风吹 2024-10-25 14:49:46

这是我的代码,但当我告诉它时它不会重绘。

invalidate() 在您调用它时不会立即发生。 invalidate()append() 以及任何涉及 UI 的其他内容一样,将一条消息放入消息队列中,一旦您执行此操作,主应用程序线程就会处理该消息让它吧。由于您将用户的时间浪费在无意义的 sleep() 调用上,再加上在主应用程序线程的循环中执行 flash I/O,因此主应用程序线程无法处理消息队列上的消息。循环结束后,它将处理所有 invalidate()append() 调用,并且您从所在的任何回调将控制权返回给 Android。

应该在添加到文本视图的每一行之后重新绘制

不,不是。

但它仍然只在最后重绘?

正确的。

简单的解决方案是摆脱 invalidate()Thread.sleep(10) 并将整个文件内容加载到 TextView< /code> 在一次调用中。

更好的解决方案是通过 AsyncTask 读取整个文件,然后在 onPostExecute() 的一次调用中将文本附加到 TextView >。如果需要,请使用 ProgressDialog 或其他东西来让用户在此过程中保持娱乐。

That is my code but it is not redrawing when I tell it to.

invalidate() does not happen immediately when you call it. invalidate(), like append() and anything else involving the UI, puts a message on a message queue, that will be processed by the main application thread as soon as you let it. Since you are wasting the user's time in pointless sleep() calls, plus doing flash I/O, in a loop on the main application thread, the main application thread cannot process the messages on the message queue. It will process all of your invalidate() and append() calls after your loop is over and you return control to Android from whatever callback you are in.

It is supposed to redraw after every line that is added to textview

No, it isn't.

but it still only redraws at the end?

Correct.

The simple solution is for you to get rid of the invalidate() and the Thread.sleep(10) and just load the entire file contents into your TextView in one call.

The better solution is for you to read the whole file in via an AsyncTask, then append the text to the TextView in one call in onPostExecute(). If needed, use a ProgressDialog or something to keep the user entertained while this is going on.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文