我应该如何确保onCreate(视图/对话框)已经完成运行,以便所有内容都已正确初始化?

时间:2016-03-02 15:25:25

标签: java android

答案

答案/示例可以在本文的底部找到。达到此答案的方式可以在answer及其评论中找到。

原始问题

我有一个dialogFragment,它有两个editText输入字段。在特定按钮上,我希望创建此dialogFragment,并使用文本填充两个editText字段。为此,我在dialogFragment的类中创建了一个简单的方法。

public void presetFields(String nameField, String tagField) {
    nameInputField.setText(nameField);
    tagInputField.setText(tagField);
}

问题是nameInputFieldtagInputField都在onCreateDialog方法中初始化。

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    LayoutInflater inflater = getActivity().getLayoutInflater();
    final View v_iew = inflater.inflate(R.layout.fragment_inputdialog, null);

    nameInputField = (EditText) v_iew.findViewById(R.id.inputdialogname);
    tagInputField = (EditText) v_iew.findViewById(R.id.inputdialogtag);
}

我认为这根本不是问题,因为我有一个类似的构造运行片段。唯一的区别是,editText的初始化位于onCreateView而不是onCreateDialog

这是显示onClick的{​​{1}}代码,并调用该方法来设置dialogFragmentnameInputField字段。

tagInputField

当我点击editButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { stuffManagerInputDialogFragment.show(getFragmentManager(), "TEST"); stuffManagerInputDialogFragment.presetFields(nameTextViewContent, tagTextViewContent); } }); 时,这是我通过NPE获得的日志

editButton

到目前为止,我还不是专家,但我对此错误的看法是03-02 16:04:25.120 509-509/com.example.tim.timapp I/art: Not late-enabling -Xcheck:jni (already on) 03-02 16:04:25.190 509-509/com.example.tim.timapp W/System: ClassLoader referenced unknown path: /data/app/com.example.tim.timapp-2/lib/x86_64 03-02 16:04:25.400 509-524/com.example.tim.timapp D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true 03-02 16:04:25.520 509-524/com.example.tim.timapp I/OpenGLRenderer: Initialized EGL, version 1.4 03-02 16:04:25.570 509-524/com.example.tim.timapp W/EGL_emulation: eglSurfaceAttrib not implemented 03-02 16:04:25.570 509-524/com.example.tim.timapp W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0x7fceb5b27dc0, error=EGL_SUCCESS 03-02 16:04:28.660 509-509/com.example.tim.timapp D/TEST: 2131493026 03-02 16:04:30.310 509-509/com.example.tim.timapp D/AndroidRuntime: Shutting down VM 03-02 16:04:30.310 509-509/com.example.tim.timapp E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.tim.timapp, PID: 509 java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.EditText.setText(java.lang.CharSequence)' on a null object reference at com.example.fragments.MainFragments.DialogFragments.StuffManagerInputDialogFragment.presetFields(StuffManagerInputDialogFragment.java:149) at com.example.fragments.MainFragments.VariableFragments.StuffManagerVariableFragment$2.onClick(StuffManagerVariableFragment.java:87) at android.view.View.performClick(View.java:5198) at android.view.View$PerformClick.run(View.java:21147) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 03-02 16:04:33.140 509-509/com.example.tim.timapp I/Process: Sending signal. PID: 509 SIG: 9 nameTextViewtagTextView目前我正试图设置文字对他们来说,这让我觉得在创建片段之前调用该方法。

在尝试调用某些内容之前,如何确保两个null都已正确初始化?

我删除了一些代码以便于阅读。如果似乎缺少某些东西,那可能就是。请让我知道,所以我可以加上它 如果您需要更多代码,请告知我们。

完整答案

所有积分都会转到此George Mulligan

所以有些东西已经改变了原来的方法。首先,editText方法已被删除。应该填充presetFields字段的文本现在作为参数传递给片段。

editText方法现在看起来像这样:

onClick

因此,如果没有editButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { nameTextViewContent = nameTextView.getText().toString(); tagTextViewContent = tagTextView.getText().toString(); Bundle args = new Bundle(); args.putString("name", nameTextViewContent); args.putString("tag", tagTextViewContent); stuffManagerInputDialogFragment.setArguments(args); stuffManagerInputDialogFragment.show(getFragmentManager(), "TEST"); } }); 方法,我们无法将presetFields字段设置为我们想要的文本。这已添加到editText方法中,如下所示。

onCreateDialog

已添加@Override public Dialog onCreateDialog(Bundle savedInstanceState) { LayoutInflater inflater = getActivity().getLayoutInflater(); final View v_iew = inflater.inflate(R.layout.fragment_inputdialog, null); nameInputField = (EditText) v_iew.findViewById(R.id.inputdialogname); tagInputField = (EditText) v_iew.findViewById(R.id.inputdialogtag); if (getArguments() != null) { nameInputField.setText(getArguments().getString("name")); tagInputField.setText(getArguments().getString("tag")); } } 的空检查,因为我有时需要调用此getArguments()而不填写dialogFragment字段。发生这种情况时,意味着没有为片段设置参数,这会在调用editText时导致NPE

那应该是它。然而,我确实因为愚蠢而闻名,所以我很可能忽略了一些东西,这应该包括在这个解释中。如果是这样,请告诉我,所以我可以添加它。

2 个答案:

答案 0 :(得分:1)

  

我对这个错误的看法是nameTextView和tagTextView   在我试图为他们设置文本的那一刻,这是空的,这让我感到高兴   认为在创建片段之前调用该方法。

这几乎是正确的。 Fragment已创建但onCreateDialog()尚未调用,因为在调用show(...)后显示对话框异步发生。

您可以通过将arguments的两个预设字符串添加到DialogFragment来解决此问题。

然后,您可以使用EditText上的onCreateDialog直接在getArguments()方法中为DialogFragment字段指定正确的值。

这是这样的:

public MyDialogFragment extends DialogFragment {
    private static final String ARG_NAME = "name";
    private static final String ARG_TAG = "tag";
    public MyDialogFragment newInstance(String name, String tag) {
        Bundle args = new Bundle();
        args.putString(ARG_NAME, name);
        args.putString(ARG_TAG, tag);

        MyDialogFragment frag = new MyDialogFragment();
        frag.setArguments(args);
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        LayoutInflater inflater = getActivity().getLayoutInflater();
        final View v_iew = inflater.inflate(R.layout.fragment_inputdialog, null);

        nameInputField = (EditText) v_iew.findViewById(R.id.inputdialogname);
        tagInputField = (EditText) v_iew.findViewById(R.id.inputdialogtag);

        nameInputField.setText(getArguments().getString(ARG_NAME, ""));
        tagInputField.setText(getArguments().getString(ARG_TAG, ""));
    }
}

然后是新的点击事件处理程序。

editButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        stuffManagerInputDialogFragment = MyDialogFragment
             .newInstance(nameTextViewContent, tagTextViewContent);

        stuffManagerInputDialogFragment.show(getFragmentManager(), "TEST");
    }
});

答案 1 :(得分:0)

请勿在调用show后立即操作对话框。

如果要为对话框中的字段设置默认值,请将它们作为参数传递给对话框,并在对话框创建期间初始化它们。

e.g

cChart.ChartGroups(1).SeriesCollection.Item(CVar(sSeriesName))

来自:http://www.androiddesignpatterns.com/2012/05/using-newinstance-to-instantiate.html