android – requestLayout() has no effect when called from onSizeChanged()?-ThrowExceptions

Exception or error:

I have a view that display texts and images in columns, in a horizontally scrolling window. It reflows and thus (at least potentially) resizes itself as its content changes; it also reflows and resizes (maintaining a roughly constant area) when the soft keyboard comes and goes and the view height changes.

What I found was that calling requestLayout() works (in the sense that it does trigger a call to my onMeasure() overload) most of the time … but not when called from my onSizeChanged() handler.

I was able to work around this by post()ing a Runnable that called requestLayout() and then post()ed another Runnable that called my code that needs to run after the onMeasure() … but this seems a bit fragile (I don’t want to add a delay, yet I do want to be sure that my second Runnable does execute after the async onMeasure()) and, perhaps because it makes so many passes through the event loop, the screen flashes too much.

Is there some way – in an onSizeChanged() – to force an onMeasure() (and, probably, another onSizeChanged()) to happen before the next onDraw()?

How to solve:

I would suggest making a call back class, maybe two

    interface ImGonnaTellClassBThatClassAdidFinished(){

              void ClassHasFinishedProcessing(String YaySuccess);

              void ClassHasFailedProcessing();    

              void SomethingWackaDoodleHappened(String SomeShyte);       
              }

Then Overload the class when you need it to perform functions

     public class FunctionA{
              ImGonnaTellClassBThatClassAdidFinished someName = new  ImGonnaTellClassBThatClassAdidFinished(){
              @Override
              void ClassHasFinishedProcessing(String YaySuccess){
              //Well I should Call class B with the info then
              //Heres Sting YaySuccess, Use it in the right way
              }
              void ClassHasFailedProcessing(){ 
              //Well I failed and should let someone know
              }
              void SomethingWackaDoodleHappened(String SomeShyte){
              //Well Something else happened and I have some info on it
              }
         //Dont forget to pass it to the class
         ClassB doWorkMeow = new ClassB();
         doWorkMeow.hereYouGo(someName);
     }

Make sure you call back when your finished

     class ActivityB(){

     public void hereYouGo(ImGonnaTellClassBThatClassAdidFinished finished){
     String itWorked = new String("Hooray");
     finished.ClassHasFinishedProcessing(itWorked);
     }
 }

Hope this helps, Good Luck in your endeavor.

###

The view implementation has a onlayout callback method that allows you to modify the child views and the positioning of the view inside the parent layout..

###

I solved the problem by postponing the call like this:

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    post(() -> someMethod());
}

Leave a Reply

Your email address will not be published. Required fields are marked *