Android中DatePicker只显示年月的方法
16lz
2021-01-24
最近项目中有一个选择信用卡有效期的功能,只需要选择年月,但是Android原生的DatePicker默认是可以选择年月日的,所以我们要做下特殊的处理,
并且Android5.0以上和以下的版本的处理方式是不同的
关于5.0以上和以下版本为什么这么处理的原因,详见so:http://stackoverflow.com/questions/26460682/custom-date-picker-dialog-in-android-lollipop
贴上代码:
dialog_date_picker.xml
<?xml version="1.0" encoding="utf-8"?>
DatePickerDialog.java
import android.app.AlertDialog;import android.content.Context;import android.content.DialogInterface;import android.content.DialogInterface.OnClickListener;import android.content.res.Resources;import android.os.Build;import android.os.Bundle;import android.view.LayoutInflater;import android.view.View;import android.widget.DatePicker;import android.widget.DatePicker.OnDateChangedListener;import java.lang.reflect.Field;public class DatePickerDialog extends AlertDialog implements OnClickListener, OnDateChangedListener { private static final String START_YEAR = "start_year"; private static final String START_MONTH = "start_month"; private static final String START_DAY = "start_day"; private final DatePicker mDatePickerStart; private final OnDateSetListener mCallBack; public interface OnDateSetListener { void onDateSet(DatePicker startDatePicker, int startYear, int startMonthOfYear, int startDayOfMonth); } public DatePickerDialog(Context context, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth) { this(context, 0, callBack, year, monthOfYear, dayOfMonth); } public DatePickerDialog(Context context, int theme, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth) { super(context, theme); mCallBack = callBack; Context themeContext = getContext(); setButton(BUTTON_POSITIVE, "确 定", this); setButton(BUTTON_NEGATIVE, "取 消", this); setIcon(0); LayoutInflater inflater = (LayoutInflater) themeContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(R.layout.dialog_date_picker, null); setView(view); mDatePickerStart = (DatePicker) view.findViewById(R.id.datePickerStart); mDatePickerStart.init(year, monthOfYear, dayOfMonth, this); hideDay(mDatePickerStart); } private void hideDay(DatePicker mDatePicker) { try { /* 处理android5.0以上的特殊情况 */ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { int daySpinnerId = Resources.getSystem().getIdentifier("day", "id", "android"); if (daySpinnerId != 0) { View daySpinner = mDatePicker.findViewById(daySpinnerId); if (daySpinner != null) { daySpinner.setVisibility(View.GONE); } } } else { Field[] datePickerfFields = mDatePicker.getClass().getDeclaredFields(); for (Field datePickerField : datePickerfFields) { if ("mDaySpinner".equals(datePickerField.getName()) || ("mDayPicker").equals(datePickerField.getName())) { datePickerField.setAccessible(true); Object dayPicker = new Object(); try { dayPicker = datePickerField.get(mDatePicker); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } ((View) dayPicker).setVisibility(View.GONE); } } } } catch (Exception e) { e.printStackTrace(); } } public void onClick(DialogInterface dialog, int which) { if (which == BUTTON_POSITIVE) tryNotifyDateSet(); } @Override public void onDateChanged(DatePicker view, int year, int month, int day) { if (view.getId() == R.id.datePickerStart) mDatePickerStart.init(year, month, day, this); } public DatePicker getDatePickerStart() { return mDatePickerStart; } public void updateStartDate(int year, int monthOfYear, int dayOfMonth) { mDatePickerStart.updateDate(year, monthOfYear, dayOfMonth); } private void tryNotifyDateSet() { if (mCallBack != null) { mDatePickerStart.clearFocus(); mCallBack.onDateSet(mDatePickerStart, mDatePickerStart.getYear(), mDatePickerStart.getMonth(), mDatePickerStart.getDayOfMonth()); } } @Override protected void onStop() { super.onStop(); } @Override public Bundle onSaveInstanceState() { Bundle state = super.onSaveInstanceState(); state.putInt(START_YEAR, mDatePickerStart.getYear()); state.putInt(START_MONTH, mDatePickerStart.getMonth()); state.putInt(START_DAY, mDatePickerStart.getDayOfMonth()); return state; } @Override public void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); int start_year = savedInstanceState.getInt(START_YEAR); int start_month = savedInstanceState.getInt(START_MONTH); int start_day = savedInstanceState.getInt(START_DAY); mDatePickerStart.init(start_year, start_month, start_day, this); }}
MainActivity.java
import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.DatePicker;import android.widget.TextView;import java.util.Calendar;public class MainActivity extends Activity { private Button mShowDateBTN; private TextView mSelectDateTV; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mShowDateBTN = (Button) findViewById(R.id.btn_show_date); mSelectDateTV = (TextView) findViewById(R.id.tv_select_date); mShowDateBTN.setOnClickListener(new View.OnClickListener() { Calendar c = Calendar.getInstance(); @Override public void onClick(View v) { new DatePickerDialog(MainActivity.this, 0, new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker startDatePicker, int startYear, int startMonthOfYear, int startDayOfMonth) { String textString = String.format("选择年月:%d-%d\n", startYear, startMonthOfYear + 1); mSelectDateTV.setText(textString); } }, c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DATE)).show(); } }); }}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
更多相关文章
- Android(安卓)SettingProvider详解
- Gradle sync failed: Cause: error in opening zip file 几个可
- RubyMotion 3发布,支持Android和WatchKit
- Android开发环境搭建及常见问题解决方法
- Android(安卓)4.0.1 源码下载,模拟器编译和运行
- Android(安卓)L为什么不用Android(安卓)5.0的版本号
- android初次学习(android studio安装及注意事项 1.5版本)
- Android之Android(安卓)Studio三种方式导入外部资源 以及 报错处
- 【Android开发】构建第一个APP