android datepicker 自定义,android DatePicker 自定义

本文解决了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 npList = findNumberPicker(tp);

for(NumberPicker np:npList){

resizeNumberPicker(np);

np.performClick();

}

}

/**

* 得到viewGroup里面的numberpicker组件

* @param viewGroup

* @return

*/

private List findNumberPicker(ViewGroup viewGroup){

List npList = new ArrayList<>();

View child = null;

if(null != viewGroup){

for(int i = 0;i

child = viewGroup.getChildAt(i);

if(child instanceof NumberPicker){

npList.add((NumberPicker)child);

}

else if(child instanceof LinearLayout){

List 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阴影区域的灰度百分比

*

* 取值 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);

}

}

这里是布局文件

android:layout_width="wrap_content"

android:layout_height="wrap_content">

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">

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" />

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">

android:layout_width="match_parent"

android:layout_height="28dp"

android:layout_marginLeft="20dp"

android:layout_marginRight="20dp"

android:orientation="horizontal">

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="年"/>

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="月"/>

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="日"/>

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"/>

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}">

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" />

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" />

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在信号处理领域,DOA(Direction of Arrival)估计是一项关键技术,主要用于确定多个信号源到达接收阵列的方向。本文将详细探讨三种ESPRIT(Estimation of Signal Parameters via Rotational Invariance Techniques)算法在DOA估计中的实现,以及它们在MATLAB环境中的具体应用。 ESPRIT算法是由Paul Kailath等人于1986年提出的,其核心思想是利用阵列数据的旋转不变性来估计信号源的角度。这种算法相比传统的 MUSIC(Multiple Signal Classification)算法具有较低的计算复杂度,且无需进行特征值分解,因此在实际应用中颇具优势。 1. 普通ESPRIT算法 普通ESPRIT算法分为两个主要步骤:构造等效旋转不变系统和估计角度。通过空间平移(如延时)构建两个子阵列,使得它们之间的关系具有旋转不变性。然后,通过对子阵列数据进行最小二乘拟合,可以得到信号源的角频率估计,进一步转换为DOA估计。 2. 常规ESPRIT算法实现 在描述中提到的`common_esprit_method1.m`和`common_esprit_method2.m`是两种不同的普通ESPRIT算法实现。它们可能在实现细节上略有差异,比如选择子阵列的方式、参数估计的策略等。MATLAB代码通常会包含预处理步骤(如数据归一化)、子阵列构造、旋转不变性矩阵的建立、最小二乘估计等部分。通过运行这两个文件,可以比较它们在估计精度和计算效率上的异同。 3. TLS_ESPRIT算法 TLS(Total Least Squares)ESPRIT是对普通ESPRIT的优化,它考虑了数据噪声的影响,提高了估计的稳健性。在TLS_ESPRIT算法中,不假设数据噪声是高斯白噪声,而是采用总最小二乘准则来拟合数据。这使得算法在噪声环境下表现更优。`TLS_esprit.m`文件应该包含了TLS_ESPRIT算法的完整实现,包括TLS估计的步骤和旋转不变性矩阵的改进处理。 在实际应用中,选择合适的ESPRIT变体取决于系统条件,例如噪声水平、信号质量以及计算资源。通过MATLAB实现,研究者和工程师可以方便地比较不同算法的效果,并根据需要进行调整和优化。同时,这些代码也为教学和学习DOA估计提供了一个直观的平台,有助于深入理解ESPRIT算法的工作原理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值