日积月累:调用Anroid私有API(隐藏DatePicker的日期选择)

本文介绍了一种在Android中利用反射机制隐藏DatePicker的日份选择器的方法,通过访问DatePicker的私有成员mDaySpinner并将其设置为不可见,从而实现信用卡有效期等场景下仅选择年份和月份的需求。

在我们日常开发过程中,可能会遇见如信用卡有效期选择的需求,它指需要选择年、月。但是系统控件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方法,在实际应用用也会碰到类似的需求。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值