/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ package android.widget; import android.annotation.Widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.format.DateFormat;
import android.text.format.DateUtils;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.widget.NumberPicker;
import android.widget.NumberPicker.OnChangedListener; import com.android.internal.R; import java.text.DateFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale; /**
* A view for selecting a month / year / day based on a calendar like layout.
*
* <p>See the <a href="{@docRoot}resources/tutorials/views/hello-datepicker.html">Date Picker
* tutorial</a>.</p>
*
* For a dialog using this view, see {@link android.app.DatePickerDialog}.
*/
@Widget
public class DatePicker extends FrameLayout { private static final int DEFAULT_START_YEAR = 1900;
private static final int DEFAULT_END_YEAR = 2100; // This ignores Undecimber, but we only support real Gregorian calendars.
private static final int NUMBER_OF_MONTHS = 12; /* UI Components */
private final NumberPicker mDayPicker;
private final NumberPicker mMonthPicker;
private final NumberPicker mYearPicker; /**
* How we notify users the date has changed.
*/
private OnDateChangedListener mOnDateChangedListener; private int mDay;
private int mMonth;
private int mYear; private Object mMonthUpdateLock = new Object();
private volatile Locale mMonthLocale;
private String[] mShortMonths; /**
* The callback used to indicate the user changes the date.
*/
public interface OnDateChangedListener { /**
* @param view The view associated with this listener.
* @param year The year that was set.
* @param monthOfYear The month that was set (0-11) for compatibility
* with {@link java.util.Calendar}.
* @param dayOfMonth The day of the month that was set.
*/
void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth);
} public DatePicker(Context context) {
this(context, null);
} public DatePicker(Context context, AttributeSet attrs) {
this(context, attrs, 0);
} public DatePicker(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle); LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.date_picker, this, true); mDayPicker = (NumberPicker) findViewById(R.id.day);
mDayPicker.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER);
mDayPicker.setSpeed(100);
mDayPicker.setOnChangeListener(new OnChangedListener() {
public void onChanged(NumberPicker picker, int oldVal, int newVal) {
mDay = newVal;
notifyDateChanged();
}
});
mMonthPicker = (NumberPicker) findViewById(R.id.month);
mMonthPicker.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER);
final String[] months = getShortMonths(); /*
* If the user is in a locale where the month names are numeric,
* use just the number instead of the "month" character for
* consistency with the other fields.
*/
if (months[0].startsWith("1")) {
for (int i = 0; i < months.length; i++) {
months[i] = String.valueOf(i + 1);
}
mMonthPicker.setRange(1, NUMBER_OF_MONTHS);
} else {
mMonthPicker.setRange(1, NUMBER_OF_MONTHS, months);
} mMonthPicker.setSpeed(200);
mMonthPicker.setOnChangeListener(new OnChangedListener() {
public void onChanged(NumberPicker picker, int oldVal, int newVal) { /* We display the month 1-12 but store it 0-11 so always
* subtract by one to ensure our internal state is always 0-11
*/
mMonth = newVal - 1;
// Adjust max day of the month
adjustMaxDay();
notifyDateChanged();
updateDaySpinner();
}
});
mYearPicker = (NumberPicker) findViewById(R.id.year);
mYearPicker.setSpeed(100);
mYearPicker.setOnChangeListener(new OnChangedListener() {
public void onChanged(NumberPicker picker, int oldVal, int newVal) {
mYear = newVal;
// Adjust max day for leap years if needed
adjustMaxDay();
notifyDateChanged();
updateDaySpinner();
}
}); // attributes
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DatePicker); int mStartYear = a.getInt(R.styleable.DatePicker_startYear, DEFAULT_START_YEAR);
int mEndYear = a.getInt(R.styleable.DatePicker_endYear, DEFAULT_END_YEAR);
mYearPicker.setRange(mStartYear, mEndYear); a.recycle(); // initialize to current date
Calendar cal = Calendar.getInstance();
init(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), null); // re-order the number pickers to match the current date format
reorderPickers(months); if (!isEnabled()) {
setEnabled(false);
}
} @Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
mDayPicker.setEnabled(enabled);
mMonthPicker.setEnabled(enabled);
mYearPicker.setEnabled(enabled);
} private void reorderPickers(String[] months) {
java.text.DateFormat format;
String order; /*
* If the user is in a locale where the medium date format is
* still numeric (Japanese and Czech, for example), respect
* the date format order setting. Otherwise, use the order
* that the locale says is appropriate for a spelled-out date.
*/ if (months[0].startsWith("1")) {
format = DateFormat.getDateFormat(getContext());
} else {
format = DateFormat.getMediumDateFormat(getContext());
} if (format instanceof SimpleDateFormat) {
order = ((SimpleDateFormat) format).toPattern();
} else {
// Shouldn't happen, but just in case.
order = new String(DateFormat.getDateFormatOrder(getContext()));
} /* Remove the 3 pickers from their parent and then add them back in the
* required order.
*/
LinearLayout parent = (LinearLayout) findViewById(R.id.parent);
parent.removeAllViews(); boolean quoted = false;
boolean didDay = false, didMonth = false, didYear = false; for (int i = 0; i < order.length(); i++) {
char c = order.charAt(i); if (c == '\'') {
quoted = !quoted;
} if (!quoted) {
if (c == DateFormat.DATE && !didDay) {
parent.addView(mDayPicker);
didDay = true;
} else if ((c == DateFormat.MONTH || c == 'L') && !didMonth) {
parent.addView(mMonthPicker);
didMonth = true;
} else if (c == DateFormat.YEAR && !didYear) {
parent.addView (mYearPicker);
didYear = true;
}
}
} // Shouldn't happen, but just in case.
if (!didMonth) {
parent.addView(mMonthPicker);
}
if (!didDay) {
parent.addView(mDayPicker);
}
if (!didYear) {
parent.addView(mYearPicker);
}
} public void updateDate(int year, int monthOfYear, int dayOfMonth) {
if (mYear != year || mMonth != monthOfYear || mDay != dayOfMonth) {
mYear = year;
mMonth = monthOfYear;
mDay = dayOfMonth;
updateSpinners();
reorderPickers(getShortMonths());
notifyDateChanged();
}
} private String[] getShortMonths() {
final Locale currentLocale = Locale.getDefault();
if (currentLocale.equals(mMonthLocale) && mShortMonths != null) {
return mShortMonths;
} else {
synchronized (mMonthUpdateLock) {
if (!currentLocale.equals(mMonthLocale)) {
mShortMonths = new String[NUMBER_OF_MONTHS];
for (int i = 0; i < NUMBER_OF_MONTHS; i++) {
mShortMonths[i] = DateUtils.getMonthString(Calendar.JANUARY + i,
DateUtils.LENGTH_MEDIUM);
}
mMonthLocale = currentLocale;
}
}
return mShortMonths;
}
} private static class SavedState extends BaseSavedState { private final int mYear;
private final int mMonth;
private final int mDay; /**
* Constructor called from {@link DatePicker#onSaveInstanceState()}
*/
private SavedState(Parcelable superState, int year, int month, int day) {
super(superState);
mYear = year;
mMonth = month;
mDay = day;
} /**
* Constructor called from {@link #CREATOR}
*/
private SavedState(Parcel in) {
super(in);
mYear = in.readInt();
mMonth = in.readInt();
mDay = in.readInt();
} public int getYear() {
return mYear;
} public int getMonth() {
return mMonth;
} public int getDay() {
return mDay;
} @Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(mYear);
dest.writeInt(mMonth);
dest.writeInt(mDay);
} public static final Parcelable.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 so we are in complete control of save / restore for this widget.
*/
@Override
protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
dispatchThawSelfOnly(container);
} @Override
protected Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState(); return new SavedState(superState, mYear, mMonth, mDay);
} @Override
protected void onRestoreInstanceState(Parcelable state) {
SavedState ss = (SavedState) state;
super.onRestoreInstanceState(ss.getSuperState());
mYear = ss.getYear();
mMonth = ss.getMonth();
mDay = ss.getDay();
updateSpinners();
} /**
* Initialize the state.
* @param year The initial year.
* @param monthOfYear The initial month.
* @param dayOfMonth The initial day of the month.
* @param onDateChangedListener How user is notified date is changed by user, can be null.
*/
public void init(int year, int monthOfYear, int dayOfMonth,
OnDateChangedListener onDateChangedListener) {
mYear = year;
mMonth = monthOfYear;
mDay = dayOfMonth;
mOnDateChangedListener = onDateChangedListener;
updateSpinners();
} private void updateSpinners() {
updateDaySpinner();
mYearPicker.setCurrent(mYear); /* The month display uses 1-12 but our internal state stores it
* 0-11 so add one when setting the display.
*/
mMonthPicker.setCurrent(mMonth + 1);
} private void updateDaySpinner() {
Calendar cal = Calendar.getInstance();
cal.set(mYear, mMonth, mDay);
int max = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
mDayPicker.setRange(1, max);
mDayPicker.setCurrent(mDay);
} public int getYear() {
return mYear;
} public int getMonth() {
return mMonth;
} public int getDayOfMonth() {
return mDay;
} private void adjustMaxDay(){
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, mYear);
cal.set(Calendar.MONTH, mMonth);
int max = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
if (mDay > max) {
mDay = max;
}
} private void notifyDateChanged() {
if (mOnDateChangedListener != null) {
mOnDateChangedListener.onDateChanged(DatePicker.this, mYear, mMonth, mDay);
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
--> <!-- Layout of date picker--> <!-- Warning: everything within the parent is removed and re-ordered depending
on the date format selected by the user. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/parent"
android:orientation="horizontal"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"> <!-- Month -->
<NumberPicker
android:id="@+id/month"
android:layout_width="80dip"
android:layout_height="wrap_content"
android:layout_marginLeft="1dip"
android:layout_marginRight="1dip"
android:focusable="true"
android:focusableInTouchMode="true"
/> <!-- Day -->
<NumberPicker
android:id="@+id/day"
android:layout_width="80dip"
android:layout_height="wrap_content"
android:layout_marginLeft="1dip"
android:layout_marginRight="1dip"
android:focusable="true"
android:focusableInTouchMode="true"
/> <!-- Year -->
<NumberPicker
android:id="@+id/year"
android:layout_width="95dip"
android:layout_height="wrap_content"
android:layout_marginLeft="1dip"
android:layout_marginRight="1dip"
android:focusable="true"
android:focusableInTouchMode="true"
/>
</LinearLayout>

android datepicker源码的更多相关文章

  1. 45个android实例源码

    分享45个android实例源码,很好很强大http://www.apkbus.com/android-20978-1-1.html andriod闹钟源代码http://www.apkbus.com ...

  2. 分享45个android实例源码,很好很强大

    分享45个android实例源码,很好很强大 http://www.apkbus.com/android-20978-1-1.html 分享45个android实例源码,很好很强大http://www ...

  3. 将Android系统源码导入ecplise

    Android系统源码中带有个IDE的配置文件,目录为:development/ide/ 如果要用eclipse导入查看系统源码,则将development/ide/eclipse/.classpat ...

  4. Android 如何在Eclipse中查看Android API源码 及 support包源码

    当我们阅读android API开发文档时候,上面的每个类,以及类的各个方法都是已经写好的方法和控件,可是我们只是在搬来使用,不知道它的原理,它是如何被实现的.android系统是开源的,所以谷歌官方 ...

  5. Android之源码之模块编译和调试

    Android之源码之模块编译调试 (一) 进行源码模块修改进行编译的调试 1.首先是从git或者svn上拉一套完整的工程下来,然后全编一下,一般这个时间比较长,大概会得2,3个小时左右, 2,编译成 ...

  6. 关于查看Android系统源码【Written By KillerLegend】

    可能你会想下载Android系统源码,但是我不知道你会看多少系统的源码,如果你对源码只是偶尔看一次的话,推荐你在线看Android的系统源码,下面提供几种查看android系统源码的方法. 1:打开这 ...

  7. 【转】Android 如何在Eclipse中查看Android API源码 及 support包源码

    原文网址:http://blog.csdn.net/vipzjyno1/article/details/22954775 当我们阅读android API开发文档时候,上面的每个类,以及类的各个方法都 ...

  8. 将android Settings 源码 导入到 eclipse工程

    1.  新建 android 项目 拷贝源码/packages/apps/Settings到你的其它目录. 在eclipse中,新建项目,但是要从exitting source选择: 2. 导入相关的 ...

  9. 最新app源码下载:200款优秀Android项目源码

    200款优秀Android项目源码!菜鸟必备!Android开发又将带来新一轮热潮,很多开发者都投入到这个浪潮中去了,创造了许许多多相当优秀的应用.其中也有许许多多的开发者提供了应用开源项目,贡献出他 ...

随机推荐

  1. 转:Apache和Nginx运行原理解析

    Web服务器 Web服务器也称为WWW(WORLD WIDE WEB)服务器,主要功能是提供网上信息浏览服务. 应用层使用HTTP协议. HTML文档格式. 浏览器统一资源定位器(URL). Web服 ...

  2. Linux Kernel KVM 'apic_get_tmcct()'函数拒绝服务漏洞

    漏洞版本: Linux Kernel 漏洞描述: Bugtraq ID:64270 CVE ID:CVE-2013-6367 Linux Kernel是一款开源的操作系统. Linux KVM LAP ...

  3. addChildViewController 与 addSubview

    在viewcontrollerA中, 如果想把controllerB.view添加进来, 可以用 addSubview, 但如果controllerB中有个事件, 使用到 self.navigatio ...

  4. 【转】使用XCODE 的SOURCE CONTROL 做版本控制 (1)

    原文网址:http://it.zhaozhao.info/archives/60469 有一次笔者在开心项目准备尝试新的练习的时候,赫然注意到在选择档案存放位置的时候,下面有个Source Contr ...

  5. golang安装卸载 linux+windows+raspberryPI 平台

    参考  https://golang.org/doc/install 自ECUG2013洗脑回来,就渴望早点接触Go 听着许式伟和谢孟军的演讲 发现go的网络库的确很强大,高负载利器,语言的一些精简导 ...

  6. [BILL WEI]stimulsoft reports DEMO自动生成模板

    stimulsoft reports是一款强大的报表开发工具,能够开发各式各样的报表. 对于初学者而言,任何报表开发,刚开始都是去模仿,熟练掌握之后,自己才能独立开发,而在报表开发实际过程中, 我们所 ...

  7. [Irving]DateTime格式处理大全

    DateTime dt = DateTime.Now;//    Label1.Text = dt.ToString();//2005-11-5 13:21:25//    Label2.Text = ...

  8. [Stephen]Export from Excel to ALM

    1.根据当前安装的ALM版本和Excel版本到https://hpln.hp.com/page/alm-excel-addin-page中对应的插件进行下载安装,安装时Excel需要关闭.安装成功后, ...

  9. vs212创建mvc3项目,添加ADO.NET实体数据模型时产生 XXXX.Desiger.cs 文件为空

    vs212创建mvc3项目,发现添加ADO.NET实体数据模型时,产生StoreDB.Desiger.cs文件为空 产生StoreDB.Desiger.cs文件为空 原因是,在vs2012中,添加AD ...

  10. 查询显示MSSQL表结构 [转]

    SELECT 表名 = Case When A.colorder= Then D.name Else '' End, 表说明 = Case When A.colorder= Then isnull(F ...