我正在使用android兼容性库(v4修订版8)。在自定义DialogFragment中,没有调用onViewCreated的覆盖方法。例如。
public class MyDialogFragment extends DialogFragment{
private String mMessage;
public MyDialogFragment(String message) {
mMessage = message;
}
@Override
public Dialog onCreateDialog( Bundle savedInstanceState){
super.onCreateDialog(savedInstanceState);
Log.d("TAG", "onCreateDialog");
setRetainInstance(true);
//....do something
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
Log.d("TAG", "onViewCreated");
//...do something
}
}
onViewCreated未被记录。
答案 0 :(得分:16)
嗯,onViewCreated状态的文档"在onCreateView(LayoutInflater,ViewGroup,Bundle)之后立即调用"。
DialogFragment使用onCreateDialog而不是onCreateView,因此不会触发onViewCreated。 (这将是我的工作理论,我没有潜入android源来确认)。
答案 1 :(得分:8)
根据我的测试,如果onCreateView返回null(这是默认行为),则不会调用onViewCreated
,因此如果您不使用onCreateView而是在setContentView
中手动调用onCreateDialog
,您可以从onViewCreated
手动拨打onCreateDialog
:
@Override public Dialog onCreateDialog(Bundle savedInstanceState) {
final Dialog d = super.onCreateDialog(savedInstanceState);
d.setContentView(R.layout.my_dialog);
// ... do stuff....
onViewCreated(d.findViewById(R.id.dialog_content), savedInstanceState);
return d;
}
在这种情况下,请确保my_dialog.xml
中的根元素具有android:id="@+id/dialog_content"
答案 2 :(得分:5)
您可以从源代码中看到发生了什么:
首先,由于您不会覆盖onCreateView()
,因此您的片段视图将为空。这可以从source code of Fragment
- 默认返回null
:
// android.support.v4.app.Fragment.java
@Nullable
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return null;
}
其次,由于您的查看为空,FragmentManager
将不会调用onViewCreated()
。来自source code of FragmentManager
:
// android.support.v4.app.FragmentManager.java
if (f.mView != null) {
f.mInnerView = f.mView;
// ...
// only called if the fragments view is not null!
f.onViewCreated(f.mView, f.mSavedFragmentState);
} else {
f.mInnerView = null;
}
答案 3 :(得分:2)
根据文档(Selecting Between Dialog or Embedding)并自行测试,您可以覆盖OnCreateView,使用自定义布局对其进行充气并将其返回。将启动OnViewCreated
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.custom_layout, null);
//do whatever
return view;
}
答案 4 :(得分:2)
这是我确保在kotlin中调用onViewCreated的方式:
class MyDialog: DialogFragment() {
private lateinit var dialogView: View
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
dialogView = LayoutInflater.from(context).inflate(R.layout.dialog, null)
val dialog = MaterialAlertDialogBuilder(context!!)
.setView(dialogView)
.create()
return dialog
}
// Need to return the view here or onViewCreated won't be called by DialogFragment, sigh
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return dialogView
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// Yay it's now called!
}
override fun onDestroyView() {
dialogView = null
super.onDestroyView()
}
}
答案 5 :(得分:0)
该文档指出,将在onCreateView(DialogFragment文档)之前调用onCreateDialog,并在onActivityCreated(Fragment文档)之前调用onCreateView。 因此,这将是呼叫流程:
onCreate
onCreateDialog
onCreateView
onActivityCreated
在onActivityCreated的OnViewCreated中执行的操作也应该如此。