片段 - 在运行方法之前等待onCreateView()完成

8

我遇到了一个与Fragment相关的令人困惑的事件序列。我正在尝试向Activity添加一个片段,然后调用片段内的一个方法来更新一些文本。但是,我发现该方法在片段的onCreateView()完成之前被处理,这导致我得到一个空的View对象,我的方法失败了。以下是Activity代码:

@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);
}

看起来很简单。这是TitleBarVerticalFragment类:

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);
    }

请注意此 logcat 输出的顺序。请注意 onCreateView() 看起来在 updateTitleBar() 方法之后运行了?这可能是怎么回事?

即将更新标题栏文本
垂直标题片段为空
标题片段 onCreateView()

如何确保在调用片段的任何其他方法之前先运行 onCreateView()?谢谢。

我通常在Fragment内使用constructor来传递值到Fragment中。 - K Neeraj Lal
谢谢。我也可以使用setArguments方法。这个方法已经存在于片段类中,所以我希望能够直接重用它,而不是编辑类本身。我有其他已经使用此片段的活动,所以我不想改变它们。我只是好奇为什么这个顺序会出错,以便更多地了解片段生命周期。 - AndroidDev
嗨 @Alex,你能发表你的解决方案吗?什么对你起作用了? - Bhagat
3个回答

6
在fragmentTransaction.commit();之后和titleBarFragment.updateTitleBar("Edit Log Entry", 20, false);之前尝试运行fragmentManager.executePendingTransactions()。

这是个好主意。不过由于某些原因没能起作用。感谢建议。 - AndroidDev

4

只需在您的活动上使用onStart()


1

定义一个监听器接口并在您的Activity中实现它。

interface LyfecycleListener {
  void onCreatedView();
}

在你的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);
}

在你的Fragment中:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

...

  this.listener.onCreatedView();
}

如果我理解正确,似乎代码是自行计时事件,而不是依赖于Android系统。对吗? - The Original Android
是的,这是一个针对此类问题的通用解决方案,称为观察者模式 - artkoenig

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接