由于NumberPicker
小部件只能在API 11
及以上版本中使用,因此我最终使用了android-numberpicker库。虽然同一作者还提供了android-datepicker,但我无法使用它。
这是我的代码,只需将android-numberpicker添加为库即可。
XML布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/linlay1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/linlay2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal" >
<net.simonvt.numberpicker.NumberPicker
android:id="@+id/npYear"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</net.simonvt.numberpicker.NumberPicker>
<net.simonvt.numberpicker.NumberPicker
android:id="@+id/npMonth"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</net.simonvt.numberpicker.NumberPicker>
<net.simonvt.numberpicker.NumberPicker
android:id="@+id/npDay"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</net.simonvt.numberpicker.NumberPicker>
</LinearLayout>
<Button
android:id="@+id/btnDateFrom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="OK" />
</LinearLayout>
Java类:
package ir.aydangostar.supportdesk.activities;
import ir.aydangostar.supportdesk.R;
import ir.aydangostar.supportdesk.utils.JDF;
import net.simonvt.numberpicker.NumberPicker;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import com.actionbarsherlock.view.Window;
public class DatePickerActivity extends Activity {
public static final String G_DAY = "gDay";
public static final String G_MONTH = "gMonth";
public static final String G_YEAR = "gYear";
public static final String J_DAY = "jDay";
public static final String J_MONTH = "jMonth";
public static final String J_YEAR = "jYear";
private String[] monthNames = { "فروردین", "اردیبهشت", "خرداد", "تیر",
"مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند" };
private NumberPicker npDay;
private NumberPicker npMonth;
private NumberPicker npYear;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature((int) Window.FEATURE_NO_TITLE);
setContentView(R.layout.date_picker);
NumberPicker.OnValueChangeListener onChangeListener = new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker picker, int oldVal,
int newVal) {
if (picker == npMonth) {
if (newVal <= 6) {
npDay.setMaxValue(31);
} else {
npDay.setMaxValue(30);
}
}
}
};
npYear = (NumberPicker) findViewById(R.id.npYear);
npMonth = (NumberPicker) findViewById(R.id.npMonth);
npDay = (NumberPicker) findViewById(R.id.npDay);
Button btnOk = (Button) findViewById(R.id.btnDateFrom);
npMonth.setOnValueChangedListener(onChangeListener);
JDF jdf = new JDF();
int iranianYear = jdf.getIranianYear();
int iranianMonth = jdf.getIranianMonth();
int iranianDay = jdf.getIranianDay();
npYear.setMinValue(1390);
npYear.setMaxValue(iranianYear);
npYear.setWrapSelectorWheel(true);
npMonth.setMinValue(1);
npMonth.setMaxValue(12);
npMonth.setDisplayedValues(monthNames);
npDay.setMinValue(1);
npDay.setMaxValue(31);
npYear.setValue(iranianYear);
npMonth.setValue(iranianMonth);
npDay.setValue(iranianDay);
btnOk.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int newIrYear = npYear.getValue();
int newIrMonth = npMonth.getValue();
int newIrDay = npDay.getValue();
JDF jdf = new JDF();
jdf.setIranianDate(newIrYear, newIrMonth, newIrDay);
Intent returnIntent = new Intent();
returnIntent.putExtra(J_YEAR, newIrYear);
returnIntent.putExtra(J_MONTH, newIrMonth);
returnIntent.putExtra(J_DAY, newIrDay);
returnIntent.putExtra(G_YEAR, jdf.getGregorianYear());
returnIntent.putExtra(G_MONTH, jdf.getGregorianMonth());
returnIntent.putExtra(G_DAY, jdf.getGregorianDay());
setResult(RESULT_OK, returnIntent);
finish();
}
});
}
}
我使用了JDF
类进行日期转换,这是该类:
package ir.aydangostar.supportdesk.utils;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class JDF {
public JDF() {
Calendar calendar = new GregorianCalendar();
setGregorianDate(calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH) + 1,
calendar.get(Calendar.DAY_OF_MONTH));
}
public JDF(int year, int month, int day) {
setGregorianDate(year, month, day);
}
public int getIranianYear() {
return irYear;
}
public int getIranianMonth() {
return irMonth;
}
public int getIranianDay() {
return irDay;
}
public int getGregorianYear() {
return gYear;
}
public int getGregorianMonth() {
return gMonth;
}
public int getGregorianDay() {
return gDay;
}
public int getJulianYear() {
return juYear;
}
public int getJulianMonth() {
return juMonth;
}
public int getJulianDay() {
return juDay;
}
public String getIranianDate() {
return (irYear + "/" + irMonth + "/" + irDay);
}
public String getGregorianDate() {
return (gYear + "/" + gMonth + "/" + gDay);
}
public String getJulianDate() {
return (juYear + "/" + juMonth + "/" + juDay);
}
public String getWeekDayStr() {
String weekDayStr[] = { "Monday", "Tuesday", "Wednesday", "Thursday",
"Friday", "Saturday", "Sunday" };
return (weekDayStr[getDayOfWeek()]);
}
@Override
public String toString() {
return (getWeekDayStr() + ", Gregorian:[" + getGregorianDate()
+ "], Julian:[" + getJulianDate() + "], Iranian:["
+ getIranianDate() + "]");
}
public int getDayOfWeek() {
return (JDN % 7);
}
public void nextDay() {
JDN++;
JDNToIranian();
JDNToJulian();
JDNToGregorian();
}
public void nextDay(int days) {
JDN += days;
JDNToIranian();
JDNToJulian();
JDNToGregorian();
}
public void previousDay() {
JDN--;
JDNToIranian();
JDNToJulian();
JDNToGregorian();
}
public void previousDay(int days) {
JDN -= days;
JDNToIranian();
JDNToJulian();
JDNToGregorian();
}
public void setIranianDate(int year, int month, int day) {
irYear = year;
irMonth = month;
irDay = day;
JDN = IranianDateToJDN();
JDNToIranian();
JDNToJulian();
JDNToGregorian();
}
public void setGregorianDate(int year, int month, int day) {
gYear = year;
gMonth = month;
gDay = day;
JDN = gregorianDateToJDN(year, month, day);
JDNToIranian();
JDNToJulian();
JDNToGregorian();
}
public void setJulianDate(int year, int month, int day) {
juYear = year;
juMonth = month;
juDay = day;
JDN = julianDateToJDN(year, month, day);
JDNToIranian();
JDNToJulian();
JDNToGregorian();
}
private void IranianCalendar() {
int Breaks[] = { -61, 9, 38, 199, 426, 686, 756, 818, 1111, 1181, 1210,
1635, 2060, 2097, 2192, 2262, 2324, 2394, 2456, 3178 };
int jm, N, leapJ, leapG, jp, j, jump;
gYear = irYear + 621;
leapJ = -14;
jp = Breaks[0];
j = 1;
do {
jm = Breaks[j];
jump = jm - jp;
if (irYear >= jm) {
leapJ += (jump / 33 * 8 + (jump % 33) / 4);
jp = jm;
}
j++;
} while ((j < 20) && (irYear >= jm));
N = irYear - jp;
leapJ += (N / 33 * 8 + ((N % 33) + 3) / 4);
if (((jump % 33) == 4) && ((jump - N) == 4))
leapJ++;
leapG = gYear / 4 - ((gYear / 100 + 1) * 3 / 4) - 150;
march = 20 + leapJ - leapG;
if ((jump - N) < 6)
N = N - jump + ((jump + 4) / 33 * 33);
leap = (((N + 1) % 33) - 1) % 4;
if (leap == -1)
leap = 4;
}
private int IranianDateToJDN() {
IranianCalendar();
return (gregorianDateToJDN(gYear, 3, march) + (irMonth - 1) * 31
- irMonth / 7 * (irMonth - 7) + irDay - 1);
}
private void JDNToIranian() {
JDNToGregorian();
irYear = gYear - 621;
IranianCalendar();
int JDN1F = gregorianDateToJDN(gYear, 3, march);
int k = JDN - JDN1F;
if (k >= 0) {
if (k <= 185) {
irMonth = 1 + k / 31;
irDay = (k % 31) + 1;
return;
} else
k -= 186;
} else {
irYear--;
k += 179;
if (leap == 1)
k++;
}
irMonth = 7 + k / 30;
irDay = (k % 30) + 1;
}
private int julianDateToJDN(int year, int month, int day) {
return (year + (month - 8) / 6 + 100100) * 1461 / 4
+ (153 * ((month + 9) % 12) + 2) / 5 + day - 34840408;
}
private void JDNToJulian() {
int j = 4 * JDN + 139361631;
int i = ((j % 1461) / 4) * 5 + 308;
juDay = (i % 153) / 5 + 1;
juMonth = ((i / 153) % 12) + 1;
juYear = j / 1461 - 100100 + (8 - juMonth) / 6;
}
private int gregorianDateToJDN(int year, int month, int day) {
int jdn = (year + (month - 8) / 6 + 100100) * 1461 / 4
+ (153 * ((month + 9) % 12) + 2) / 5 + day - 34840408;
jdn = jdn - (year + 100100 + (month - 8) / 6) / 100 * 3 / 4 + 752;
return (jdn);
}
private void JDNToGregorian() {
int j = 4 * JDN + 139361631;
j = j + (((((4 * JDN + 183187720) / 146097) * 3) / 4) * 4 - 3908);
int i = ((j % 1461) / 4) * 5 + 308;
gDay = (i % 153) / 5 + 1;
gMonth = ((i / 153) % 12) + 1;
gYear = j / 1461 - 100100 + (8 - gMonth) / 6;
}
private int irYear;
private int irMonth;
private int irDay;
private int gYear;
private int gMonth;
private int gDay;
private int juYear;
private int juMonth;
private int juDay;
private int leap;
private int JDN;
private int march;
}
更新:您还需要在 styles.xml
文件中的 Theme
中为此小部件添加样式:
<item name="numberPickerStyle">@style/NPWidget.Holo.NumberPicker</item>
LogCat
输出,做完后告诉我。 - Nevercom