带有自定义布局的DialogFragment会导致应用程序崩溃

我有Dialog片段的问题。 简单的对话框与我的自定义布局工作正常。 但是我想在显示对话框时启动控件。 我试图在onActivityCreated方法中做到这一点。 但getView()返回null,所以我认为我必须在onCreateView而不是onCreateDialog设置我的自定义视图。 这里发生错误。 当我使用onCreateView然后我的应用程序崩溃。 这是我的代码:

 class StatisticDialog extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // Use the Builder class for convenient dialog construction AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder .setPositiveButton(getString(android.R.string.ok), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // FIRE ZE MISSILES! } }); // Create the AlertDialog object and return it return builder.create(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.statistics, container, true); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); } } 

我点击活动button打开这个对话框:

 StatisticDialog dlg = new StatisticDialog(); dlg.show(getSupportFragmentManager(), "missiles"); 

和错误:

 11-08 18:05:14.470: E/AndroidRuntime(1075): FATAL EXCEPTION: main 11-08 18:05:14.470: E/AndroidRuntime(1075): android.util.AndroidRuntimeException: requestFeature() must be called before adding content 11-08 18:05:14.470: E/AndroidRuntime(1075): at com.android.internal.policy.impl.PhoneWindow.requestFeature(PhoneWindow.java:215) 11-08 18:05:14.470: E/AndroidRuntime(1075): at com.android.internal.app.AlertController.installContent(AlertController.java:234) 11-08 18:05:14.470: E/AndroidRuntime(1075): at android.app.AlertDialog.onCreate(AlertDialog.java:336) 11-08 18:05:14.470: E/AndroidRuntime(1075): at android.app.Dialog.dispatchOnCreate(Dialog.java:351) 11-08 18:05:14.470: E/AndroidRuntime(1075): at android.app.Dialog.show(Dialog.java:256) 11-08 18:05:14.470: E/AndroidRuntime(1075): at android.support.v4.app.DialogFragment.onStart(DialogFragment.java:385) 11-08 18:05:14.470: E/AndroidRuntime(1075): at android.support.v4.app.Fragment.performStart(Fragment.java:1336) 11-08 18:05:14.470: E/AndroidRuntime(1075): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:907) 11-08 18:05:14.470: E/AndroidRuntime(1075): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1083) 11-08 18:05:14.470: E/AndroidRuntime(1075): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:635) 11-08 18:05:14.470: E/AndroidRuntime(1075): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1431) 11-08 18:05:14.470: E/AndroidRuntime(1075): at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:420) 11-08 18:05:14.470: E/AndroidRuntime(1075): at android.os.Handler.handleCallback(Handler.java:615) 11-08 18:05:14.470: E/AndroidRuntime(1075): at android.os.Handler.dispatchMessage(Handler.java:92) 11-08 18:05:14.470: E/AndroidRuntime(1075): at android.os.Looper.loop(Looper.java:137) 11-08 18:05:14.470: E/AndroidRuntime(1075): at android.app.ActivityThread.main(ActivityThread.java:4745) 11-08 18:05:14.470: E/AndroidRuntime(1075): at java.lang.reflect.Method.invokeNative(Native Method) 11-08 18:05:14.470: E/AndroidRuntime(1075): at java.lang.reflect.Method.invoke(Method.java:511) 11-08 18:05:14.470: E/AndroidRuntime(1075): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 11-08 18:05:14.470: E/AndroidRuntime(1075): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 11-08 18:05:14.470: E/AndroidRuntime(1075): at dalvik.system.NativeStart.main(Native Method) 

Solutions Collecting From Web of "带有自定义布局的DialogFragment会导致应用程序崩溃"

尝试这个:

 class StatisticDialog extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // Use the Builder class for convenient dialog construction AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); LayoutInflater inflater = getActivity().getLayoutInflater(); View view = inflater.inflate(R.layout.statistics, null); builder.setView(view); builder.setPositiveButton(getString(android.R.string.ok), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // FIRE ZE MISSILES! } }); // Create the AlertDialog object and return it return builder.create(); } } 

避免请求function崩溃:

公共类MyCombinedFragment扩展DialogFragment {私人布尔isModal = false;

 public static MyCombinedFragment newInstance() { MyCombinedFragment frag = new MyCombinedFragment(); frag.isModal = true; // WHEN FRAGMENT IS CALLED AS A DIALOG SET FLAG return frag; } public MyCombinedFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if(isModal) // AVOID REQUEST FEATURE CRASH { return super.onCreateView(inflater, container, savedInstanceState); } else { View view = inflater.inflate(R.layout.fragment_layout, container, false); setupUI(view); return view; } } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder alertDialogBuilder = null; alertDialogBuilder = new AlertDialog.Builder(getActivity()); View view = getActivity().getLayoutInflater().inflate(R.layout.fragment_layout, null); alertDialogBuilder.setView(view); alertDialogBuilder.setTitle(“Modal Dialog“); alertDialogBuilder.setPositiveButton("Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); setupUI(view); return alertDialogBuilder.create(); } 

}

DialogFragment类中存在getShowDialog()方法。 这里是一个解释: developer.android.com

  if (!getShowsDialog()) { View rootView = inflater.inflate(R.layout.fr_layout, container, false); initViews(rootView); return rootView; } else { return super.onCreateView(inflater, container, savedInstanceState); } } 

你应该使用灵活的DialogFragment来设置任何布局。 你应该按照这个步骤。 也许它是复杂的,但非常强大和灵活。 更重要的是你的Activity从Dialogfragment获取date。

1-创build一个实例类来监听并从你的activity中获取你的dialogfragment的date。我把它命名为OnMFDialogFragmentDoneListener.java。

2 – 创buildDialogFragment并在onCreateView方法中定义布局,3在活动中使用类和新方法

我创build一个DialogFragment获取用户名和密码的forms用户,并提供这个dateactivity.dialog片段包含一个textview,两个EditText和两个button(login和取消,但你可以使用任何东西。

第1步:OnMFDialogFragmentDoneListener.java

 public interface OnMFDialogFragmentDoneListener { public void onMFDialogFragmentDone(String tag,boolean cancelled, CharSequence username, CharSequence password); } 

onMFDialogFragmentDone的方法必须在DialogFragment类中定义,以便将信息发送给yor活动并在您的活动中获取信息(info =用户在DialogFragmetn中键入的date,如txt或其他)。

step2devise你的DialogFragment类。

  public class MFDialogFragment extends DialogFragment implements View.OnClickListener{ private EditText editTextusername,editTextpassword; public static MFDialogFragment newInstance(String title){ MFDialogFragment mfDialogFragment=new MFDialogFragment(); Bundle bundle =new Bundle(); bundle.putString("title",title); mfDialogFragment.setArguments(bundle); return mfDialogFragment; } @Override public void onAttach(Activity act){ try{ OnMFDialogFragmentDoneListener test= (OnMFDialogFragmentDoneListener) act; }catch (ClassCastException cce){ ////...activity !!!! not listen to me } super.onAttach(act); } @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); this.setCancelable(true); int style = DialogFragment.STYLE_NORMAL, theme = 0; setStyle(style, theme); } public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) { View v = inflater.inflate(R.layout.mfdialogfragmentlayout, container, false); TextView tvtitle = (TextView) v.findViewById(R.id.tv_dialogfragmentuserpass_title); tvtitle.setText(getArguments().getString("title")); editTextusername = (EditText) v.findViewById(R.id.et_dialogfragmentuserpass_username); editTextpassword = (EditText) v.findViewById(R.id.et_dialogfragmentuserpass_password); Button btnlogin = (Button) v.findViewById(R.id.btn_dialogfragmentuserpass_login); btnlogin.setOnClickListener(this); Button btncancel = (Button) v.findViewById(R.id.btn_dialogfragmentuserpass_cancel); btncancel.setOnClickListener(this); if(bundle!=null) { editTextpassword.setText(bundle.getCharSequence("SaveInstanceStatepassword")); editTextusername.setText(bundle.getCharSequence("SaveInstanceStateusername")); } return v; } @Override public void onSaveInstanceState(Bundle icicle) { super.onSaveInstanceState(icicle); icicle.putCharSequence("SaveInstanceStatepassword", editTextpassword.getText()); icicle.putCharSequence("SaveInstanceStateusername", editTextusername.getText()); } public void onClick(View v) { OnMFDialogFragmentDoneListener act = (OnMFDialogFragmentDoneListener)getActivity(); if (v.getId() == R.id.btn_dialogfragmentuserpass_login) { act.onMFDialogFragmentDone(this.getTag(), false, editTextusername.getText(),editTextpassword.getText()); dismiss(); return; } if (v.getId() == R.id.btn_dialogfragmentuserpass_cancel) { act.onMFDialogFragmentDone(this.getTag(), true, "nousername", "nopass"); dismiss(); return; } } } 

第3步 – 在您的活动中使用您的DialogFragment,首先将代码“implements OnMFDialogFragmentDoneListener”添加到您的活动类,如

 public class MainActivity extends Activity implements OnMFDialogFragmentDoneListener 

第二

 public static final String PROMPT_MFDIALOGFRAGMENT_TAG="PROMPT_MFDIALOGFRAGMENT_TAG"; 

第三

定义获取input到Dialogfragment的数据的方法

 public void onMFDialogFragmentDone(String tag, boolean cancelled, CharSequence username, CharSequence password){ String total; total=username.toString()+"...."+password.toString(); Toast.makeText(this,total,Toast.LengthShort).show(); } 

你的date是用户名和密码接下来是定义一个简单的方法来调用你的对话框

 public void MFDialogFragmentShow(){ FragmentTransaction ft = getFragmentManager().beginTransaction(); MFDialogFragment mfDialogFragment = MFDialogFragment.newInstance("Login to your account"); mfDialogFragment.show(ft, PROMPT_MFDIALOGFRAGMENT_TAG); } 

完成。 你的frgaments布局mfdialogfragmentlayout.xml

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Title" android:id="@+id/tv_dialogfragmentuserpass_title"/> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:hint="User Name" android:id="@+id/et_dialogfragmentuserpass_username"/> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:hint="Password" android:password="true" android:id="@+id/et_dialogfragmentuserpass_password"/> <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Login" android:id="@+id/btn_dialogfragmentuserpass_login"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Cancel" android:id="@+id/btn_dialogfragmentuserpass_cancel"/> </LinearLayout> </LinearLayout>