android中DatePickerDialog只顯示年月
阿新 • • 發佈:2019-01-01
今天專案中碰到一個需求,就是在填信用卡的時候,需要填信用卡的有效期(包括年月,沒有日),但是正常的日期選擇器都是有日的。。。。另外專案中希望彈出個dialog來顯示日期選擇器,所以這裡採用DatePickerDialog。
實現的效果是:無論在什麼語言的系統下,都只顯示年月,並且月在前,年在後(在英文的系統中,是mmddyy的順序,但是在中文系統中是yymmdd的順序)
看下程式碼:
final Calendar calendar = Calendar.getInstance(); int yy = calendar.get(Calendar.YEAR); int mm = calendar.get(Calendar.MONTH); int dd = calendar.get(Calendar.DAY_OF_MONTH); DatePickerDialog dlg = new DatePickerDialog(new ContextThemeWrapper(getActivity(), android.R.style.Theme_Holo_Light_Dialog_NoActionBar), null, yy, mm, dd) { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LinearLayout mSpinners = (LinearLayout) findViewById(getContext().getResources().getIdentifier("android:id/pickers", null, null)); if (mSpinners != null) { NumberPicker mMonthSpinner = (NumberPicker) findViewById(getContext().getResources().getIdentifier("android:id/month", null, null)); NumberPicker mYearSpinner = (NumberPicker) findViewById(getContext().getResources().getIdentifier("android:id/year", null, null)); mSpinners.removeAllViews(); if (mMonthSpinner != null) { mSpinners.addView(mMonthSpinner); } if (mYearSpinner != null) { mSpinners.addView(mYearSpinner); } } View dayPickerView = findViewById(getContext().getResources().getIdentifier("android:id/day", null, null)); if(dayPickerView != null){ dayPickerView.setVisibility(View.GONE); } } @Override public void onDateChanged(DatePicker view, int year, int month, int day) { super.onDateChanged(view, year, month, day); setTitle("請選擇信用卡有效期"); } }; dlg.setTitle("請選擇信用卡有效期");
執行上述程式碼的效果是這樣的:
怎麼樣,是不是好看了很多?效果的變化來源於在宣告DatePickerDialog的時候,傳了一個主題theme給它:
new ContextThemeWrapper(getActivity(),android.R.style.Theme_Holo_Light_Dialog_NoActionBar)
如果沒有傳入style的話,長這個樣子:
現在再來看看,是如何做到隱藏日的選擇器,只顯示年和月的,並且讓月顯示在年前面的。
在DatePickerDialog中,也是有一個DatePicker的,現在來看下DatePicker的程式碼,我找到了他引用的layout資源:
開啟該資原始檔:
preview的效果是:<?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 "pickers" layout 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:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_gravity="center_horizontal" android:orientation="horizontal" android:gravity="center"> <LinearLayout android:id="@+id/pickers" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="horizontal" android:gravity="center"> <!-- Month --> <NumberPicker android:id="@+id/month" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="1dip" android:layout_marginEnd="1dip" android:focusable="true" android:focusableInTouchMode="true" /> <!-- Day --> <NumberPicker android:id="@+id/day" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="1dip" android:layout_marginEnd="1dip" android:focusable="true" android:focusableInTouchMode="true" /> <!-- Year --> <NumberPicker android:id="@+id/year" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="1dip" android:layout_marginEnd="1dip" android:focusable="true" android:focusableInTouchMode="true" /> </LinearLayout> <!-- calendar view --> <CalendarView android:id="@+id/calendar_view" android:layout_width="245dip" android:layout_height="280dip" android:layout_marginStart="44dip" android:layout_weight="1" android:focusable="true" android:focusableInTouchMode="true" android:visibility="gone" /> </LinearLayout>
看到了吧,其實內部是三個NumberPicker,外部的佈局是LinearLayout,橫向排列。那我在想隱藏日的選擇器很簡單,直接獲取該view,然後設定為gone就好了。(看上面的程式碼你就懂了,這裡不說明了)
但是再一看程式碼,發現該layout原來的順序就是month-day-year,那為什麼中文系統中會修改順序呢?繼續找程式碼!
往下翻找,找到了一個reorderSpinner的方法,原來就是這段程式碼,根據當前系統的語言,來重排序了!
/**
* Reorders the spinners according to the date format that is
* explicitly set by the user and if no such is set fall back
* to the current locale's default format.
*/
private void reorderSpinners() {
mSpinners.removeAllViews();
// We use numeric spinners for year and day, but textual months. Ask icu4c what
// order the user's locale uses for that combination. http://b/7207103.
String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), "yyyyMMMdd");
char[] order = ICU.getDateFormatOrder(pattern);
final int spinnerCount = order.length;
for (int i = 0; i < spinnerCount; i++) {
switch (order[i]) {
case 'd':
mSpinners.addView(mDaySpinner);
setImeOptions(mDaySpinner, spinnerCount, i);
break;
case 'M':
mSpinners.addView(mMonthSpinner);
setImeOptions(mMonthSpinner, spinnerCount, i);
break;
case 'y':
mSpinners.addView(mYearSpinner);
setImeOptions(mYearSpinner, spinnerCount, i);
break;
default:
throw new IllegalArgumentException(Arrays.toString(order));
}
}
}
看完這段程式碼,我就大概知道怎麼重排年和月了,看最上面我提供的實現程式碼,你就應該知道了,不再贅述了。