Invalidate is not redrawing the screen. Android

▼魔方 西西 提交于 2020-01-30 07:25:06

问题


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.


回答1:


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); 
     }



回答2:


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.



来源:https://stackoverflow.com/questions/5072749/invalidate-is-not-redrawing-the-screen-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!