Alex Alex - 2 months ago 9
Android Question

Fragment - wait for onCreateView() to complete before running methods

I'm struggling with a puzzling sequence of events relating to a

Fragment
. I'm trying to add a fragment to an
Activity
, and then call a method inside the fragment to update some text. However, what I am finding is that the method is being processed in the fragment before
onCreateView()
finishes, which leaves me with a null
View
object, and my method fails. Here is the
Activity
code:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_log_entry_details);

fragmentManager = getSupportFragmentManager();

titleBarFragment = new TitleBarVerticalFragment();

fragmentTransaction = fragmentManager.beginTransaction ();
fragmentTransaction.add(R.id.log_entry_title_frame, titleBarFragment);
fragmentTransaction.commit();

titleBarFragment.updateTitleBar("Edit Log Entry", 20, false);
}


Seems simple enough. Here is the TitleBarVerticalFragment class:

public class TitleBarVerticalFragment extends TitleBarFragment {

@Inject SharedVisualElements sharedVisualElements;

View view;
TextView titleLabel;

public TitleBarVerticalFragment() {
// add this line for any class that want to use any of the singleton objects
Injector.INSTANCE.getAppComponent().inject(this);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

super.onCreateView(inflater, container, savedInstanceState);

Log.d(Constants.TAG, "title fragment onCreateView()");

view = inflater.inflate(R.layout.fragment_title_bar_vertical, container, false);

ImageView logoImage = (ImageView) view.findViewById(R.id.logo_vertical);
titleLabel = (TextView) view.findViewById(R.id.verticalTitleLabel);

titleLabel.setTextColor(sharedVisualElements.secondaryFontColor());
titleLabel.setTypeface(sharedVisualElements.font());
titleLabel.setTextSize(20);

logoImage.setImageDrawable(sharedVisualElements.logoImage());
logoImage.setBackgroundColor(Color.TRANSPARENT);

return view;
}

public void updateTitleBar(String text, int textSize, boolean titleLabelIsHidden) {

Log.d(Constants.TAG, "about to update title bar text");

if (view == null) {
Log.d(Constants.TAG, "vertical title fragment is null");
return;
}

if (titleLabel == null)
titleLabel = (TextView) view.findViewById(R.id.verticalTitleLabel);

if (titleLabel == null) {
Log.d(Constants.TAG, "vertical title label is null");
return;
}

Log.d(Constants.TAG, "updating title text: " + text);
titleLabel.setText(text);
titleLabel.setTextSize(textSize);
}


Note the order of this logcat output. Notice how
onCreateView()
seems to run after the
updateTitleBar()
method? How can that be?


about to update title bar text
vertical title fragment is null

title fragment onCreateView()



How can I ensure that
onCreateView()
runs before I call any of the fragment's other methods? Thank you.

Answer

Define a listener interface and implement it in your Activity.

interface LyfecycleListener {
  void onCreatedView();
}

in your Activity:

@Override
protected void onCreate(Bundle savedInstanceState) {
  ...
  this.titleBarFragment = new TitleBarVerticalFragment();
  this.titleBarFragment.setListener(this)
  ...
}

@Override
public void onCreatedView() {
  titleBarFragment.updateTitleBar("Edit Log Entry", 20, false);
}

in your Fragment:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

...

  this.listener.onCreatedView();
}
Comments