0

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.

Kyle R
  • 99
  • 2
  • 12
  • when you call `setContentView()`. – Zamrony P. Juhara Sep 07 '17 at 04:33
  • @Zamrony However if that was the case then wouldn't the output be "on layout - > adapter is null -> initialize called -> adapter set"? – Kyle R Sep 07 '17 at 04:48
  • [Why does calling getWidth() on a View in onResume() return 0?](https://stackoverflow.com/q/22972022/3290339) – Onik Sep 07 '17 at 19:05
  • @Onik I set up a listener for that, and updated the code snippet above. The order of calls is -> on Create, initialize called, adapter set, on Start, on Layout, and then finally listener detected layout – Kyle R Sep 07 '17 at 20:31

1 Answers1

0

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.

Zamrony P. Juhara
  • 5,222
  • 2
  • 24
  • 40
  • It's not written in that code snippet, but after my (adapter==null) check, I have a for loop which adds views to myStack using addViewInLayout(). This is the only place I'm calling addView in this class. So myStack doesn't have any child views until onLayout() has already been called. – Kyle R Sep 07 '17 at 20:19
  • I updated the code to show that, and also took Onik's suggestion and set up a layout listener. It seems that layout doesnt get called until after the adapter is set and after on Start – Kyle R Sep 07 '17 at 20:34
  • @user3363126, the point at which the system calls `onLayout()` has nothing in common with your adapter. Have you read the explanation to my answer I referred in the comment or followed the other references in the post? Also, I recommend to look [here](https://stackoverflow.com/q/13146765/3290339) – Onik Sep 07 '17 at 20:52
  • @Onik Thanks that diagram does help. I realize it has nothing to do with my adapter being set, I even commented out that code, and I still get onLayout being triggered, which is fine I'm just wondering why. I guess my question could better be phrased at this point as "does a viewgroup recieve an initial layout pass before it adds any children". From looking at those discussions it seems the answer is yes. I think the reason why set adapter can output before onlayout is because onlayout is a more expensive process. It's starting before I call setadapter, but not finishing until after perhaps? – Kyle R Sep 07 '17 at 21:14