Android DialogFragment onViewCreated не вызывается
Я использую библиотеку совместимости 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 не регистрируется.
Ответы
Ответ 1
Ну, документы для состояния onViewCreated "Вызывается сразу после onCreateView (LayoutInflater, ViewGroup, Bundle)".
DialogFragment использует onCreateDialog, а не onCreateView, поэтому onViewCreated не запускается. (Будет моей рабочей теорией, я не нырнул в источник андроида, чтобы подтвердить).
Ответ 2
Из моего тестирования onViewCreated
не вызывается, если onCreateView возвращает null, что является поведением по умолчанию, поэтому, если вы не используете onCreateView, а вручную вызываете setContentView
в onCreateDialog
, вы можете вручную вызвать onViewCreated
from 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"
Ответ 3
Вы можете увидеть, что происходит из исходного кода:
Во-первых, поскольку вы не переопределяете onCreateView()
, ваш фрагмент будет пустым. Это видно из исходного кода Fragment
- по умолчанию возвращается null
:
// android.support.v4.app.Fragment.java
@Nullable
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return null;
}
Во-вторых, так как вы просматриваете ноль, FragmentManager
не будет вызывать onViewCreated()
. Из исходного кода 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;
}
Ответ 4
В соответствии с документом (Выбор между диалогом или вложением) и его самотестированием вы можете переопределить 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;
}
Ответ 5
Вот как я должен убедиться, что onViewCreated вызывается в kotlin:
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 now called!
}
override fun onDestroyView() {
dialogView = null
super.onDestroyView()
}
}