Search code examples
androidandroid-layoutviewactivity-lifecycleviewgroup

When does an Activity Layout It's Views


I'm wondering when during an Activities lifecycle views start being layed out, or perhaps when a viewgroup decides its time to layout itself.

I have a class and activity set up like this ->

public class MainActivity extends AppCompatActivity
{
   protected void onCreate(Bundle savedInstanceState)
   {
      Log.i("i", "on Create");
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      myStack = (myStack) findViewById(R.id.myStack);
      myStack.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
     {
         @Override
         public void onGlobalLayout()
         {
         Log.i("i", "listener detected Layout");
         }
      }
      myStackAdapter adapter = new myStackAdapter(dataset);
      myStack.setAdapter(adapter);
   }
   protected void onStart()
   {
      Log.i("i", "on Start");
      super.onStart();
   }
}

public class myStack extends ViewGroup
{
   public myStack(Context context, AttributeSet attrs, int defStyleAttr)
   {
      super(context, attrs, defStyleAttr);
      initialize();
   }
   public void initialize()
   {
      Log.i("i", "initialize called");
   }
   public void onLayout(boolean changed, int l, int t, int r, int b)
   {
      Log.i("i", "on Layout");
      if (adapter == null)
      {
         Log.i("i", "adapter is null");
         return;
      }
      for (conditions)
      {
         addNextView();
      }
   }
   public void setAdapter(Adapter adapter)
   {
      Log.i("i", "adapter set");
      this.adapter = adapter;
   }

The output is as follows

  • initialize called
  • adapter set
  • on Layout

Edit: added more checks, output is -on Create, -initialize called, -adapter set, -on Start, -on Layout, -listener detected layout

However, this implies to me that onLayout is only called after setAdapter has been called from the MainActivity, as my adapter is null by default. So i'm wondering when onLayout is triggered for the first time. Is it after onCreate is finished in the MainActivity (perhaps during onStart)? or else is there some other reason why onLayout (following onMeasure) wouldn't be the first thing that is called when instantiating myStack.


Solution

  • onLayout() is called inside layout() when view size is changed or after measurement phase is finished and mPrivateFlags contains PFLAG_LAYOUT_REQUIRED bit set.

    It is very likely that your myStack class has not changed in size nor required layout flag set because it has not contained any child view yet.

    As soon as you set adapter, then child view is inserted and make view group size changed, hence onLayout() is triggered.