代码是别人开源的,改了个丢丢拿来用,记录下。方便下次搬砖
效果图
一、MyTimePicker类
import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.NumberPicker;
import android.widget.NumberPicker.Formatter;
import java.text.DateFormatSymbols;
import java.util.Calendar;
/**
* A view for selecting the time of day, in either 24 hour or AM/PM mode.
*
* The hour, each minute digit, each seconds digit, and AM/PM (if applicable) can be conrolled by
* vertical spinners.
*
* The hour can be entered by keyboard input. Entering in two digit hours
* can be accomplished by hitting two digits within a timeout of about a
* second (e.g. '1' then '2' to select 12).
*
* The minutes can be entered by entering single digits.
* The seconds can be entered by entering single digits.
*
* Under AM/PM mode, the user can hit 'a', 'A", 'p' or 'P' to pick.
*
* For a dialog using this view, see {@link android.app.TimePickerDialog}.
*/
public class MyTimePicker extends FrameLayout {
/**
* A no-op callback used in the constructor to avoid null checks
* later in the code.
*/
private static final OnTimeChangedListener NO_OP_CHANGE_LISTENER = new OnTimeChangedListener() {
public void onTimeChanged(MyTimePicker view, int hourOfDay, int minute, int seconds) {
}
};
public static final Formatter TWO_DIGIT_FORMATTER =
new Formatter() {
@Override
public String format(int value) {
// TODO Auto-generated method stub
return String.format("%02d", value);
}
};
// state
private int mCurrentHour = 0; // 0-23
private int mCurrentMinute = 0; // 0-59
private int mCurrentSeconds = 0; // 0-59
private Boolean mIs24HourView = false;
private boolean mIsAm;
// ui components
private final NumberPicker mHourPicker;
private final NumberPicker mMinutePicker;
private final NumberPicker mSecondPicker;
private final Button mAmPmButton;
private final String mAmText;
private final String mPmText;
// callbacks
private OnTimeChangedListener mOnTimeChangedListener;
/**
* The callback interface used to indicate the time has been adjusted.
*/
public interface OnTimeChangedListener {
/**
* @param view The view associated with this listener.
* @param hourOfDay The current hour.
* @param minute The current minute.
* @param seconds The current second.
*/
void onTimeChanged(MyTimePicker view, int hourOfDay, int minute, int seconds);
}
public MyTimePicker(Context context) {
this(context, null);
}
public MyTimePicker(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyTimePicker(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
LayoutInflater inflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.time_picker_widget,
this, // we are the parent
true);
// hour
mHourPicker = (NumberPicker) findViewById(R.id.hour);
mHourPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
// TODO Auto-generated method stub
mCurrentHour = newVal;
if (!mIs24HourView) {
// adjust from [1-12] to [0-11] internally, with the times
// written "12:xx" being the start of the half-day
if (mCurrentHour == 12) {
mCurrentHour = 0;
}
if (!mIsAm) {
// PM means 12 hours later than nominal
mCurrentHour += 12;
}
}
onTimeChanged();
}
});
// digits of minute
mMinutePicker = (NumberPicker) findViewById(R.id.minute);
mMinutePicker.setMinValue(0);
mMinutePicker.setMaxValue(59);
mMinutePicker.setFormatter(TWO_DIGIT_FORMATTER);
mMinutePicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker spinner, int oldVal, int newVal) {
mCurrentMinute = newVal;
onTimeChanged();
}
});
// digits of seconds
mSecondPicker = (NumberPicker) findViewById(R.id.seconds);
mSecondPicker.setMinValue(0);
mSecondPicker.setMaxValue(59);
mSecondPicker.setFormatter( TWO_DIGIT_FORMATTER);
mSecondPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
mCurrentSeconds = newVal;
onTimeChanged();
}
});
// am/pm
mAmPmButton = (Button) findViewById(R.id.amPm);
// now that the hour/minute picker objects have been initialized, set
// the hour range properly based on the 12/24 hour display mode.
configurePickerRanges();
// initialize to current time
Calendar cal = Calendar.getInstance();
setOnTimeChangedListener(NO_OP_CHANGE_LISTENER);
// by default we're not in 24 hour mode
setCurrentHour(cal.get(Calendar.HOUR_OF_DAY));
setCurrentMinute(cal.get(Calendar.MINUTE));
setCurrentSecond(cal.get(Calendar.SECOND));
mIsAm = (mCurrentHour < 12);
/* Get the localized am/pm strings and use them in the spinner */
DateFormatSymbols dfs = new DateFormatSymbols();
String[] dfsAmPm = dfs.getAmPmStrings();
mAmText = dfsAmPm[Calendar.AM];
mPmText = dfsAmPm[Calendar.PM];
mAmPmButton.setText(mIsAm ? mAmText : mPmText);
mAmPmButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
requestFocus();
if (mIsAm) {
// Currently AM switching to PM
if (mCurrentHour < 12) {
mCurrentHour += 12;
}
} else {
// Currently PM switching to AM
if (mCurrentHour >= 12) {
mCurrentHour -= 12;
}
}
mIsAm = !mIsAm;
mAmPmButton.setText(mIsAm ? mAmText : mPmText);
onTimeChanged();
}
});
if (!isEnabled()) {
setEnabled(false);
}
}
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
mMinutePicker.setEnabled(enabled);
mHourPicker.setEnabled(enabled);
mAmPmButton.setEnabled(enabled);
}
/**
* Used to save / restore state of time picker
*/
private static class SavedState extends BaseSavedState {
private final int mHour;
private final int mMinute;
private SavedState(Parcelable superState, int hour, int minute) {
super(superState);
mHour = hour;
mMinute = minute;
}
private SavedState(Parcel in) {
super(in);
mHour = in.readInt();
mMinute = in.readInt();
}
public int getHour() {
return mHour;
}
public int getMinute() {
return mMinute;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(mHour);
dest.writeInt(mMinute);
}
public static final Creator<SavedState> CREATOR
= new Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
@Override
protected Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
return new SavedState(superState, mCurrentHour, mCurrentMinute);
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
SavedState ss = (SavedState) state;
super.onRestoreInstanceState(ss.getSuperState());
setCurrentHour(ss.getHour());
setCurrentMinute(ss.getMinute());
}
/**
* Set the callback that indicates the time has been adjusted by the user.
* @param onTimeChangedListener the callback, should not be null.
*/
public void setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener) {
mOnTimeChangedListener = onTimeChangedListener;
}
/**
* @return The current hour (0-23).
*/
public Integer getCurrentHour() {
return mCurrentHour;
}
/**
* Set the current hour.
*/
public void setCurrentHour(Integer currentHour) {
this.mCurrentHour = currentHour;
updateHourDisplay();
}
/**
* Set whether in 24 hour or AM/PM mode.
* @param is24HourView True = 24 hour mode. False = AM/PM.
*/
public void setIs24HourView(Boolean is24HourView) {
if (mIs24HourView != is24HourView) {
mIs24HourView = is24HourView;
configurePickerRanges();
updateHourDisplay();
}
}
/**
* @return true if this is in 24 hour view else false.
*/
public boolean is24HourView() {
return mIs24HourView;
}
/**
* @return The current minute.
*/
public Integer getCurrentMinute() {
return mCurrentMinute;
}
/**
* Set the current minute (0-59).
*/
public void setCurrentMinute(Integer currentMinute) {
this.mCurrentMinute = currentMinute;
updateMinuteDisplay();
}
/**
* @return The current minute.
*/
public Integer getCurrentSeconds() {
return mCurrentSeconds;
}
/**
* Set the current second (0-59).
*/
public void setCurrentSecond(Integer currentSecond) {
this.mCurrentSeconds = currentSecond;
updateSecondsDisplay();
}
@Override
public int getBaseline() {
return mHourPicker.getBaseline();
}
/**
* Set the state of the spinners appropriate to the current hour.
*/
private void updateHourDisplay() {
int currentHour = mCurrentHour;
if (!mIs24HourView) {
// convert [0,23] ordinal to wall clock display
if (currentHour > 12) currentHour -= 12;
else if (currentHour == 0) currentHour = 12;
}
mHourPicker.setValue(currentHour);
mIsAm = mCurrentHour < 12;
mAmPmButton.setText(mIsAm ? mAmText : mPmText);
onTimeChanged();
}
private void configurePickerRanges() {
if (mIs24HourView) {
mHourPicker.setMinValue(0);
mHourPicker.setMaxValue(23);
mHourPicker.setFormatter(TWO_DIGIT_FORMATTER);
mAmPmButton.setVisibility(View.GONE);
} else {
mHourPicker.setMinValue(1);
mHourPicker.setMaxValue(12);
mHourPicker.setFormatter(null);
mAmPmButton.setVisibility(View.VISIBLE);
}
}
private void onTimeChanged() {
mOnTimeChangedListener.onTimeChanged(this, getCurrentHour(), getCurrentMinute(), getCurrentSeconds());
}
/**
* Set the state of the spinners appropriate to the current minute.
*/
private void updateMinuteDisplay() {
mMinutePicker.setValue(mCurrentMinute);
mOnTimeChangedListener.onTimeChanged(this, getCurrentHour(), getCurrentMinute(), getCurrentSeconds());
}
/**
* Set the state of the spinners appropriate to the current second.
*/
private void updateSecondsDisplay() {
mSecondPicker.setValue(mCurrentSeconds);
mOnTimeChangedListener.onTimeChanged(this, getCurrentHour(), getCurrentMinute(), getCurrentSeconds());
}
}
二、MyTimePickerDialog类
import java.util.Calendar;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.text.format.DateFormat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
/**
* A dialog that prompts the user for the time of day using a {@link MyTimePicker}.
*/
public class MyTimePickerDialog extends AlertDialog implements OnClickListener,
MyTimePicker.OnTimeChangedListener {
/**
* The callback interface used to indicate the user is done filling in
* the time (they clicked on the 'Set' button).
*/
public interface OnTimeSetListener {
/**
* @param view The view associated with this listener.
* @param hourOfDay The hour that was set.
* @param minute The minute that was set.
*/
void onTimeSet(MyTimePicker view, int hourOfDay, int minute, int seconds);
}
private static final String HOUR = "hour";
private static final String MINUTE = "minute";
private static final String SECONDS = "seconds";
private static final String IS_24_HOUR = "is24hour";
public MyTimePicker getmTimePicker() {
return mTimePicker;
}
private final MyTimePicker mTimePicker;
private final OnTimeSetListener mCallback;
private final Calendar mCalendar;
private final java.text.DateFormat mDateFormat;
int mInitialHourOfDay;
int mInitialMinute;
int mInitialSeconds;
boolean mIs24HourView;
/**
* @param context Parent.
* @param callBack How parent is notified.
* @param hourOfDay The initial hour.
* @param minute The initial minute.
* @param is24HourView Whether this is a 24 hour view, or AM/PM.
*/
public MyTimePickerDialog(Context context,
OnTimeSetListener callBack,
int hourOfDay, int minute, int seconds, boolean is24HourView) {
this(context, 0,
callBack, hourOfDay, minute, seconds, is24HourView);
}
/**
* @param context Parent.
* @param theme the theme to apply to this dialog
* @param callBack How parent is notified.
* @param hourOfDay The initial hour.
* @param minute The initial minute.
* @param is24HourView Whether this is a 24 hour view, or AM/PM.
*/
public MyTimePickerDialog(Context context,
int theme,
OnTimeSetListener callBack,
int hourOfDay, int minute, int seconds, boolean is24HourView) {
super(context, theme);
requestWindowFeature(Window.FEATURE_NO_TITLE);
mCallback = callBack;
mInitialHourOfDay = hourOfDay;
mInitialMinute = minute;
mInitialSeconds = seconds;
mIs24HourView = is24HourView;
mDateFormat = DateFormat.getTimeFormat(context);
mCalendar = Calendar.getInstance();
updateTitle(mInitialHourOfDay, mInitialMinute, mInitialSeconds);
setButton(context.getText(R.string.btn_sure), this);
setButton2(context.getText(R.string.btn_cancel), (OnClickListener) null);
//setIcon(android.R.drawable.ic_dialog_time);
LayoutInflater inflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.time_picker_dialog, null);
setView(view);
mTimePicker = (MyTimePicker) view.findViewById(R.id.timePicker);
// initialize state
mTimePicker.setCurrentHour(mInitialHourOfDay);
mTimePicker.setCurrentMinute(mInitialMinute);
mTimePicker.setCurrentSecond(mInitialSeconds);
mTimePicker.setIs24HourView(mIs24HourView);
mTimePicker.setOnTimeChangedListener(this);
}
public void onClick(DialogInterface dialog, int which) {
if (mCallback != null) {
mTimePicker.clearFocus();
mCallback.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
mTimePicker.getCurrentMinute(), mTimePicker.getCurrentSeconds());
}
}
public void onTimeChanged(MyTimePicker view, int hourOfDay, int minute, int seconds) {
updateTitle(hourOfDay, minute, seconds);
}
public void updateTime(int hourOfDay, int minutOfHour, int seconds) {
mTimePicker.setCurrentHour(hourOfDay);
mTimePicker.setCurrentMinute(minutOfHour);
mTimePicker.setCurrentSecond(seconds);
}
private void updateTitle(int hour, int minute, int seconds) {
String sHour = String.format("%02d", hour);
String sMin = String.format("%02d", minute);
String sSec = String.format("%02d", seconds);
setTitle(sHour + ":" + sMin + ":" + sSec);
}
@Override
public Bundle onSaveInstanceState() {
Bundle state = super.onSaveInstanceState();
state.putInt(HOUR, mTimePicker.getCurrentHour());
state.putInt(MINUTE, mTimePicker.getCurrentMinute());
state.putInt(SECONDS, mTimePicker.getCurrentSeconds());
state.putBoolean(IS_24_HOUR, mTimePicker.is24HourView());
return state;
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
int hour = savedInstanceState.getInt(HOUR);
int minute = savedInstanceState.getInt(MINUTE);
int seconds = savedInstanceState.getInt(SECONDS);
mTimePicker.setCurrentHour(hour);
mTimePicker.setCurrentMinute(minute);
mTimePicker.setCurrentSecond(seconds);
mTimePicker.setIs24HourView(savedInstanceState.getBoolean(IS_24_HOUR));
mTimePicker.setOnTimeChangedListener(this);
updateTitle(hour, minute, seconds);
}
}
三、布局文件time_picker_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal">
<com.dssoft.mnursing.dialog.MyTimePicker
android:id="@+id/timePicker"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
四、布局文件time_picker_widget.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layoutDirection="ltr">
<!-- hour -->
<NumberPicker
android:id="@+id/hour"
android:layout_width="70dip"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
/>
<!-- minute -->
<NumberPicker
android:id="@+id/minute"
android:layout_width="70dip"
android:layout_height="wrap_content"
android:layout_marginStart="5dip"
android:focusable="true"
android:focusableInTouchMode="true"
/>
<!-- seconds -->
<NumberPicker
android:id="@+id/seconds"
android:layout_width="70dip"
android:layout_height="wrap_content"
android:layout_marginStart="5dip"
android:focusable="true"
android:focusableInTouchMode="true"
/>
</LinearLayout>
<!-- AM / PM -->
<Button
android:id="@+id/amPm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="43dip"
android:layout_marginStart="5dip"
android:paddingStart="20dip"
android:paddingEnd="20dip"
style="?android:attr/textAppearanceLargeInverse"
android:textColor="@android:color/primary_text_light_nodisable"
/>
</LinearLayout>
五、项目中运用
MyTimePickerDialog myDialog = new MyTimePickerDialog(this, new MyTimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(MyTimePicker view, int hourOfDay, int minute, int seconds) {
timeBtn.setText(String.format("%02d", hourOfDay)+
":" + String.format("%02d", minute) +
":" + String.format("%02d", seconds));
}
}, Calendar.HOUR_OF_DAY, Calendar.MINUTE, Calendar.SECOND, true);
myDialog.show();
myDialog.setButton(DialogInterface.BUTTON_POSITIVE, "确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(which == DialogInterface.BUTTON_POSITIVE) {
MyTimePicker timePicker = myDialog.getmTimePicker();
String time = ToolUtil.timeFormat(timePicker.getCurrentHour(), timePicker.getCurrentMinute(), timePicker.getCurrentSeconds());
timeBtn.setText(time);
myDialog.dismiss();
}
}
});
myDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(which == DialogInterface.BUTTON_NEGATIVE) {
myDialog.dismiss();
}
}
});