片段中onCreateView和onViewCreated之间的区别


118

这两种方法之间的本质区别是什么?创建TextView时,是否应该一个使用另一个来提高性能?

编辑:有什么区别

onCreateView() {
  root = some view
  View v = new View(some context);
  root.add(v);
  return root;
}


onViewCreated() {
  View v = new View(some context);
  getView().add(v);
}

我添加了一个编辑以解释我的困惑。如果一种方法紧接着另一种方法,为什么会有两种?不能像上述那样在单个方法中完成所有视图的创建吗?
史密斯

7
如果您必须使用Google进行猜测,那么可能是命名错误的方法。
巴拉兹内梅特

Answers:


85

我们会遇到一些崩溃,初始化中的视图onCreateView

您应该在中增加布局,onCreateView但不应使用findViewByIdin 初始化其他视图onCreateView

因为有时视图没有正确初始化。因此,请始终使用findViewByIdin onViewCreated(当完全创建视图时),并且还会将视图作为参数传递。

onViewCreated 确保已完全创建视图。

onViewCreated android文档

onCreateViewandroid.view.LayoutInflater, android.view.ViewGroupandroid.os.Bundle)返回之后,但尚未将任何保存状态恢复到视图中之前立即调用。一旦子类知道其视图层次结构已完全创建,这将给子类一个初始化自身的机会。但是,此时片段的视图层次结构尚未附加到其父级。


4
谢谢。我也遇到了这个问题并使用了组件。post(...)方法等待显示。可能会在中进行findViewById和其他初始化onViewCreated
CoolMind

22
该文字是从哪里引用的?我在官方文档中找不到它。
丹尼尔(Daniel)

您能否在开发人员网站上发布此处引用的声明的引用?
Namrata Bagerwal,

4
这实际上是不正确的。您可以在onCreateView中找到视图,但只能在将其放大后才能使用,也只能从已经放大的视图中找到。Fragment.findViewById()不安全,但是如果您已经放大了片段视图,则View.findViewById()是安全的。
colintheshots

46

onViewCreatedonCreateView(您初始化并创建所有对象(包括TextView)的方法)之后立即调用,因此这与性能无关。

从开发者站点:

onViewCreated(视图,捆绑了saveInstanceState)

在onCreateView(LayoutInflater,ViewGroup,Bundle)返回之后,但在任何保存的状态恢复到视图之前,立即调用。一旦子类知道其视图层次结构已完全创建,这将给子类一个初始化自身的机会。但是,此时片段的视图层次结构尚未附加到其父级。

资料来源:Fragment#onViewCreated


28

最好对中的字段分配子视图onViewCreated。这是因为该框架会为您执行自动的空检查,以确保正确创建和放大了Fragment的视图层次结构(如果使用XML布局文件)。

来自以下代码段:FragmentManger.java

// This calls onCreateView()
f.mView = f.performCreateView(f.getLayoutInflater(f.mSavedFragmentState), null, f.mSavedFragmentState);

// Null check avoids possible NPEs in onViewCreated
// It's also safe to call getView() during or after onViewCreated()
if (f.mView != null) {
    f.mView.setSaveFromParentEnabled(false);
    if (f.mHidden) f.mView.setVisibility(View.GONE);
    f.onViewCreated(f.mView, f.mSavedFragmentState);
}

6
它还将任何初始化逻辑与视图层次结构的膨胀/创建逻辑
分开

1
这很有趣,您是否还有其他资源可以了解为什么这种方法更好?这是否意味着每个onCreateView方法仅应包含“ return inflater.inflate(R.layout.layout_file,container,false);”;和onviewcreated应该具有所有“ findViewById”方法?这会带来什么性能提升?它会使过渡更快吗?
android_student

为了回答您的第一个问题,onCreateView用于创建片段的视图层次结构。这可以通过XML膨胀或动态创建(即,以编程方式创建Java视图)来实现。因此,您可能根本不打电话inflate。但是,如果片段需要具有UI元素,则应该返回一些父视图。否则返回null
orangemako

根本没有性能提升。查看FragmentManager和的代码performCreateView,调用onCreateView github.com/android/platform_frameworks_base/blob/…,可以保证onViewCreated生命周期回调有一些
好处

1.如果片段已动态添加到其父活动,则视图层次结构将附加到容器。2.您可以安全地进行视图查找,而不必担心NPE。3.我对动画不是很熟悉,但是片段过渡已经开始(即,发送到UI线程消息队列)。
orangemako

13

onCreateView返回展开的视图。OnViewCreated之后被调用onCreateView并获取具有膨胀视图的参数。其返回类型为void


1
我添加了一个编辑以解释我的困惑。如果一种方法紧接着另一种方法,为什么会有两种?不能像上述那样在单个方法中完成所有视图的创建吗?
史密斯

3
onCreateView应该很快返回。例如,OnViewCreate可用于执行初始化工作。就像我说的那样,onViewCreated具有您在onCreateView内部展开的View作为参数。这样您就可以避免getView打来电话
Blackbelt 2014年

8

onCreateView()onCreate()Activity 的Fragment等效项,并 View创建期间运行。创建视图
onViewCreated()运行。

should I use one over the other for performance? NO。没有证据表明性能会提高。

实际上onCreate(),Fragments中也有一种方法,但是很少使用(我从不使用它,也没有找到一个好的用例)。

我总是用onCreateView()Fragments代替onCreate()
我对此感到满意。


2
@npace,为什么?我也认为onCreateView这与Activity的等效onCreate
CoolMind

2
@CoolMind好吧,nPace并不是完全错误的,因为onCreate()Framents中也有一种方法。但是它从未被使用过(或者至少我从未使用过)。我总是用onCreateView()Fragments作为替换。
Phantômaxx

1
@Rotwang,同意你的观点!一些教程使用onCreate来放置setHasOptionsMenu(true),但我认为最好在onCreateView或onViewCreated中进行。
CoolMind

1
@CoolMind我完全同意。也许我在回答中使用了错误的单词。
Phantômaxx

1
@罗旺,你说的没错。第一次使用片段时,我也不知道为什么不使用onCreate。
CoolMind

4

Fragment.onCreateView()现在的文档说:

建议仅在此方法中膨胀布局,并将对返回的View进行操作的逻辑移动到onViewCreated(View,Bundle)。

无需我们了解原因;我们只需要按照文档所述进行操作,但是了解为什么存在此建议将很有趣。我最好的猜测是关注分离,但是恕我直言,这使它比必须的要复杂一些。


如果原因是关注点分离,那么Activity为什么要在setContentView()in中扩大其布局onCreate()
MinhNghĩa

@MinhNghĩa好点。这些问题的答案可能仅仅是因为它是由不同的程序员设计的,他们的想法有所不同(碎片是在我们首次使用Android几年后才引入的),但谁知道呢。
Peppe LG

2

我要使用的主要原因onViewCreated是因为它将所有初始化逻辑与应放入的视图层次结构膨胀/创建逻辑分开onViewCreate。所有其他性能特征都相同。


2

我认为这之间的主要区别是,当您每次要在xml文件中访问视图时,在onCreateView()中使用kotlin.in时,都应使用findViewById,但在onViewCreated中,只需调用其ID即可访问视图。


这是真的吗?如果我只是以两种方式在代码中使用id,则视图的null。我需要始终使用findViewById。
Jim Leask '18

1
不,不是.. oncreate视图实例化视图,在oncreateview之后和恢复保存的状态之前调用onviewcreated ...这更是片段生命周期中的时间问题
me_

1

onCreateView在片段中用于创建布局和扩大视图。onViewCreated用于引用上述方法创建的视图。最后,在onActivityCreated中定义动作侦听器是一个好习惯。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.