Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 362
AndroidDev Avatar asked Dec 08 '15 18:12

AndroidDev


3 Answers

Try running fragmentManager.executePendingTransactions() after fragmentTransaction.commit(); and before titleBarFragment.updateTitleBar("Edit Log Entry", 20, false);

like image 81
Jonnathan Avatar answered Sep 23 '22 21:09

Jonnathan


Just use onStart() on your activity

like image 24
Pablo Cegarra Avatar answered Sep 23 '22 21:09

Pablo Cegarra


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();
}
like image 21
artkoenig Avatar answered Sep 25 '22 21:09

artkoenig