为什么我必须在onCreateView中返回一个视图而不是直接设置视图?

时间:2015-11-29 22:04:04

标签: java android android-fragments

我对方法有点迷惑

public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState).

1)我不太确定为什么片段必须使用此代码才能将其与视图或xml文件链接。

2)为什么我不能直接在片段中调用setContentView()而不是通过onCreateView()方法并返回一个视图对象。

3)此返回View中的哪个方法或对象作为参数?

2 个答案:

答案 0 :(得分:4)

  

1)我不太确定为什么片段必须使用此代码   将它与视图或xml文件链接。

此代码将返回一个视图,用于在布局上显示所需内容。 Fragment具有此方法,但您可以根据需要使用自己的布局,容器和包覆盖。你怎么覆盖它?你在方法中返回的内容。

View v = inflater.inflate(R.layout.somelayout, container, false)
  

2)为什么我不能直接在片段中调用setContentView()而不是   通过onCreateView()方法并返回一个视图对象。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_crime);
    FragmentManager fm = getSupportFragmentManager();
}

另一个原因是因为onCreate in activity必须受到保护,而onCreateView是公共的,因为片段需要相互通信。即

,因为onCreate受到保护,所以你不能在多个片段上使用setContentView。

  

3)返回View作为参数的方法或对象是什么?

片段的生命周期由FragmentManager控制, Lifecycle of a Fragment

将片段添加到堆栈时,FragmentManager会调用其视图,以查看屏幕上需要放置的内容。

答案 1 :(得分:0)

嗯,根据我能猜出的代码,

FragmentActivity:

final FragmentController mFragments = FragmentController.createController(new HostCallbacks());

@Override
final View dispatchFragmentsOnCreateView(View parent, String name, Context context,
        AttributeSet attrs) {
    return mFragments.onCreateView(parent, name, context, attrs);
}

FragmentController:

public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
    return mHost.mFragmentManager.onCreateView(parent, name, context, attrs);
}

FragmentManagerImpl:

final class FragmentManagerImpl extends FragmentManager implements LayoutInflaterFactory {
//[...]
void moveToState(Fragment f, int newState, int transit, int transitionStyle,
        boolean keepActive) {
     //[...]
            if (f.mFromLayout) {
                    // For fragments that are part of the content view
                    // layout, we need to instantiate the view immediately
                    // and the inflater will take care of adding it.
                    f.mView = f.performCreateView(f.getLayoutInflater(
                            f.mSavedFragmentState), null, f.mSavedFragmentState);
                    if (f.mView != null) {
                        f.mInnerView = f.mView;
                        if (Build.VERSION.SDK_INT >= 11) {
                            ViewCompat.setSaveFromParentEnabled(f.mView, false);
                        } else {
                            f.mView = NoSaveStateFrameLayout.wrap(f.mView);
                        }
                        if (f.mHidden) f.mView.setVisibility(View.GONE);
                        f.onViewCreated(f.mView, f.mSavedFragmentState);
                    } else {
                        f.mInnerView = null;
                    }
                }
               //[...]
                   if (!f.mFromLayout) {
                        ViewGroup container = null;
                        if (f.mContainerId != 0) {
                            container = (ViewGroup)mContainer.onFindViewById(f.mContainerId);
                            if (container == null && !f.mRestored) {
                                throwException(new IllegalArgumentException(
                                        "No view found for id 0x"
                                        + Integer.toHexString(f.mContainerId) + " ("
                                        + f.getResources().getResourceName(f.mContainerId)
                                        + ") for fragment " + f));
                            }
                        }
                        f.mContainer = container;
                        f.mView = f.performCreateView(f.getLayoutInflater(
                                f.mSavedFragmentState), container, f.mSavedFragmentState);
                        if (f.mView != null) {
                            f.mInnerView = f.mView;
                            if (Build.VERSION.SDK_INT >= 11) {
                                ViewCompat.setSaveFromParentEnabled(f.mView, false);
                            } else {
                                f.mView = NoSaveStateFrameLayout.wrap(f.mView);
                            }
                            if (container != null) {
                                Animation anim = loadAnimation(f, transit, true,
                                        transitionStyle);
                                if (anim != null) {
                                    setHWLayerAnimListenerIfAlpha(f.mView, anim);
                                    f.mView.startAnimation(anim);
                                }
                                container.addView(f.mView);
                            }
                            if (f.mHidden) f.mView.setVisibility(View.GONE);
                            f.onViewCreated(f.mView, f.mSavedFragmentState);
                        } else {
                            f.mInnerView = null;
                        }
                    }

                    f.performActivityCreated(f.mSavedFragmentState);
                    if (f.mView != null) {
                        f.restoreViewState(f.mSavedFragmentState);
                    }
                    f.mSavedFragmentState = null;
       ...

void saveFragmentViewState(Fragment f) {
    if (f.mInnerView == null) {
        return;
    }
    if (mStateArray == null) {
        mStateArray = new SparseArray<Parcelable>();
    } else {
        mStateArray.clear();
    }
    f.mInnerView.saveHierarchyState(mStateArray);
    if (mStateArray.size() > 0) {
        f.mSavedViewState = mStateArray;
        mStateArray = null;
    }
}

我们只是说片段管理器需要直接查看视图才能管理片段的内部状态。碎片令人困惑,所以我还没有确定地解决它。