Подтвердить что ты не робот

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 не регистрируется.

4b9b3361

Ответ 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()
    }
}