在我们日常开发过程中,可能会遇见如信用卡有效期选择的需求,它指需要选择年、月。但是系统控件DatePicker默认是支持年、月和日的选择,如下图:
那么,我们如何才能使得日期选择器不显示呢,我们先来看看DatePicker的源代码:
在DatePicker源码中,拥有一个private成员NumberPicker变量mDaySpinner,这个应该就是用于日期选择的控件了。那么对于private的访问权限,当然难不倒我们,因为我们有强大的“反射”功能,下面看看实例代码;
MainActivity.java文件:
public classMainActivity extends Activity {
privateButton button;
@Override
protectedvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button= (Button) findViewById(R.id.button);
button.setOnClickListener(newOnClickListener() {
@Override
publicvoid onClick(View v) {
DatePickerdatePicker = new DatePicker(MainActivity.this);
datePicker.setCalendarViewShown(false);
//通过反射机制,访问private的mDaySpinner成员,并隐藏它
try {
Field daySpinner =datePicker.getClass().getDeclaredField("mDaySpinner");
daySpinner.setAccessible(true);
((View)daySpinner.get(datePicker)).setVisibility(View.GONE);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
CalendarminCalendar = Calendar.getInstance();
minCalendar.set(Calendar.HOUR_OF_DAY,0);
minCalendar.set(Calendar.MINUTE,0);
minCalendar.set(Calendar.SECOND,0);
datePicker.setMinDate(minCalendar.getTimeInMillis());
CalendarmaxCalendar = Calendar.getInstance();
maxCalendar.add(Calendar.YEAR,1);
datePicker.setMaxDate(maxCalendar.getTimeInMillis());
CalendarcurCalendar = Calendar.getInstance();
datePicker.init(curCalendar.get(Calendar.YEAR),
curCalendar.get(Calendar.MONTH),
curCalendar.get(Calendar.DAY_OF_MONTH),null);
AlertDialog.Builderbuilder = new AlertDialog.Builder(MainActivity.this);
builder.setView(datePicker);
builder.setTitle("请选择有效期");
builder.setPositiveButton("确定", null);
AlertDialogdialog = builder.create();
dialog.setCanceledOnTouchOutside(true);
dialog.show();
}
});
}
}
好了,运行一下,看看效果:
该实例向大家展示了如何使用反射调用Android没有公开的API方法,在实际应用用也会碰到类似的需求。