2013-02-15 37 views
2
我似乎

不能建立我DateTimeDialogFragment,因为它使在这里我把一部分崩溃:日期+时间选择在DialogFragment实现OnDateChangedListener和OnTimeChangedListener

datePicker = (DatePicker) getView().findViewById(R.id.DatePicker); 

错误日志:

02-14 21:38:43.262: E/AndroidRuntime(2435): FATAL EXCEPTION: main 
02-14 21:38:43.262: E/AndroidRuntime(2435): java.lang.NullPointerException 
02-14 21:38:43.262: E/AndroidRuntime(2435):  at com.test.DateTimeDialogFragment.onActivityCreated(DateTimeDialogFragment.java:98) 
02-14 21:38:43.262: E/AndroidRuntime(2435):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:847) 
02-14 21:38:43.262: E/AndroidRuntime(2435):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1032) 
02-14 21:38:43.262: E/AndroidRuntime(2435):  at android.app.BackStackRecord.run(BackStackRecord.java:622) 
02-14 21:38:43.262: E/AndroidRuntime(2435):  at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1382) 
02-14 21:38:43.262: E/AndroidRuntime(2435):  at android.app.FragmentManagerImpl$1.run(FragmentManager.java:426) 
02-14 21:38:43.262: E/AndroidRuntime(2435):  at android.os.Handler.handleCallback(Handler.java:605) 
02-14 21:38:43.262: E/AndroidRuntime(2435):  at android.os.Handler.dispatchMessage(Handler.java:92) 
02-14 21:38:43.262: E/AndroidRuntime(2435):  at android.os.Looper.loop(Looper.java:137) 
02-14 21:38:43.262: E/AndroidRuntime(2435):  at android.app.ActivityThread.main(ActivityThread.java:4424) 
02-14 21:38:43.262: E/AndroidRuntime(2435):  at java.lang.reflect.Method.invokeNative(Native Method) 
02-14 21:38:43.262: E/AndroidRuntime(2435):  at java.lang.reflect.Method.invoke(Method.java:511) 
02-14 21:38:43.262: E/AndroidRuntime(2435):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 
02-14 21:38:43.262: E/AndroidRuntime(2435):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 
02-14 21:38:43.262: E/AndroidRuntime(2435):  at dalvik.system.NativeStart.main(Native Method) 

下面是完整的代码:

public class DateTimeDialogFragment extends DialogFragment implements 
     OnDateChangedListener, OnTimeChangedListener { 
    // Define constants for date-time picker. 
    public final int DATE_PICKER = 1; 
    public final int TIME_PICKER = 2; 
    public final int DATE_TIME_PICKER = 3; 

    // DatePicker reference 
    private DatePicker datePicker; 

    // TimePicker reference 
    private TimePicker timePicker; 

    // Calendar reference 
    private Calendar mCalendar; 

    // Define activity 
    private Activity activity; 

    // Define Dialog type 
    private int intDialogType; 

    // Constructor start 
    public DateTimeDialogFragment(Activity activity) { 
     this.activity = activity; 
    } 

    @Override 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 
     // Use the Builder class for convenient dialog construction 
     AlertDialog.Builder builder = new AlertDialog.Builder(activity); 

     // Get the layout inflater 
     LayoutInflater inflater = activity.getLayoutInflater(); 

     // Inflate and set the layout for the dialog 
     // Pass null as the parent view because its going in the dialog layout 
     builder.setView(inflater.inflate(R.layout.date_time_dialog, null)); 

     // Set title of dialog 
     builder.setMessage("Set Date") 
       // Set Ok button 
       .setPositiveButton("Set", 
         new DialogInterface.OnClickListener() { 
          public void onClick(DialogInterface dialog, int id) { 
           // User ok the dialog 
          } 
         }) 
       // Set Cancel button 
       .setNegativeButton("Cancel", 
         new DialogInterface.OnClickListener() { 
          public void onClick(DialogInterface dialog, int id) { 
           // User cancelled the dialog 
          } 
         }) 
       // Set Neutral button (reset Time/Date) 
       .setNeutralButton("Reset", 
         new DialogInterface.OnClickListener() { 
          @Override 
          public void onClick(DialogInterface dialog, int id) { 
           // User reset the dialog 
           // reset(); 
          } 
         }); 

     // Create the AlertDialog object and return it 
     return builder.create(); 
    } 

    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     // TODO Auto-generated method stub 
     super.onActivityCreated(savedInstanceState); 
     // Grab a Calendar instance 
     mCalendar = Calendar.getInstance(); 

     // Init date picker 
     datePicker = (DatePicker) getView().findViewById(R.id.DatePicker); 
     datePicker.init(mCalendar.get(Calendar.YEAR), mCalendar.get(Calendar.MONTH), mCalendar.get(Calendar.DAY_OF_MONTH), this); 

     // Init time picker 
     timePicker = (TimePicker) getView().findViewById(R.id.TimePicker); 
     timePicker.setOnTimeChangedListener(this); 
    } 

    public void setIntDialogType(int intDialogType) { 
     this.intDialogType = intDialogType; 
    } 

    // Convenience wrapper for internal Calendar instance 
    public int get(final int field) { 
     return mCalendar.get(field); 
    } 

    // Reset DatePicker, TimePicker and internal Calendar instance 
    public void reset() { 
     final Calendar c = Calendar.getInstance(); 
     updateDate(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH)); 
     updateTime(c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE)); 
    } 

    // Convenience wrapper for internal Calendar instance 
    public long getDateTimeMillis() { 
     return mCalendar.getTimeInMillis(); 
    } 

    // Convenience wrapper for internal TimePicker instance 
    public void setIs24HourView(boolean is24HourView) { 
     timePicker.setIs24HourView(is24HourView); 
    } 

    // Convenience wrapper for internal TimePicker instance 
    public boolean is24HourView() { 
     return timePicker.is24HourView(); 
    } 

    // Convenience wrapper for internal DatePicker instance 
    public void setCalendarViewShown(boolean calendarView) { 
     datePicker.setCalendarViewShown(calendarView); 
    } 

    // Convenience wrapper for internal DatePicker instance 
    public boolean CalendarViewShown() { 
     return datePicker.getCalendarViewShown(); 
    } 

    // Convenience wrapper for internal DatePicker instance 
    public void updateDate(int year, int monthOfYear, int dayOfMonth) { 
     datePicker.updateDate(year, monthOfYear, dayOfMonth); 
    } 

    // Convenience wrapper for internal TimePicker instance 
    public void updateTime(int currentHour, int currentMinute) { 
     timePicker.setCurrentHour(currentHour); 
     timePicker.setCurrentMinute(currentMinute); 
    } 

    public String getDateTime() { 
     SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US); 
     return sdf.format(mCalendar.getTime()); 
    } 

    // Called every time the user changes DatePicker values 
    @Override 
    public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) { 
     // Update the internal Calendar instance 
     mCalendar.set(year, monthOfYear, dayOfMonth, mCalendar.get(Calendar.HOUR_OF_DAY), mCalendar.get(Calendar.MINUTE)); 
    } 

    // Called every time the user changes TimePicker values 
    @Override 
    public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { 
     // Update the internal Calendar instance 
     mCalendar.set(mCalendar.get(Calendar.YEAR), mCalendar.get(Calendar.MONTH), mCalendar.get(Calendar.DAY_OF_MONTH), hourOfDay, minute); 
    } 

这里的date_time_dialog.xml:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/DateTimePicker" 
    android:layout_width="wrap_content" 
    android:layout_height="fill_parent" 
    android:gravity="center" 
    android:orientation="horizontal" 
    android:padding="5dip" > 

    <DatePicker 
     android:id="@+id/DatePicker" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center" 
     android:layout_marginRight="40dp" /> 

    <TimePicker 
     android:id="@+id/TimePicker" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center" /> 

</LinearLayout> 
+0

什么,我有点困惑,是我如何从我在“builder.setView”这样我可以访问使用的布局访问他R.id.DatePicker timePicker和datePicker。我试图清理项目,但我仍然得到同样的错误。出于某种原因,在执行上面提到的这一行之后,datePicker对象仍然为空 – user1848850 2013-02-15 05:06:37

+1

尝试使用getDialog()来代替'getView()'。 – 2013-02-15 05:08:20

+0

同样的事情,空指针参考,它找不到R.id。DatePicker我不知道我是不是应该在onActivityCreated方法中做到这一点。我很困惑 – user1848850 2013-02-15 05:18:44

回答

5

我想说,感谢大家帮助我,让我走向正确的方向。我现在对Android有了更好的理解。下面是完整的工人阶级:

import java.text.SimpleDateFormat; 
import java.util.Calendar; 
import java.util.Locale; 

import android.app.Activity; 
import android.app.AlertDialog; 
import android.app.AlertDialog.Builder; 
import android.app.Dialog; 
import android.app.DialogFragment; 
import android.content.DialogInterface; 
import android.os.Bundle; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.widget.DatePicker; 
import android.widget.DatePicker.OnDateChangedListener; 
import android.widget.TimePicker; 
import android.widget.TimePicker.OnTimeChangedListener; 

public class DateTimeDialogFragment extends DialogFragment implements OnDateChangedListener, OnTimeChangedListener { 
    // Define constants for date-time picker. 
    public final static int DATE_PICKER = 1; 
    public final static int TIME_PICKER = 2; 
    public final static int DATE_TIME_PICKER = 3; 

    // DatePicker reference 
    private DatePicker datePicker; 

    // TimePicker reference 
    private TimePicker timePicker; 

    // Calendar reference 
    private Calendar mCalendar; 

    // Define activity 
    private Activity activity; 

    // Define Dialog type 
    private int DialogType; 

    // Define Dialog view 
    private View mView; 

    // Constructor start 
    public DateTimeDialogFragment(Activity activity) { 
     this(activity, DATE_TIME_PICKER); 
    } 

    public DateTimeDialogFragment(Activity activity, int DialogType) { 
     this.activity = activity; 
     this.DialogType = DialogType; 

     // Inflate layout for the view 
     // Pass null as the parent view because its going in the dialog layout 
     LayoutInflater inflater = activity.getLayoutInflater(); 
     mView = inflater.inflate(R.layout.date_time_dialog, null); 

     // Grab a Calendar instance 
     mCalendar = Calendar.getInstance(); 

     // Init date picker 
     datePicker = (DatePicker) mView.findViewById(R.id.DatePicker); 
     datePicker.init(mCalendar.get(Calendar.YEAR), mCalendar.get(Calendar.MONTH), mCalendar.get(Calendar.DAY_OF_MONTH), this); 

     // Init time picker 
     timePicker = (TimePicker) mView.findViewById(R.id.TimePicker); 

     // Set default Calendar and Time Style 
     setIs24HourView(true); 
     setCalendarViewShown(false); 

     switch (DialogType) { 
     case DATE_PICKER: 
      timePicker.setVisibility(View.GONE); 
      break; 
     case TIME_PICKER: 
      datePicker.setVisibility(View.GONE); 
      break; 
     } 
    } 

    @Override 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 

     // Use the Builder class for convenient dialog construction 
     Builder builder = new AlertDialog.Builder(activity); 

     // Set the layout for the dialog 
     builder.setView(mView); 

     // Set title of dialog 
     builder.setMessage("Set Date") 
       // Set Ok button 
       .setPositiveButton("Set", 
         new DialogInterface.OnClickListener() { 
          public void onClick(DialogInterface dialog, int id) { 
           // User ok the dialog 
          } 
         }) 
       // Set Cancel button 
       .setNegativeButton("Cancel", 
         new DialogInterface.OnClickListener() { 
          public void onClick(DialogInterface dialog, int id) { 
           // User cancelled the dialog 
           DateTimeDialogFragment.this.getDialog().cancel(); 
          } 
         }); 

     // Create the AlertDialog object and return it 
     return builder.create(); 
    } 

    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 
     timePicker.setOnTimeChangedListener(this); 
    } 

    // Convenience wrapper for internal Calendar instance 
    public int get(final int field) { 
     return mCalendar.get(field); 
    } 

    // Convenience wrapper for internal Calendar instance 
    public long getDateTimeMillis() { 
     return mCalendar.getTimeInMillis(); 
    } 

    // Convenience wrapper for internal TimePicker instance 
    public void setIs24HourView(boolean is24HourView) { 
     timePicker.setIs24HourView(is24HourView); 
    } 

    // Convenience wrapper for internal TimePicker instance 
    public boolean is24HourView() { 
     return timePicker.is24HourView(); 
    } 

    // Convenience wrapper for internal DatePicker instance 
    public void setCalendarViewShown(boolean calendarView) { 
     datePicker.setCalendarViewShown(calendarView); 
    } 

    // Convenience wrapper for internal DatePicker instance 
    public boolean CalendarViewShown() { 
     return datePicker.getCalendarViewShown(); 
    } 

    // Convenience wrapper for internal DatePicker instance 
    public void updateDate(int year, int monthOfYear, int dayOfMonth) { 
     datePicker.updateDate(year, monthOfYear, dayOfMonth); 
    } 

    // Convenience wrapper for internal TimePicker instance 
    public void updateTime(int currentHour, int currentMinute) { 
     timePicker.setCurrentHour(currentHour); 
     timePicker.setCurrentMinute(currentMinute); 
    } 

    public String getDateTime() { 
     SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US); 
     return sdf.format(mCalendar.getTime()); 
    } 

    // Called every time the user changes DatePicker values 
    @Override 
    public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) { 
     // Update the internal Calendar instance 
     mCalendar.set(year, monthOfYear, dayOfMonth, mCalendar.get(Calendar.HOUR_OF_DAY), mCalendar.get(Calendar.MINUTE)); 
    } 

    // Called every time the user changes TimePicker values 
    @Override 
    public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { 
     // Update the internal Calendar instance 
     mCalendar.set(mCalendar.get(Calendar.YEAR), mCalendar.get(Calendar.MONTH), mCalendar.get(Calendar.DAY_OF_MONTH), hourOfDay, minute); 
    } 
} 
+0

非常感谢!这是一个完美的实施。从2-3天开始我一直在寻找这样的东西! – 2013-05-28 09:44:12

+0

片段不是假设使用构造函数。 [链接](http://stackoverflow.com/questions/10450348/do-fragments-really-need-an-empty-constructor) – minhaz 2014-07-01 20:40:52

+0

如何从这个@ user1848850 – 2015-05-06 10:58:57

1

你可以尝试this实现不使用AlertDialog.Builder,你可以有到view参考。所以你可以拨打view.findViewById(R.id.yourViewItem)

编辑:Pragnani的解决方案和建议也帮助我。非常感谢你。

+0

,允许我运行它,但如果我运行setter:setCalendarViewShown它崩溃。显然我在这里失去了一些东西,我一直在阅读几个小时,并没有找到线索,为什么它找不到R.id.DatePicker,我试图清理该项目,甚至重置模拟器,仍然 – user1848850 2013-02-15 05:25:38

+1

做你有与R.id.TimePicker相同的问题? – 2013-02-15 05:31:56

+0

我的错误,我已经完成了你的建议,并且在使用你发布的方法时,我没有得到空指针参考。虽然我无法对datePicker进行更改,因为这会使其崩溃。而且在使用你的方法时,我也失去了使用setNegativeButton/setNeutralButton的能力。我将不得不继续尝试找出为什么当使用AlertDialog.Builder时我无法访问R.id.DatePicker – user1848850 2013-02-15 05:33:26

3

编辑:

您好我已与你相同的代码工作,我能够打开日期和时间选择对话框...... 如果你已经错过了是你还没有充气的布局,以获得视图

试图改变自己的onActivityCreate这样

public void onActivityCreated(Bundle savedInstanceState) { 
// TODO Auto-generated method stub 
super.onActivityCreated(savedInstanceState); 
// Grab a Calendar instance 
mCalendar = Calendar.getInstance(); 
LayoutInflater inflater = activity.getLayoutInflater(); 

//Inflate and set the layout for the dialog 
//Pass null as the parent view because its going in the dialog layout 
View v=inflater.inflate(R.layout.date_time_dialog, null); 

// Init date picker 
datePicker = (DatePicker)v.findViewById(R.id.DatePicker); 
datePicker.init(mCalendar.get(Calendar.YEAR), mCalendar.get(Calendar.MONTH), mCalendar.get(Calendar.DAY_OF_MONTH), this); 

// Init time picker 
timePicker = (TimePicker) v.findViewById(R.id.TimePicker); 
timePicker.setOnTimeChangedListener(this); 
} 

这将解决你的问题....我相信因为... e用你的代码我已经成功的打开了对话框。


你好,请参阅与本文档OnActivityCreate

根据这onCreateView(LayoutInflater,ViewGroup中,包)后onViewStateRestored(包)之前调用的文件你需要使用onCreateView来获取datePicker =(DatePicker)getView()。findViewById(R.id.DatePicker);这个......我不知道,但我已经实现了,像这样的对话框中的DatePicker可能会有所帮助

public class DateDialogFragment extends DialogFragment implements 
      OnDateSetListener { 
     boolean fired = false; 

     @Override 
     public Dialog onCreateDialog(Bundle savedInstanceState) { 
      Calendar cal = Calendar.getInstance(); 
      int year = cal.get(Calendar.YEAR); 
      int month = cal.get(Calendar.MONTH); 
      int day = cal.get(Calendar.DAY_OF_MONTH); 
      return new DatePickerDialog(getActivity(), this, year, month, day); 
     } 

     @Override 
     public void onDateSet(DatePicker view, int year, int monthOfYear, 
       int dayOfMonth) { 

      if (fired == true) { 
       return; 
      } else { 
       // first time fired 
       fired = true; 
      } 
      String date = checkDigit(monthOfYear + 1) + "/" 
        + checkDigit(dayOfMonth) + "/" + year; 
      strDate = date; 
      getAppointments(date); 
     } 
    } 

格式化结果日期

public String checkDigit(int number) { 
      return number <= 9 ? "0" + number : String.valueOf(number); 
     } 

,并在活动中使用它像这样(建议使用FragmentActivity)

DateDialogFragment datepicker = new DateDialogFragment(); 
       datepicker.show(getSupportFragmentManager(), "DatePicker"); 
+1

获得选定的日期和时间也尝试膨胀布局像这样为你的代码 – Pragnani 2013-02-15 05:50:26

+0

问题为u,onCreateDialog在onActivityCreated之后触发? – user1848850 2013-02-15 05:52:35

+0

我使用AlertDialog.Builder的原因是为了创建Positive/Neutral/Negative按钮。我从这里得到了主意:[链接](http://developer.android.com/guide/topics/ui/dialogs.html#DialogFragment) – user1848850 2013-02-15 05:53:59