2013-07-30 45 views
14

反正有DatePicker小工具與其他日曆系統?如何將DatePicker小部件與其他日曆系統一起提供?

我需要一個選擇器Jalali(波斯)日曆系統,但我不知道如何喂DatePicker與我的數據。

我已經研究了與DatePicker相關的方法,但找不到任何允許我這樣做的方法。

我還發現一個名爲android-wheel的自定義小部件,它的iOS-styled小部件並不感覺本機,但它允許我實現這一點。

所以反正是有有native-looking DatePicker小工具,可以讓我挑選日期爲Jalali日曆系統,並有一個月名在波斯

更新:我以前回答我的問題,並解決問題,但@Mohamad Amin創造了一個great library,我強烈建議你使用他的圖書館(感謝穆罕默德·阿明)。

+0

嗨Nevercom,你有問題嗎?我用這個問題的答案,但我得到例外,你能幫我嗎? –

+1

@Shayanpourvatan嗨沙燕,我實際上使用了我在下面提供的答案,你面臨的問題是什麼? – Nevercom

+0

感謝您的回覆,我有他的圖書館的問題,我認爲,錯誤發生在android-numberpicker上,得到resurce文件 –

回答

14

最近,我創建了一個新的具有波斯(回曆/沙姆西)的日期選擇器,它的設計是基於材料設計拾荒者。 你可以從the library's github page得到更多的信息。

一個截圖從DatePickerDialog:

A **screenshot** from the DatePickerDialog

+0

奇怪的是,Android默認不支持這個功能,因爲iOS上的這個功能可以強制日期選擇器顯示波斯日期。感謝您的貢獻。 – box

+0

@MohamadAmin。我無法在android studio中運行你的項目。我從github下載它。作爲提取過程它顯示「錯誤0 * 80010135路徑太長」。所以我如何使用你的cde? –

+0

@MinaDahesh將另一個文件夾中的zip壓縮文件解壓縮到路徑較短的位置,如C:\驅動器的根目錄。這個錯誤與Windows相關,並且Windows無法處理很長的路徑。 – Loqman

20

我結束了使用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) { 
     // TODO Auto-generated method stub 
     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 { 

    /** 
    * Main: The default constructor uses the current Gregorian date to 
    * initialize the other private memebers of the class (Iranian and Julian 
    * dates). 
    */ 
    public JDF() { 
     Calendar calendar = new GregorianCalendar(); 
     setGregorianDate(calendar.get(Calendar.YEAR), 
       calendar.get(Calendar.MONTH) + 1, 
       calendar.get(Calendar.DAY_OF_MONTH)); 
    } 

    /** 
    * Main: This constructor receives a Gregorian date and initializes the 
    * other private members of the class accordingly. 
    * 
    * @param year 
    *   int 
    * @param month 
    *   int 
    * @param day 
    *   int 
    * @return 
    */ 
    public JDF(int year, int month, int day) { 
     setGregorianDate(year, month, day); 
    } 

    /** 
    * getIranianYear: Returns the 'year' part of the Iranian date. 
    * 
    * @return int 
    */ 
    public int getIranianYear() { 
     return irYear; 
    } 

    /** 
    * getIranianMonth: Returns the 'month' part of the Iranian date. 
    * 
    * @return int 
    */ 
    public int getIranianMonth() { 
     return irMonth; 
    } 

    /** 
    * getIranianDay: Returns the 'day' part of the Iranian date. 
    * 
    * @return int 
    */ 
    public int getIranianDay() { 
     return irDay; 
    } 

    /** 
    * getGregorianYear: Returns the 'year' part of the Gregorian date. 
    * 
    * @return int 
    */ 
    public int getGregorianYear() { 
     return gYear; 
    } 

    /** 
    * getGregorianMonth: Returns the 'month' part of the Gregorian date. 
    * 
    * @return int 
    */ 
    public int getGregorianMonth() { 
     return gMonth; 
    } 

    /** 
    * getGregorianDay: Returns the 'day' part of the Gregorian date. 
    * 
    * @return int 
    */ 
    public int getGregorianDay() { 
     return gDay; 
    } 

    /** 
    * getJulianYear: Returns the 'year' part of the Julian date. 
    * 
    * @return int 
    */ 
    public int getJulianYear() { 
     return juYear; 
    } 

    /** 
    * getJulianMonth: Returns the 'month' part of the Julian date. 
    * 
    * @return int 
    */ 
    public int getJulianMonth() { 
     return juMonth; 
    } 

    /** 
    * getJulianDay() Returns the 'day' part of the Julian date. 
    * 
    * @return int 
    */ 
    public int getJulianDay() { 
     return juDay; 
    } 

    /** 
    * getIranianDate: Returns a string version of Iranian date 
    * 
    * @return String 
    */ 
    public String getIranianDate() { 
     return (irYear + "/" + irMonth + "/" + irDay); 
    } 

    /** 
    * getGregorianDate: Returns a string version of Gregorian date 
    * 
    * @return String 
    */ 
    public String getGregorianDate() { 
     return (gYear + "/" + gMonth + "/" + gDay); 
    } 

    /** 
    * getJulianDate: Returns a string version of Julian date 
    * 
    * @return String 
    */ 
    public String getJulianDate() { 
     return (juYear + "/" + juMonth + "/" + juDay); 
    } 

    /** 
    * getWeekDayStr: Returns the week day name. 
    * 
    * @return String 
    */ 
    public String getWeekDayStr() { 
     String weekDayStr[] = { "Monday", "Tuesday", "Wednesday", "Thursday", 
       "Friday", "Saturday", "Sunday" }; 
     return (weekDayStr[getDayOfWeek()]); 
    } 

    /** 
    * toString: Overrides the default toString() method to return all dates. 
    * 
    * @return String 
    */ 
    @Override 
    public String toString() { 
     return (getWeekDayStr() + ", Gregorian:[" + getGregorianDate() 
       + "], Julian:[" + getJulianDate() + "], Iranian:[" 
       + getIranianDate() + "]"); 
    } 

    /** 
    * getDayOfWeek: Returns the week day number. Monday=0..Sunday=6; 
    * 
    * @return int 
    */ 
    public int getDayOfWeek() { 
     return (JDN % 7); 
    } 

    /** 
    * nextDay: Go to next julian day number (JDN) and adjusts the other dates. 
    */ 
    public void nextDay() { 
     JDN++; 
     JDNToIranian(); 
     JDNToJulian(); 
     JDNToGregorian(); 
    } 

    /** 
    * nextDay: Overload the nextDay() method to accept the number of days to go 
    * ahead and adjusts the other dates accordingly. 
    * 
    * @param days 
    *   int 
    */ 
    public void nextDay(int days) { 
     JDN += days; 
     JDNToIranian(); 
     JDNToJulian(); 
     JDNToGregorian(); 
    } 

    /** 
    * previousDay: Go to previous julian day number (JDN) and adjusts the otehr 
    * dates. 
    */ 
    public void previousDay() { 
     JDN--; 
     JDNToIranian(); 
     JDNToJulian(); 
     JDNToGregorian(); 
    } 

    /** 
    * previousDay: Overload the previousDay() method to accept the number of 
    * days to go backward and adjusts the other dates accordingly. 
    * 
    * @param days 
    *   int 
    */ 
    public void previousDay(int days) { 
     JDN -= days; 
     JDNToIranian(); 
     JDNToJulian(); 
     JDNToGregorian(); 
    } 

    /** 
    * setIranianDate: Sets the date according to the Iranian calendar and 
    * adjusts the other dates. 
    * 
    * @param year 
    *   int 
    * @param month 
    *   int 
    * @param day 
    *   int 
    */ 
    public void setIranianDate(int year, int month, int day) { 
     irYear = year; 
     irMonth = month; 
     irDay = day; 
     JDN = IranianDateToJDN(); 
     JDNToIranian(); 
     JDNToJulian(); 
     JDNToGregorian(); 
    } 

    /** 
    * setGregorianDate: Sets the date according to the Gregorian calendar and 
    * adjusts the other dates. 
    * 
    * @param year 
    *   int 
    * @param month 
    *   int 
    * @param day 
    *   int 
    */ 
    public void setGregorianDate(int year, int month, int day) { 
     gYear = year; 
     gMonth = month; 
     gDay = day; 
     JDN = gregorianDateToJDN(year, month, day); 
     JDNToIranian(); 
     JDNToJulian(); 
     JDNToGregorian(); 
    } 

    /** 
    * setJulianDate: Sets the date according to the Julian calendar and adjusts 
    * the other dates. 
    * 
    * @param year 
    *   int 
    * @param month 
    *   int 
    * @param day 
    *   int 
    */ 
    public void setJulianDate(int year, int month, int day) { 
     juYear = year; 
     juMonth = month; 
     juDay = day; 
     JDN = julianDateToJDN(year, month, day); 
     JDNToIranian(); 
     JDNToJulian(); 
     JDNToGregorian(); 
    } 

    /** 
    * IranianCalendar: This method determines if the Iranian (Jalali) year is 
    * leap (366-day long) or is the common year (365 days), and finds the day 
    * in March (Gregorian Calendar)of the first day of the Iranian year 
    * ('irYear').Iranian year (irYear) ranges from (-61 to 3177).This method 
    * will set the following private data members as follows: leap: Number of 
    * years since the last leap year (0 to 4) Gy: Gregorian year of the 
    * begining of Iranian year march: The March day of Farvardin the 1st (first 
    * day of jaYear) 
    */ 
    private void IranianCalendar() { 
     // Iranian years starting the 33-year rule 
     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]; 
     // Find the limiting years for the Iranian year 'irYear' 
     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; 
     // Find the number of leap years from AD 621 to the begining of the 
     // current 
     // Iranian year in the Iranian (Jalali) calendar 
     leapJ += (N/33 * 8 + ((N % 33) + 3)/4); 
     if (((jump % 33) == 4) && ((jump - N) == 4)) 
      leapJ++; 
     // And the same in the Gregorian date of Farvardin the first 
     leapG = gYear/4 - ((gYear/100 + 1) * 3/4) - 150; 
     march = 20 + leapJ - leapG; 
     // Find how many years have passed since the last leap year 
     if ((jump - N) < 6) 
      N = N - jump + ((jump + 4)/33 * 33); 
     leap = (((N + 1) % 33) - 1) % 4; 
     if (leap == -1) 
      leap = 4; 
    } 

    /** 
    * IranianDateToJDN: Converts a date of the Iranian calendar to the Julian 
    * Day Number. It first invokes the 'IranianCalender' private method to 
    * convert the Iranian date to Gregorian date and then returns the Julian 
    * Day Number based on the Gregorian date. The Iranian date is obtained from 
    * 'irYear'(1-3100),'irMonth'(1-12) and 'irDay'(1-29/31). 
    * 
    * @return long (Julian Day Number) 
    */ 
    private int IranianDateToJDN() { 
     IranianCalendar(); 
     return (gregorianDateToJDN(gYear, 3, march) + (irMonth - 1) * 31 
       - irMonth/7 * (irMonth - 7) + irDay - 1); 
    } 

    /** 
    * JDNToIranian: Converts the current value of 'JDN' Julian Day Number to a 
    * date in the Iranian calendar. The caller should make sure that the 
    * current value of 'JDN' is set correctly. This method first converts the 
    * JDN to Gregorian calendar and then to Iranian calendar. 
    */ 
    private void JDNToIranian() { 
     JDNToGregorian(); 
     irYear = gYear - 621; 
     IranianCalendar(); // This invocation will update 'leap' and 'march' 
     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; 
    } 

    /** 
    * julianDateToJDN: Calculates the julian day number (JDN) from Julian 
    * calendar dates. This integer number corresponds to the noon of the date 
    * (i.e. 12 hours of Universal Time). This method was tested to be good 
    * (valid) since 1 March, -100100 (of both calendars) up to a few millions 
    * (10^6) years into the future. The algorithm is based on D.A.Hatcher, 
    * Q.Jl.R.Astron.Soc. 25(1984), 53-55 slightly modified by K.M. Borkowski, 
    * Post.Astron. 25(1987), 275-279. 
    * 
    * @param year 
    *   int 
    * @param month 
    *   int 
    * @param day 
    *   int 
    * @return int 
    */ 
    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; 
    } 

    /** 
    * JDNToJulian: Calculates Julian calendar dates from the julian day number 
    * (JDN) for the period since JDN=-34839655 (i.e. the year -100100 of both 
    * calendars) to some millions (10^6) years ahead of the present. The 
    * algorithm is based on D.A. Hatcher, Q.Jl.R.Astron.Soc. 25(1984), 53-55 
    * slightly modified by K.M. Borkowski, Post.Astron. 25(1987), 275-279). 
    */ 
    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; 
    } 

    /** 
    * gergorianDateToJDN: Calculates the julian day number (JDN) from Gregorian 
    * calendar dates. This integer number corresponds to the noon of the date 
    * (i.e. 12 hours of Universal Time). This method was tested to be good 
    * (valid) since 1 March, -100100 (of both calendars) up to a few millions 
    * (10^6) years into the future. The algorithm is based on D.A.Hatcher, 
    * Q.Jl.R.Astron.Soc. 25(1984), 53-55 slightly modified by K.M. Borkowski, 
    * Post.Astron. 25(1987), 275-279. 
    * 
    * @param year 
    *   int 
    * @param month 
    *   int 
    * @param day 
    *   int 
    * @return int 
    */ 
    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); 
    } 

    /** 
    * JDNToGregorian: Calculates Gregorian calendar dates from the julian day 
    * number (JDN) for the period since JDN=-34839655 (i.e. the year -100100 of 
    * both calendars) to some millions (10^6) years ahead of the present. The 
    * algorithm is based on D.A. Hatcher, Q.Jl.R.Astron.Soc. 25(1984), 53-55 
    * slightly modified by K.M. Borkowski, Post.Astron. 25(1987), 275-279). 
    */ 
    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; // Year part of a Iranian date 
    private int irMonth; // Month part of a Iranian date 
    private int irDay; // Day part of a Iranian date 
    private int gYear; // Year part of a Gregorian date 
    private int gMonth; // Month part of a Gregorian date 
    private int gDay; // Day part of a Gregorian date 
    private int juYear; // Year part of a Julian date 
    private int juMonth; // Month part of a Julian date 
    private int juDay; // Day part of a Julian date 
    private int leap; // Number of years since the last leap year (0 to 4) 
    private int JDN; // Julian Day Number 
    private int march; // The march day of Farvardin the first (First day of 
         // jaYear) 
} // End of Class 'Main' 

UPDATE:也你需要爲這個小部件添加樣式到你的Themestyles.xml文件:

<item name="numberPickerStyle">@style/NPWidget.Holo.NumberPicker</item> 
+0

感謝很多,非常有用的實現。 (^ _-) –

+0

@ShaahinAshayeri我很高興幫助 – Nevercom

+0

@Nevercom,非常感謝您的代碼。但是我在import部分有問題,因爲我是android編程新手,終於可以做到了。現在我想在這個日期設置textview的內容,我該怎麼做? –

1

從現在開始,你可以使用基於DroidPersianCalendar應用PersianCaldroid庫。我已經拍攝了這個夢幻般的應用程序,並對其進行了許多更改,將其變爲圖書館。我還添加了許多苛刻的功能來克服自己的需求,但在大多數應用程序中也很常見。這個庫爲您提供波斯日曆對話框,這是日期選擇器,以及波斯日曆片段,它是用於在波斯日曆上表示用戶事件的小部件。波斯日曆片段具有基本的API,例如將日期添加到日期中以定製顏色來圈選,設置自定義字體,日期點擊偵聽器,月份更改偵聽器等。

有關更多信息,請參閱庫的git存儲庫https://github.com/dariushm2/PersianCaldroid

相關問題