android5.0及以上的版本中,DatePicker 在 calendar 模式下,自带了一个快速切换年份和日期的头部:
隐藏这个头部的原理就是找到相应的 View 并设置 Visibility 为 Gone.
在 DatePicker 源码中,如果 mode 使用的是 Calendar 则会调用 createCalendarUIDelegate 方法。
switch (mode) {
case MODE_CALENDAR:
mDelegate = createCalendarUIDelegate(context, attrs, defStyleAttr, defStyleRes);
break;
case MODE_SPINNER:
default:
mDelegate = createSpinnerUIDelegate(context, attrs, defStyleAttr, defStyleRes);
break;
}
createCalendarUIDelegate 则会返回一个 DatePickerSpinnerDelegate
private DatePickerDelegate createCalendarUIDelegate(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
return new DatePickerCalendarDelegate(this, context, attrs, defStyleAttr, defStyleRes);
}
其中 DatePickerCalendarDelegate 使用的布局文件为 R.layout.date_picker_material
final int layoutResourceId = a.getResourceId(R.styleable.DatePicker_internalLayout, R.layout.date_picker_material);
// Set up and attach container.
mContainer = (ViewGroup) inflater.inflate(layoutResourceId, mDelegator, false);
mDelegator.addView(mContainer);
R.layout.date_picker_material 的内容为
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<include
layout="@layout/date_picker_header_material"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<include
layout="@layout/date_picker_view_animator_material"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
第一个 include 的布局就是头部了,接下来要做的就是找到这个 View 然后隐藏掉。
ViewGroup rootView = (ViewGroup) datePicker.getChildAt(0);
if (rootView == null) {
return;
}
View headerView = rootView.getChildAt(0);
if (headerView == null) {
return;
}
headerView.setVisibility(View.GONE);
考虑到安全性,为了保证隐藏掉的 View 就是想要隐藏的头部,可以加上 id 的判断。
- 5.0中,头部根布局的 id 为 day_picker_selector_layout
- 6.0及以上,头部根布局的 id 为 date_picker_header
设置为 gone 之后还要动态的调整一下布局,所以最后的方法为:
private void hideDatePickerHeader(DatePicker datePicker) {
ViewGroup rootView = (ViewGroup) datePicker.getChildAt(0);
if (rootView == null) {
return;
}
View headerView = rootView .getChildAt(0);
if (headerView == null) {
return;
}
//5.0+
int headerId = context.getResources().getIdentifier("day_picker_selector_layout", "id", "android");
if (headerId == headerView.getId()) {
headerView.setVisibility(View.GONE);
ViewGroup.LayoutParams layoutParamsRoot = rootView.getLayoutParams();
layoutParamsRoot.width = ViewGroup.LayoutParams.WRAP_CONTENT;
rootView.setLayoutParams(layoutParamsRoot);
ViewGroup animator = (ViewGroup) rootView.getChildAt(1);
ViewGroup.LayoutParams layoutParamsAnimator = animator.getLayoutParams();
layoutParamsAnimator.width = ViewGroup.LayoutParams.WRAP_CONTENT;
animator.setLayoutParams(layoutParamsAnimator);
View child = animator.getChildAt(0);
ViewGroup.LayoutParams layoutParamsChild = child.getLayoutParams();
layoutParamsChild.width = ViewGroup.LayoutParams.WRAP_CONTENT;
child.setLayoutParams(layoutParamsChild );
return;
}
//6.0+
headerId = context.getResources().getIdentifier("date_picker_header", "id", "android");
if (headerId == headerView.getId()) {
headerView.setVisibility(View.GONE);
}
}
最终效果: