Android 官方推荐 : DialogFragment 创建对话框
DialogFragment有两种实现方式,我采用的是实现onCreateDialog方法,但是在使用的过程中发现onViewCreated方法并没有被回调(我在该方法中开启子线程获取需要展示的数据)。
/**
* Called immediately after {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}
* has returned, but before any saved state has been restored in to the view.
* This gives subclasses a chance to initialize themselves once
* they know their view hierarchy has been completely created. The fragment's
* view hierarchy is not however attached to its parent at this point.
* @param view The View returned by {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}.
* @param savedInstanceState If non-null, this fragment is being re-constructed
* from a previous saved state as given here.
*/
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
}
根据方法的介绍我们知道onViewCreated应该是在onCreateView执行之后会被调用的,但是其实这里是有一个前提的,即onCreateView返回的view不为 null,这里的逻辑可以在FragmentManager中找到:
f.mView = f.performCreateView(f.performGetLayoutInflater(
f.mSavedFragmentState), container, f.mSavedFragmentState);
if (f.mView != null) {
f.mInnerView = f.mView;
f.mView.setSaveFromParentEnabled(false);
if (container != null) {
container.addView(f.mView);
}
if (f.mHidden) {
f.mView.setVisibility(View.GONE);
}
f.onViewCreated(f.mView, f.mSavedFragmentState);
dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState, false);
// Only animate the view if it is visible. This is done after
// dispatchOnFragmentViewCreated in case visibility is changed
f.mIsNewlyAdded = (f.mView.getVisibility() == View.VISIBLE) && f.mContainer != null;
}
performCreateView方法只会调用onCreateView,这里返回的view也即是onCreateView返回的view,可以看到只有不为null的时候才会继续执行 f.onViewCreated(f.mView, f.mSavedFragmentState); 而onCreateView方法默认是返回null:
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return null;
}
这也是为什么我的DialogFragment的onViewCreated不执行的原因。如果用重写onCreateView创建Dialog的方式就不会出现这种情况。
那有没有用onCreateDialog也能执行onViewCreated方法的办法呢?当然有!就是自己调用:
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Timber.i("onCreateDialog");
AlertDialog dialog = new AlertDialog.Builder(getContext())
.setMessage("this is a dialog form onCreateDialog")
.create();
onViewCreated(dialog.findViewById(R.id.fl_root), savedInstanceState);
return dialog;
}
还有一种方法,同时复写onCreateDialog以及onCreateView,这样onCreateView返回的view不为null,接着也会触发onViewCreated方法。并且同时实现时展示的是onCreateDialog返回的dialog。