Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

forceLayout(), requestLayout()

My reading of the android documentation finds the methods forceLayout() (which is to produce a layout display at the next layout request) and requestLayout() (which is supposed to post an immediate layout request), but I can not get them to behave as advertised. In particular, if I do one set text before a Thread.Sleep and one after, it waits for the Sleep to finish before setting both texts at once, whether or I call the forceLayout() and requestLayout() in between. Please do not respond with a lot of nonsense about how I should not call a Thread.Sleep in the UI thread. If I wrap the Thread.Sleep in a CountDownTimer it works perfectly well (as long as I have the tick time short enough to not interfere with sleep time, and the duration of the timer long enough to permit the Sleep to finish. The following is an example:

    int i=0;
TextView tv2;
TextView tv1;
LinearLayout ll;
Button bt;
@Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ll=new LinearLayout(this);
    ll.setOrientation(LinearLayout.VERTICAL);
    tv1=new TextView(this);
    tv2=new TextView(this);
    bt=new Button(this);
    bt.setText("Press to start");
    ll.addView(bt);
    ll.addView(tv1);
    ll.addView(tv2);
    tv2.setText("");
    setContentView(ll);
    bt.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            tv1.setText("starting sleep");
            new CountDownTimer(6000,50){
              public void onTick(long msuf)
                {if(i==1)
                    {
                try{
              Thread.sleep(4000);
              tv2.setText("waking up");
               }
            catch(InterruptedException e){};
            }
                i++;
                 }
               public void onFinish(){}}.start();
              }         
      });

        }
like image 879
peter gottlieb Avatar asked Mar 25 '11 05:03

peter gottlieb


1 Answers

[lots of nonsense about calling sleep() in UI thread]. If i get it right, you mean having something like:

//...inside onTick()
try {
    tv2.setText("almost waking up"); // first setText()
    Thread.sleep(4000);
    tv2.setText("waking up"); // second seText()
}

If you make your main thread sleep, it will just stop processing anything: the current method, the thread loop and the message queue. Once awake again, it will finish executing the method, with the second setText() overriding the first one, and then leave the thread loop continue and do the UI refresh, showing only the second text.

Not requestLayout() nor forceLayout() can actually make the UI refresh immediately, they will both schedule a layout request in the thread loop. I'm not sure, but I think the difference between them is that requestLayout() is called by a view that has changed its size/position in its parent, and forceLayout() is called by a ViewGroup that needs its children to be re-laid out.

Therefore [more nonsense about calling sleep() in UI thread]. For such things calling postDelayed() on a main thread handler is the best solution probably, if you don't want to mess with multithreading.

like image 170
bigstones Avatar answered Oct 09 '22 00:10

bigstones