本文解决了android 原生Datapicker无法改变文字大小的问题,通过反射实现 废话不多说,直接上代码
import android.app.Dialog;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.os.Build;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Display;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.NumberPicker;
import androidx.annotation.ColorInt;
import androidx.appcompat.app.AlertDialog;
import androidx.databinding.DataBindingUtil;
import com.blankj.utilcode.util.ConvertUtils;
import com.blankj.utilcode.util.LogUtils;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
/**
* Created by chen
* on Date: 2020/8/2
* on Time: 20:24
* on Describe:对 DatePicker 和 AlertDialog 包装生成的自定义 日期 选择器dialog
*/
public class CustomDatePickerAlertDialog {
private final Context context;
private final AlertDialog dialog;//dialog对象
private View dialogView; //dialogView
private CustomDatepickerDialogAntBinding dialogBinding;
private int year;
private int month;
private int day;
/**
* @param context 上下文
* @param year 年份,具体年份 (此处三个日期 同 Calendar 中取出的值)
* @param monthOfYear 月份,取值 0-11
* @param dayOfMonth 天,取值1-31
*/
public CustomDatePickerAlertDialog(Context context, int year, int monthOfYear, int dayOfMonth) {
this.context = context;
AlertDialog.Builder builder = new AlertDialog.Builder(context);
dialog = builder.create();
initDate(year, monthOfYear, dayOfMonth);
initDialogView();
}
/**
* 初始化日期,如果外部在初始化传递的都是0 ,则使用该日期去初始化DatePicker
*
* @param year 年份,具体年份 (此处三个日期 同 Calendar 中取出的值)
* @param monthOfYear 月份,取值 0-11
* @param dayOfMonth 天,取值1-31
*/
private void initDate(int year, int monthOfYear, int dayOfMonth) {
if (year == 0 || dayOfMonth == 0) {
Calendar calendar = Calendar.getInstance();
year = calendar.get(Calendar.YEAR);
month = calendar.get(Calendar.MONTH); //取值 0-11
day = calendar.get(Calendar.DAY_OF_MONTH);
} else {
this.year = year;
month = monthOfYear;
day = dayOfMonth;
}
LogUtils.e("初始化时的年月日是:", year + "/" + (month + 1) + "/" + day);
}
private void initDialogView() {
LayoutInflater inflater = LayoutInflater.from(context);
dialogBinding = DataBindingUtil.inflate(inflater, R.layout.custom_datepicker_dialog_ant, null, false);
dialogView = dialogBinding.getRoot();
dialog.setView(dialogView); //设置view
if (Build.VERSION.SDK_INT >= 21) { //21之前设置背景的时候依旧会有白色边框
setBackGroundDrawableResource(0);
}
setDimAmount(0.15f);
initDatePicker();
}
private void initDatePicker() {
DatePicker datePicker = dialogBinding.datePickerCustomDatePickerDialog;
datePicker.init(year, month, day, new DatePicker.OnDateChangedListener() {
@Override
public void onDateChanged(DatePicker view, int selectedyear, int monthOfYear, int dayOfMonth) {
year = selectedyear;
month = monthOfYear;
day = dayOfMonth;
resizePikcer(view);
}
});
resizePikcer(datePicker);
}
/**
* 调整FrameLayout大小
* @param tp
*/
private void resizePikcer(FrameLayout tp){
List<NumberPicker> npList = findNumberPicker(tp);
for(NumberPicker np:npList){
resizeNumberPicker(np);
np.performClick();
}
}
/**
* 得到viewGroup里面的numberpicker组件
* @param viewGroup
* @return
*/
private List<NumberPicker> findNumberPicker(ViewGroup viewGroup){
List<NumberPicker> npList = new ArrayList<>();
View child = null;
if(null != viewGroup){
for(int i = 0;i<viewGroup.getChildCount();i++){
child = viewGroup.getChildAt(i);
if(child instanceof NumberPicker){
npList.add((NumberPicker)child);
}
else if(child instanceof LinearLayout){
List<NumberPicker> result = findNumberPicker((ViewGroup)child);
if(result.size()>0){
return result;
}
}
}
}
return npList;
}
/**
* 调整numberpicker大小
*/
private void resizeNumberPicker(NumberPicker np){
setNumberPickerText(np);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ConvertUtils.dp2px(280)/3, ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(10, 0, 10, 0);
np.setLayoutParams(params);
}
public EditText setNumberPickerText(NumberPicker numberPicker){
Field field ;
try{
field = numberPicker.getClass().getDeclaredField("mInputText");
field.setAccessible(true);
try {
((EditText)field.get(numberPicker)).setTextSize(24);
((EditText)field.get(numberPicker)).setClickable(false);
((EditText)field.get(numberPicker)).setFocusable(false);
return ((EditText)field.get(numberPicker));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
return null;
}
/**
* 设置picker之间的间距
*/
private void setPickerMargin(DatePicker picker) {
LinearLayout.LayoutParams p= (LinearLayout.LayoutParams) picker.getLayoutParams();
p.width = ConvertUtils.dp2px(280)/3;
p.height =ConvertUtils.dp2px(30);
p.setMargins(10,0,10,0);
if(Build.VERSION.SDK_INT> Build.VERSION_CODES.JELLY_BEAN_MR1){
p.setMarginStart(0);
p.setMarginEnd(0);
}
picker.setLayoutParams(p);
}
/**
* 展示dialog
*/
public void show() {
if (dialog != null && !dialog.isShowing()) {
dialog.show();
}
}
/**
* 关闭dialog
*/
public void dismissDialog() {
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
}
}
/**
* 返回dialog的view对象
*/
public View getDialogView() {
return dialogView;
}
/**
* 返回dialog对象
*/
public Dialog getDialogObj() {
return dialog;
}
/**
* 设置dialog的背景--传入资源id
*/
public void setBackGroundDrawableResource(int drawableResId) {
Window window = dialog.getWindow();
if (null != window) {
if (0 == drawableResId) {
drawableResId = R.mipmap.img_dialog;
}
window.setBackgroundDrawableResource(drawableResId);
}
}
/**
* 设置背景图--传入drawable对象
*/
public void setBackGroundDrawable(Drawable drawable) {
Window window = dialog.getWindow();
if (null != window) {
if (null == drawable) {
// drawable = context.getResources().getDrawable(R.drawable.shape_bk_rect_cornor_white);
}
window.setBackgroundDrawable(drawable);
}
}
/**
* 设置背景图--根据传入的color值生成对应填充色的圆角背景图
*
* @param colorInt 色值
* @param conorRadiusPx 圆角半径,单位PX
*/
public void setBackGroundDrawable(
@ColorInt
int colorInt, int conorRadiusPx) {
GradientDrawable drawable = new GradientDrawable();
drawable.setColor(colorInt);
drawable.setCornerRadius(conorRadiusPx);
drawable.setShape(GradientDrawable.RECTANGLE);
Window window = dialog.getWindow();
if (null != window) {
window.setBackgroundDrawable(drawable);
}
}
/**
* 设置确定按钮的问题及其点击事件,
* 传入的事件监听为null时,会关闭dialog
*/
public void setPositiveButton(String des, final AntDatePickerDialogClickListener clickListener) {
dialogBinding.setIsConfirmBtShow(true);
dialogBinding.btnConfirm.setText(des);
dialogBinding.btnConfirm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (null != clickListener) {
clickListener.onClick(v, year, month + 1, day);
}
dismissDialog();
}
});
}
public void setPositiveButton(int strResId, final AntDatePickerDialogClickListener clickListener) {
dialogBinding.setIsConfirmBtShow(true);
dialogBinding.btnConfirm.setText(context.getResources().getString(strResId));
dialogBinding.btnConfirm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (null != clickListener) {
clickListener.onClick(v, year, month + 1, day);
}
dismissDialog();
}
});
}
/**
* 取消按钮的点击事件
*/
public void setNegativeButton(String des, final AntDatePickerDialogClickListener clickListener) {
dialogBinding.setIsCancleBtShow(true);
dialogBinding.btnCancel.setText(des);
dialogBinding.btnCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (null != clickListener) {
clickListener.onClick(v, year, month + 1, day);
}
dismissDialog();
}
});
}
public void setNegativeButton(int strResId, final AntDatePickerDialogClickListener clickListener) {
dialogBinding.setIsCancleBtShow(true);
dialogBinding.btnCancel.setText(context.getResources().getString(strResId));
dialogBinding.btnCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (null != clickListener) {
clickListener.onClick(v, year, month + 1, day);
}
dismissDialog();
}
});
}
/**
* 设置确认按钮的文字颜色
*/
public void setPositiveButtonTextColor(
@ColorInt
int color) {
dialogBinding.btnConfirm.setTextColor(color);
}
public void setPositiveButtonTextColor(ColorStateList colorStateList) {
dialogBinding.btnConfirm.setTextColor(colorStateList);
}
/**
* 设置取消按钮的字体颜色
*/
public void setNegativeButtonTextColor(
@ColorInt
int color) {
dialogBinding.btnCancel.setTextColor(color);
}
public void setNegativeButtonTextColor(ColorStateList colorStateList) {
dialogBinding.btnCancel.setTextColor(colorStateList);
}
/**
* 设置标题
*/
public void setTitle(String title) {
dialogBinding.setIsTitleShow(true);
dialogBinding.tvTitle.setText(title);
}
public void setTitle(int strResId) {
dialogBinding.setIsTitleShow(true);
dialogBinding.tvTitle.setText(context.getResources().getString(strResId));
}
/**
* 更改主标题文字的大小
*/
public void setTitleTextSize(int sizeSP) {
if (sizeSP <= 0) {
sizeSP = 14;
}
dialogBinding.tvTitle.setTextSize(sizeSP);
}
/**
* 修改Dialog阴影区域的灰度百分比
* <p>
* 取值 0-1.
*/
public void setDimAmount(float rate) {
Window window = dialog.getWindow();
if (null != window) {
if (rate < 0) {
rate = 0;
} else if (rate > 1) {
rate = 1;
}
window.setDimAmount(rate);
}
}
/**
* 点击非内容区域是否可以关闭
*/
public void setCancelable(boolean bool) {
dialog.setCancelable(bool);
}
/**
* 对外暴露点击事件的自定义接口
*/
public interface AntDatePickerDialogClickListener {
void onClick(View view, int selectedYear, int selectedMonth, int selectedDay);
}
}
这里是布局文件
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<import type="android.view.View"/>
<variable name="isTitleShow" type="Boolean"/>
<variable name="isSubTitleShow" type="Boolean"/>
<variable name="isCancleBtShow" type="Boolean"/>
<variable name="isConfirmBtShow" type="Boolean"/>
<variable name="isSkipBtShow" type="Boolean"/>
</data>
<!--外面这层RL的实际作用是,让内部的LL布局参数生效,因为在填充布局时parent传递的null,所以被填充布局的第一层布局参数不生效,从第二层起才生效-->
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/ll_root_antDialog"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@mipmap/img_dialog"
android:layout_centerInParent="true"
android:orientation="vertical"
android:showDividers="middle">
<!--主标题-->
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:includeFontPadding="false"
android:text="选择日期"
android:padding="@dimen/dp_10"
android:textColor="@color/white"
android:textSize="23sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="@mipmap/ic_select_main_bg"
android:layout_marginTop="20dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="28dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:textColor="@color/white"
android:textSize="16.67sp"
android:text="年"/>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:textColor="@color/white"
android:textSize="16.67sp"
android:text="月"/>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:textColor="@color/white"
android:textSize="16.67sp"
android:text="日"/>
</LinearLayout>
<DatePicker
android:id="@+id/datePicker_customDatePickerDialog"
style="@android:style/Widget.DatePicker"
android:layout_width="match_parent"
android:layout_height="96dp"
android:yearListSelectorColor="@color/light_gray"
android:calendarViewShown="false"
android:background="@color/white"
android:layout_marginLeft="@dimen/dp_10"
android:layout_marginRight="@dimen/dp_10"
android:datePickerMode="spinner"/>
</LinearLayout>
<!--底部按钮-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:showDividers="middle"
android:layout_marginTop="18dp"
android:gravity="center_horizontal"
android:visibility="@{isConfirmBtShow||isCancleBtShow?View.VISIBLE:View.GONE}">
<top.jnsh.health.view.SoundButton
android:id="@+id/btn_confirm"
android:layout_width="129dp"
android:layout_height="45dp"
android:layout_gravity="center"
android:background="@drawable/select_confirm_btn_bg"
android:gravity="center"
android:text="确认"
android:textColor="@drawable/select_confirm_btn_text_bg"
android:textSize="18sp" />
<top.jnsh.health.view.SoundButton
android:id="@+id/btn_cancel"
android:layout_width="129dp"
android:layout_height="45dp"
android:layout_gravity="center"
android:background="@drawable/select_confirm_btn_bg"
android:gravity="center"
android:layout_marginStart="22dp"
android:text="取消"
android:textColor="@drawable/select_confirm_btn_text_bg"
android:textSize="18sp" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
</layout>
网友评论