未调用Android DialogFragment onViewCreated

时间:2012-05-15 06:05:59

标签: android android-support-library android-dialogfragment

我正在使用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未被记录。

6 个答案:

答案 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中执行的操作也应该如此。