package com.github.jjobes.slidedaytimepicker; import android.content.Context; import android.os.Build; import android.os.Bundle; import android.support.v4.app.Fragment; import android.text.format.DateFormat; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.DatePicker; import android.widget.NumberPicker; import android.widget.NumberPicker.OnValueChangeListener; import android.widget.TimePicker; /** * The fragment for the second page in the ViewPager that holds * the {@link CustomTimePicker}. * * @author jjobes * */ public class TimeFragment extends Fragment { /** * Used to communicate back to the parent fragment as the user * is changing the time spinners so we can dynamically update * the tab text. */ public interface TimeChangedListener { void onTimeChanged(int hour, int minute); } private TimeChangedListener mCallback; private TimePicker mTimePicker; public TimeFragment() { // Required empty public constructor for fragment. } /** * Cast the reference to {@link SlideDayTimeDialogFragment} to a * {@link TimeChangedListener}. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); try { mCallback = (TimeChangedListener) getTargetFragment(); } catch (ClassCastException e) { throw new ClassCastException("Calling fragment must implement " + "TimeFragment.TimeChangedListener interface"); } } /** * Return an instance of TimeFragment with its bundle filled with the * constructor arguments. The values in the bundle are retrieved in * {@link #onCreateView()} below to properly initialize the TimePicker. * * @param theme * @param hour * @param minute * @param isClientSpecified24HourTime * @param is24HourTime * @return */ public static final TimeFragment newInstance(int theme, int hour, int minute, boolean isClientSpecified24HourTime, boolean is24HourTime) { TimeFragment f = new TimeFragment(); Bundle b = new Bundle(); b.putInt("theme", theme); b.putInt("hour", hour); b.putInt("minute", minute); b.putBoolean("isClientSpecified24HourTime", isClientSpecified24HourTime); b.putBoolean("is24HourTime", is24HourTime); f.setArguments(b); return f; } /** * Create and return the user interface view for this fragment. */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { int theme = getArguments().getInt("theme"); int initialHour = getArguments().getInt("hour"); int initialMinute = getArguments().getInt("minute"); boolean isClientSpecified24HourTime = getArguments().getBoolean("isClientSpecified24HourTime"); boolean is24HourTime = getArguments().getBoolean("is24HourTime"); // Unless we inflate using a cloned inflater with a Holo theme, // on Lollipop devices the TimePicker will be the new-style // radial TimePicker, which is not what we want. So we will // clone the inflater that we're given but with our specified // theme, then inflate the layout with this new inflater. Context contextThemeWrapper = new ContextThemeWrapper( getActivity(), theme == SlideDayTimePicker.HOLO_DARK ? android.R.style.Theme_Holo : android.R.style.Theme_Holo_Light); LayoutInflater localInflater = inflater.cloneInContext(contextThemeWrapper); View v = localInflater.inflate(R.layout.fragment_time, container, false); mTimePicker = (TimePicker) v.findViewById(R.id.timePicker); // block keyboard popping up on touch mTimePicker.setDescendantFocusability(DatePicker.FOCUS_BLOCK_DESCENDANTS); mTimePicker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() { @Override public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { mCallback.onTimeChanged(hourOfDay, minute); } }); // If the client specifies a 24-hour time format, set it on // the TimePicker. if (isClientSpecified24HourTime) { mTimePicker.setIs24HourView(is24HourTime); } else { // If the client does not specify a 24-hour time format, use the // device default. mTimePicker.setIs24HourView(DateFormat.is24HourFormat( getTargetFragment().getActivity())); } mTimePicker.setCurrentHour(initialHour); mTimePicker.setCurrentMinute(initialMinute); // Fix for the bug where a TimePicker's onTimeChanged() is not called when // the user toggles the AM/PM button. Only applies to 4.0.0 and 4.0.3. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH && Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { fixTimePickerBug18982(); } return v; } /** * Workaround for bug in Android TimePicker where the onTimeChanged() callback * is not invoked when the user toggles between AM/PM. But we need to be able * to detect this in order to dynamically update the tab title properly when * the user toggles between AM/PM. * * Registered as Issue 18982: * * https://code.google.com/p/android/issues/detail?id=18982 */ private void fixTimePickerBug18982() { View amPmView = ((ViewGroup) mTimePicker.getChildAt(0)).getChildAt(3); if (amPmView instanceof NumberPicker) { ((NumberPicker) amPmView).setOnValueChangedListener(new OnValueChangeListener() { @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { if (picker.getValue() == 1) // PM { if (mTimePicker.getCurrentHour() < 12) mTimePicker.setCurrentHour(mTimePicker.getCurrentHour() + 12); } else // AM { if (mTimePicker.getCurrentHour() >= 12) mTimePicker.setCurrentHour(mTimePicker.getCurrentHour() - 12); } mCallback.onTimeChanged( mTimePicker.getCurrentHour(), mTimePicker.getCurrentMinute()); } }); } } }