【问题标题】:Create Custom AlertDialog requestFeature exception [duplicate]创建自定义 AlertDialog requestFeature 异常 [重复]
【发布时间】:2015-01-23 13:09:08
【问题描述】:

我正在尝试在 DialogFragment 中为一个简单的闹钟应用程序创建自己的自定义 AlertDialog,onCreateDialog 方法的代码如下。

public class CreateAlarmSetting extends DialogFragment implements View.OnClickListener, AlertDialog.OnClickListener, TimePicker.OnTimeChangedListener, NumberPicker.OnValueChangeListener {

    /*
    the isEdit variable is set to true when an existing alarm time is clicked, this will add the
    "delete" button to the dialog, to possibly delete the item from the listview
     */
    private boolean isEdit = false;
    public static final String ISEDIT_PARAM = "isEdit";
    public static final String ALARMSETTING_PARAM = "AlarmSetting";
    public AlarmSetting alarmSetting;

    private TimePicker timePicker;
    private NumberPicker numberPicker;
    //private Button cancelButton, createButton, deleteButton;
    //View of the dialog layout that will be inflated
    private View main;
    private OnFragmentInteractionListener mListener;

    public CreateAlarmSetting() {

    }

    /*
    Below are a few of the Fragment lifecycle methods
     */

    public void setArguments(Bundle bundle) {
        isEdit = bundle.getBoolean(ISEDIT_PARAM);
        alarmSetting = (AlarmSetting) bundle.get(ALARMSETTING_PARAM);

    }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        getActivity().requestWindowFeature(Window.FEATURE_ACTION_BAR);
        super.onCreate(savedInstanceState);
        /*
        Not doing anything yet, because findViewById() doesn't work at this point in the lifecycle
         */

    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        //    TODO: check if this is to edit a current alarmSetting and add the save button and delete button


        main = inflater.inflate(R.layout.fragment_create_alarm_setting, null);
        //Initialize views and their listeners
        timePicker = (TimePicker) main.findViewById(R.id.alarm_fragment_dialog_timepicker);
        numberPicker = (NumberPicker) main.findViewById(R.id.alarm_fragment_dialog_numberpicker);
        //    cancelButton = (Button)  main.findViewById(R.id.alarm_fragment_dialog_cancel_button);
        //  createButton = (Button)  main.findViewById(R.id.alarm_fragment_dialog_create_button);
        timePicker.setOnTimeChangedListener(this);
        numberPicker.setOnValueChangedListener(this);
        //cancelButton.setOnClickListener(this);
        //createButton.setOnClickListener(this);
        numberPicker.setMaxValue(45);
        numberPicker.setMinValue(0);
        //create display based on given parameters
  /*
        if (isEdit) {
         //   ViewGroup parent= (ViewGroup) main.findViewById(R.id.alarm_fragment_dialog_button_container);
            deleteButton= (Button) main.findViewById(R.id.alarm_fragment_dialog_delete_button);
            deleteButton.setText("Delete");
            deleteButton.getLayoutParams().height= LinearLayout.LayoutParams.WRAP_CONTENT;
            deleteButton.getLayoutParams().width= LinearLayout.LayoutParams.WRAP_CONTENT;
            deleteButton.setOnClickListener(this);
            createButton.setText("Save");

//TODO: Set Display Settings to current alarm settings, includes having cancel, delete, save buttons
            timePicker.setCurrentHour(alarmSetting.getHours());
            timePicker.setCurrentMinute(alarmSetting.getMinutes());



            //Replace create button with the save add the delete button
            ViewGroup parent= (ViewGroup) main.findViewById(R.id.alarm_fragment_dialog_button_container);
            ViewGroup v=(ViewGroup) edit.findViewById(R.id.miscellaneous_items_container);
            //v.removeView(edit.findViewById(R.id.alarm_fragment_dialog_delete_button));
            parent.addView(edit.findViewById(R.id.alarm_fragment_dialog_delete_button), 1);
            //Replace create button with save button
            parent = (ViewGroup) createButton.getParent();
            int index = parent.indexOfChild(createButton);
            parent.removeView(createButton);
            parent.addView(parent.findViewById(R.id.alarm_fragment_dialog_save_button), index);


        }*/

        return main;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
          super.onCreateDialog(savedInstanceState);
        if (main == null) {
            main = getActivity().getLayoutInflater().inflate(R.layout.fragment_create_alarm_setting, null);
        }

        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setView(main);
        builder.setNegativeButton("Cancel", this);
        builder.setPositiveButton("Create", this);
        builder.setTitle("Create a new Alarm Setting");
        AlertDialog alertDialog=builder.create();

        //show or create?
      return  alertDialog;


    }


    // TODO: Rename method, update argument and hook method into UI event
    public void onButtonPressed(Uri uri) {
        if (mListener != null) {
            mListener.onFragmentInteraction(uri);
        }
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnFragmentInteractionListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    /*
    Below are listeners for the actions in the dialog
     */
    @Override
    public void onClick(DialogInterface dialogInterface, int id) {
        switch (id) {
            case DialogInterface.BUTTON_NEGATIVE:


            case DialogInterface.BUTTON_NEUTRAL:


            case DialogInterface.BUTTON_POSITIVE:

        }


    }


    @Override
    public void onValueChange(NumberPicker picker, int val, int num) {
        //Do something

    }

    @Override
    public void onTimeChanged(TimePicker picker, int hours, int minutes) {
        if (alarmSetting != null) {
            alarmSetting.setHours(hours);
            alarmSetting.setMinutes(minutes);
        } else alarmSetting = new AlarmSetting(hours, minutes, false);


    }


    @Override
    public void onClick(View v) {
        //do stuff for each button
        switch (v.getId()) {


        }


    }

当我在模拟器中运行这段代码时,我收到一个异常提示

    01-22 20:32:39.489    1883-1883/com.stanfordude.ryan.snooze E/AndroidRuntime﹕ FATAL EXCEPTION: main
android.util.AndroidRuntimeException: requestFeature() must be called before adding content
        at com.android.internal.policy.impl.PhoneWindow.requestFeature(PhoneWindow.java:215)
        at com.android.internal.app.AlertController.installContent(AlertController.java:234)
        at android.app.AlertDialog.onCreate(AlertDialog.java:336)
        at android.app.Dialog.dispatchOnCreate(Dialog.java:351)
        at android.app.Dialog.show(Dialog.java:256)
        at android.app.DialogFragment.onStart(DialogFragment.java:490)
        at android.app.Fragment.performStart(Fragment.java:1570)
        at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:863)
        at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1035)
        at android.app.BackStackRecord.run(BackStackRecord.java:635)
        at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1397)
        at android.app.FragmentManagerImpl$1.run(FragmentManager.java:426)
        at android.os.Handler.handleCallback(Handler.java:615)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4745)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        at dalvik.system.NativeStart.main(Native Method)

我该如何解决这个问题?

顺便说一句,很抱歉我乱七八糟的代码和 cmets,我是 java 新手

【问题讨论】:

  • 添加完整代码和logcat

标签: java android exception android-dialogfragment


【解决方案1】:

它不是我从错误中看到的代码,它是 requestWindowsFeature 或您在顶部的 setContentView 之前调用的东西。您应该在设置 contentView 之前调用请求:

super.onCreate(savedInstanceState);
    // Hiding title bar using code
    requestWindowFeature(Window.FEATURE_NO_TITLE);

    // Hiding status bar using code
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setContentView(R.layout.activity_main);

【讨论】:

  • 在片段中,requestWindowFeature 方法只能通过 getActivity() 方法使用,该方法在生命周期的那个时刻返回 null。
  • 我们可以看到整个代码以便调试吗?
猜你喜欢
  • 2019-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多