使用 DialogFragment 在 Fragment 中实现 TimePicker 对话框并获取 ClassCastException
日志猫:
02-15 02:44:29.199: E/AndroidRuntime(1297): FATAL EXCEPTION: main
02-15 02:44:29.199: E/AndroidRuntime(1297): Process: com.example.datetimeabs, PID: 1297
02-15 02:44:29.199: E/AndroidRuntime(1297): java.lang.ClassCastException: com.example.datetimeabs.MainActivity@b1d75900 must implement com.example.datetimeabs.TimePickerFragment$TimePickedListener
02-15 02:44:29.199: E/AndroidRuntime(1297): at com.example.datetimeabs.TimePickerFragment.onAttach(TimePickerFragment.java:40)
02-15 02:44:29.199: E/AndroidRuntime(1297): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:883)
02-15 02:44:29.199: E/AndroidRuntime(1297): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
02-15 02:44:29.199: E/AndroidRuntime(1297): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
02-15 02:44:29.199: E/AndroidRuntime(1297): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1460)
02-15 02:44:29.199: E/AndroidRuntime(1297): at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:440)
02-15 02:44:29.199: E/AndroidRuntime(1297): at android.os.Handler.handleCallback(Handler.java:733)
02-15 02:44:29.199: E/AndroidRuntime(1297): at android.os.Handler.dispatchMessage(Handler.java:95)
02-15 02:44:29.199: E/AndroidRuntime(1297): at android.os.Looper.loop(Looper.java:136)
02-15 02:44:29.199: E/AndroidRuntime(1297): at android.app.ActivityThread.main(ActivityThread.java:5017)
02-15 02:44:29.199: E/AndroidRuntime(1297): at java.lang.reflect.Method.invokeNative(Native Method)
02-15 02:44:29.199: E/AndroidRuntime(1297): at java.lang.reflect.Method.invoke(Method.java:515)
02-15 02:44:29.199: E/AndroidRuntime(1297): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
02-15 02:44:29.199: E/AndroidRuntime(1297): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
02-15 02:44:29.199: E/AndroidRuntime(1297): at dalvik.system.NativeStart.main(Native Method)
02-15 02:44:32.679: I/Process(1297): Sending signal. PID: 1297 SIG: 9
我正在关注本教程: http ://www.lukehorvat.com/blog/android-time-picker-example/你也可以看到我在代码中使用的TimePickerFragment.java !
FragmentTab1.java:
public class FragmentTab1 extends SherlockFragment implements TimePickedListener{
Button buttonDate;
Button buttonTime;
TextView textDate;
TextView textTime;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragmenttab1, container, false);
buttonDate = (Button) rootView.findViewById(R.id.btnDate);
buttonTime = (Button) rootView.findViewById(R.id.btnTime);
textDate = (TextView) rootView.findViewById(R.id.txtDate);
textTime = (TextView) rootView.findViewById(R.id.txtTime);
// calendar class get the current instance of android phone clock
Calendar c = Calendar.getInstance();
// a formatted object for date and time
SimpleDateFormat sdfTime = new SimpleDateFormat("HH:mm a");
// save date and time in string object.
String strTime = sdfTime.format(c.getTime());
textTime.setText(strTime);
SimpleDateFormat sdfDate = new SimpleDateFormat("dd-MMM-yyyy");
String strDate = sdfDate.format(c.getTime());
textDate.setText(strDate);
buttonTime.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
// show the time picker dialog
TimePickerFragment newFragment = new TimePickerFragment();
newFragment.show(getActivity().getSupportFragmentManager(), "timePicker");
}
});
return rootView;
}
@Override
public void onTimePicked(Calendar time)
{
// display the selected time in the TextView
textTime.setText(DateFormat.format("HH:mm a", time));
}
}
MainActivity.java:-
public class MainActivity extends SherlockFragmentActivity{
// Declare Variables
private FragmentTabHost mTabHost;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set the view from main_fragment.xml
setContentView(R.layout.main_fragment);
// Locate android.R.id.tabhost in main_fragment.xml
mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
// Create the tabs in main_fragment.xml
mTabHost.setup(this, getSupportFragmentManager(), R.id.tabcontent);
// Create Tab1 with a custom image in res folder
mTabHost.addTab(mTabHost.newTabSpec("tab1").setIndicator("", getResources().getDrawable(R.drawable.tab1)),
FragmentTab1.class, null);
// Create Tab2
mTabHost.addTab(mTabHost.newTabSpec("tab2").setIndicator("Tab2"),
FragmentTab2.class, null);
// Create Tab3
mTabHost.addTab(mTabHost.newTabSpec("tab3").setIndicator("Tab3"),
FragmentTab3.class, null);
}
}
TimePickerFragment.java:-
public class TimePickerFragment extends DialogFragment implements TimePickerDialog.OnTimeSetListener
{
private TimePickedListener mListener;
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
// use the current time as the default values for the picker
final Calendar c = Calendar.getInstance();
int hour = c.get(Calendar.HOUR_OF_DAY);
int minute = c.get(Calendar.MINUTE);
// create a new instance of TimePickerDialog and return it
return new TimePickerDialog(getActivity(), this, hour, minute, DateFormat.is24HourFormat(getActivity()));
}
@Override
public void onAttach(Activity activity)
{
// when the fragment is initially shown (i.e. attached to the activity), cast the activity to the callback interface type
super.onAttach(activity);
try
{
mListener = (TimePickedListener) activity;
}
catch (ClassCastException e)
{
throw new ClassCastException(activity.toString() + " must implement " + TimePickedListener.class.getName());
}
}
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute)
{
// when the time is selected, send it to the activity via its callback interface method
Calendar c = Calendar.getInstance();
c.set(Calendar.HOUR_OF_DAY, hourOfDay);
c.set(Calendar.MINUTE, minute);
mListener.onTimePicked(c);
}
public static interface TimePickedListener
{
public void onTimePicked(Calendar time);
}
}
编辑的代码: 归功于@Luksprog
FragmentTab1.java:
public class FragmentTab1 extends SherlockFragment{
Button buttonDate;
Button buttonTime;
TextView textDate;
TextView textTime;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragmenttab1, container, false);
buttonDate = (Button) rootView.findViewById(R.id.btnDate);
buttonTime = (Button) rootView.findViewById(R.id.btnTime);
textDate = (TextView) rootView.findViewById(R.id.txtDate);
textTime = (TextView) rootView.findViewById(R.id.txtTime);
// calendar class get the current instance of android phone clock
Calendar c = Calendar.getInstance();
// a formatted object for date and time
SimpleDateFormat sdfTime = new SimpleDateFormat("HH:mm a");
// save date and time in string object.
String strTime = sdfTime.format(c.getTime());
textTime.setText(strTime);
SimpleDateFormat sdfDate = new SimpleDateFormat("dd-MMM-yyyy");
String strDate = sdfDate.format(c.getTime());
textDate.setText(strDate);
buttonTime.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
// show the time picker dialog
TimePickerFragment newFragment = new TimePickerFragment();
newFragment.show(getActivity().getSupportFragmentManager(), "timePicker");
}
});
return rootView;
}
public void onTimePicked(Calendar time)
{
SimpleDateFormat sdfTime = new SimpleDateFormat("HH:mm a");
String strTime = sdfTime.format(time.getTime());
Log.i("onTimePicked >>> ", strTime);
// display the selected time in the TextView
textTime.setText(DateFormat.format("HH:mm a", time));
}
}
MainActivity.java:
public class MainActivity extends SherlockFragmentActivity implements TimePickedListener {
// Declare Variables
private FragmentTabHost mTabHost;
FragmentTab1 fragmentTab1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set the view from main_fragment.xml
setContentView(R.layout.main_fragment);
fragmentTab1 = new FragmentTab1();
// Locate android.R.id.tabhost in main_fragment.xml
mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
// Create the tabs in main_fragment.xml
mTabHost.setup(this, getSupportFragmentManager(), R.id.tabcontent);
// Create Tab1 with a custom image in res folder
mTabHost.addTab(mTabHost.newTabSpec("tab1").setIndicator("", getResources().getDrawable(R.drawable.tab1)),
FragmentTab1.class, null);
// Create Tab2
mTabHost.addTab(mTabHost.newTabSpec("tab2").setIndicator("Tab2"),
FragmentTab2.class, null);
// Create Tab3
mTabHost.addTab(mTabHost.newTabSpec("tab3").setIndicator("Tab3"),
FragmentTab3.class, null);
}
@Override
public void onTimePicked(Calendar time) {
// TODO Auto-generated method stub
fragmentTab1.onTimePicked(time);
}
}
例外线:
textTime.setText(DateFormat.format("HH:mm a", time));
新日志:
02-15 04:18:40.149: D/dalvikvm(1469): GC_FOR_ALLOC freed <1K, 4% free 5141K/5324K, paused 42ms, total 42ms
02-15 04:18:40.349: I/Choreographer(1469): Skipped 126 frames! The application may be doing too much work on its main thread.
02-15 04:18:40.939: I/Choreographer(1469): Skipped 46 frames! The application may be doing too much work on its main thread.
02-15 04:18:49.669: I/onTimePicked >>>(1469): 08:25 AM
02-15 04:18:49.669: D/AndroidRuntime(1469): Shutting down VM
02-15 04:18:49.729: W/dalvikvm(1469): threadid=1: thread exiting with uncaught exception (group=0xb1a94ba8)
02-15 04:18:49.739: E/AndroidRuntime(1469): FATAL EXCEPTION: main
02-15 04:18:49.739: E/AndroidRuntime(1469): Process: com.example.datetimeabs, PID: 1469
02-15 04:18:49.739: E/AndroidRuntime(1469): java.lang.NullPointerException
02-15 04:18:49.739: E/AndroidRuntime(1469): at com.example.datetimeabs.FragmentTab1.onTimePicked(FragmentTab1.java:73)
02-15 04:18:49.739: E/AndroidRuntime(1469): at com.example.datetimeabs.MainActivity.onTimePicked(MainActivity.java:47)
02-15 04:18:49.739: E/AndroidRuntime(1469): at com.example.datetimeabs.TimePickerFragment.onTimeSet(TimePickerFragment.java:52)
02-15 04:18:49.739: E/AndroidRuntime(1469): at android.app.TimePickerDialog.tryNotifyTimeSet(TimePickerDialog.java:130)
02-15 04:18:49.739: E/AndroidRuntime(1469): at android.app.TimePickerDialog.onClick(TimePickerDialog.java:115)
02-15 04:18:49.739: E/AndroidRuntime(1469): at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:166)
02-15 04:18:49.739: E/AndroidRuntime(1469): at android.os.Handler.dispatchMessage(Handler.java:102)
02-15 04:18:49.739: E/AndroidRuntime(1469): at android.os.Looper.loop(Looper.java:136)
02-15 04:18:49.739: E/AndroidRuntime(1469): at android.app.ActivityThread.main(ActivityThread.java:5017)
02-15 04:18:49.739: E/AndroidRuntime(1469): at java.lang.reflect.Method.invokeNative(Native Method)
02-15 04:18:49.739: E/AndroidRuntime(1469): at java.lang.reflect.Method.invoke(Method.java:515)
02-15 04:18:49.739: E/AndroidRuntime(1469): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
02-15 04:18:49.739: E/AndroidRuntime(1469): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
02-15 04:18:49.739: E/AndroidRuntime(1469): at dalvik.system.NativeStart.main(Native Method)