在项目中需做一个自定义时间选择器,仅显示选择年月,其中设置分割线颜色和宽度,设置仅能选择已知时间,不能设置未来时间.话不多说,直接上代码.
Fragment代码片段
//...
import com.xxx.dialog.CustomDateDialog;
//...
private CustomDateDialog timeDialog;
private View mainView;
//...
private ConstraintLayout timeBtn;//时间盒子
private AppCompatTextView timeText; //时间文字
private String selectTime = ""; //所选择时间值
//...
timeBtn = mainView.findViewById(R.id.time_btn);//时间盒子
timeText = mainView.findViewById(R.id.time_text); //时间文字
//...
//时间筛选
timeBtn.setOnClickListener(v -> {
//ButtonUtils 多次点击仅一次有效
if (!ButtonUtils.isFastDoubleClick()) {
timeDialog = new CustomDateDialog(getContext());
Calendar calendar = Calendar.getInstance();
timeDialog.setDate(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH),(year, month, day) -> {
//Log.i(TAG, "日期:" + year + month + day);
String monthNum = month + "";
String dayNum = day + "";
if (monthNum.length() == 1) {
monthNum = "0" + monthNum;
}
//if (dayNum.length() == 1) {
// dayNum = "0" + dayNum;
// }
// timeText .setText(year + "年" + monthNum + "月" + dayNum);
timeText .setText(year + "年" + monthNum + "月");
selectTime = year + "-" + monthNum;
//请求数据
getList(true, true);
});
timeDialog.show();
}
});
//获取数据
private void getList(boolean clearData, boolean showDialog) {
//TODO
}
//CustomDateDialog片段
//...
package com.xxx.dialog;
import com.xxx.R;
//...
import android.app.Dialog;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
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 java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import androidx.appcompat.widget.AppCompatButton;
import androidx.appcompat.widget.AppCompatTextView;
public class CustomDateDialog implements View.OnClickListener, DatePicker.OnDateChangedListener {
private Dialog dialog;
private AppCompatTextView titleTv;//标题
private DatePicker datePicker;//日期选择控件
private AppCompatButton confirmTv;//确认按钮
private AppCompatButton cancelTv;//取消按钮
private View dialogView;
private OnDateSetListener onDateSetListener;
/**
* 构造器
*
* @param context 上下文
*/
public CustomDateDialog(Context context) {
dialogView = LayoutInflater.from(context).inflate(R.layout.dialog_time_warp, null);
dialog = new Dialog(context, R.style.CustomDateDialog);
titleTv = dialogView.findViewById(R.id.type_title);
datePicker = dialogView.findViewById(R.id.datePicker);
resizePicker(datePicker);
ViewGroup viewGroup1 = (ViewGroup) datePicker.getChildAt(0);
ViewGroup viewGroup2 = (ViewGroup) viewGroup1.getChildAt(0);//获取年月日的下拉列表项
//隐藏 --日--
if (viewGroup2.getChildCount() == 3) {//有的机型没有竖线,只有年、月、日
viewGroup2.getChildAt(2).setVisibility(View.GONE);
} else if (viewGroup2.getChildCount() == 5) {//有的机型有有竖线
viewGroup2.getChildAt(3).setVisibility(View.GONE);
viewGroup2.getChildAt(4).setVisibility(View.GONE);
}
confirmTv = dialogView.findViewById(R.id.ok_btn);
cancelTv = dialogView.findViewById(R.id.cancel_btn);
confirmTv.setOnClickListener(this);
cancelTv.setOnClickListener(this);
setDatePickerDividerColor(datePicker);
//设置最大日期
setMaxSelectableDate(datePicker);
datePicker.setOnDateChangedListener(this);
}
/**
* 显示对话框
*/
public void show() {
Window window = dialog.getWindow();
window.setContentView(dialogView);//设置对话框窗口的内容视图(这里有个坑,参数不要传R.layout.date_dialog,否则会出现各种问题,比如按钮响应不了点击事件)
window.setLayout(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);//设置对话框窗口的布局参数
dialog.show();
dialog.setCancelable(false);
}
/**
* 关闭对话框
*/
public void dismiss() {
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
}
}
/**
* 设置标题
*
* @param title 标题
*/
public void setTitle(String title) {
titleTv.setText(title);
}
public void setDate(int year, int month, OnDateSetListener onDateSetListener) {
Calendar calendar = Calendar.getInstance();
datePicker.init(year, month, calendar.get(Calendar.DAY_OF_MONTH), this);
this.onDateSetListener = onDateSetListener;
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.ok_btn) {
dialog.dismiss();
if (onDateSetListener != null) {
datePicker.clearFocus();
int year = datePicker.getYear();
int month = datePicker.getMonth();
int day = datePicker.getDayOfMonth();
onDateSetListener.onDateSet(year, month + 1, day);
}
}
if (v.getId() == R.id.cancel_btn) {
dialog.dismiss();
}
}
@Override
public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
Calendar now = Calendar.getInstance();
if (year > now.get(Calendar.YEAR) ||
(year == now.get(Calendar.YEAR) && monthOfYear > now.get(Calendar.MONTH)) ||
(year == now.get(Calendar.YEAR) && monthOfYear == now.get(Calendar.MONTH) && dayOfMonth > now.get(Calendar.DAY_OF_MONTH))) {
// 如果选择了未来日期,则重置为当前日期
datePicker.updateDate(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DAY_OF_MONTH));
}
// datePicker.init(year, monthOfYear, dayOfMonth, this);
}
public interface OnDateSetListener {
void onDateSet(int year, int month, int day);
}
/**
* 调整FrameLayout的大小
*/
private void resizePicker(FrameLayout tp) { //DatePicker和TimePicker继承自FrameLayout
List<NumberPicker> npList = findNumberPicker(tp); //找到组成的NumberPicker
for (NumberPicker np : npList) {
resizeNumberPicker(np); //调整每个NumberPicker的宽度
}
}
/**
* 得到viewGroup 里面的numberpicker组件
*/
private List<NumberPicker> findNumberPicker(ViewGroup viewGroup) {
List<NumberPicker> npList = new ArrayList<NumberPicker>();
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.isEmpty()) {
return result;
}
}
}
}
return npList;
}
/**
* 调整numberpicker大小
*/
private void resizeNumberPicker(NumberPicker np) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(200, 220);
// LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(200, ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(20, 14, 20, 14);
np.setLayoutParams(params);
}
/**
* 设置时间选择器的分割线颜色
*
* @param datePicker
*/
private void setDatePickerDividerColor(DatePicker datePicker) {
// Divider changing:
// 获取 mSpinners
LinearLayout llFirst = (LinearLayout) datePicker.getChildAt(0);
// 获取 CustomNumberPicker
LinearLayout mSpinners = (LinearLayout) llFirst.getChildAt(0);
for (int i = 0; i < mSpinners.getChildCount(); i++) {
NumberPicker picker = (NumberPicker) mSpinners.getChildAt(i);
picker.setSelectionDividerHeight(0);//设置分割线高度为0
for (EditText editText : findEditText(picker)) {
editText.setTextSize(32);
resizeNumberPicker(picker);
picker.setWrapSelectorWheel(true);
picker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
picker.setOnScrollListener((view, scrollState) -> {
view.performClick();//刷新选中状态
});
}
//设置分割线颜色
Field[] pickerFields = NumberPicker.class.getDeclaredFields();
for (Field pf : pickerFields) {
pf.setAccessible(true);
if (pf.getName().equals("mSelectionDivider")) {
try {
pf.set(picker, new ColorDrawable(Color.alpha(0)));设置分割线颜色
} catch (IllegalAccessException e) {
e.printStackTrace();
}
break;
}
}
}
}
private List<EditText> findEditText(ViewGroup viewGroup) {
List<EditText> npList = new ArrayList<>();
View child = null;
if (null != viewGroup) {
for (int i = 0; i < viewGroup.getChildCount(); i++) {
child = viewGroup.getChildAt(i);
if (child instanceof EditText) {
npList.add((EditText) child);
} else if (child instanceof LinearLayout) {
List<EditText> result = findEditText((ViewGroup) child);
if (!result.isEmpty()) {
return result;
}
}
}
}
return npList;
}
/**
* 设置最大可选日期为当前日期
*
* @param datePicker
*/
private void setMaxSelectableDate(DatePicker datePicker) {
Calendar calendar = Calendar.getInstance();
int currentYear = calendar.get(Calendar.YEAR);
int currentMonth = calendar.get(Calendar.MONTH);
int currentDay = calendar.get(Calendar.DAY_OF_MONTH);
calendar.set(currentYear,currentMonth,currentDay);
long maxDate = calendar.getTimeInMillis();
datePicker.setMaxDate(maxDate);
datePicker.init(currentYear, currentMonth, currentDay, this);
//设置最大时间为当前月
datePicker.updateDate(currentYear,currentYear, currentYear);
}
}
// dialog_time_warp片段
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="760dp"
android:layout_height="wrap_content"
android:background="@drawable/dialog_box"
android:paddingBottom="48dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/type_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:gravity="center"
android:text="请选择年月"
android:textColor="@color/colorFFF"
android:textSize="32sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!--年月-->
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_marginStart="50dp"
android:layout_marginTop="182dp"
android:layout_marginEnd="50dp"
android:background="@drawable/service_item"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/year_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="286dp"
android:gravity="center"
android:text="年"
android:textColor="@color/colorFFF"
android:textSize="32sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/month_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="184dp"
android:gravity="center"
android:text="月"
android:textColor="@color/colorFFF"
android:textSize="32sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/year_text"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<DatePicker
android:id="@+id/datePicker"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:calendarViewShown="false"
android:datePickerMode="spinner"
android:spinnersShown="true"
android:theme="@style/my_time_picker_style"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/cancel_btn"
android:layout_width="312dp"
android:layout_height="80dp"
android:background="@drawable/cancel_btn"
android:gravity="center"
android:text="取消"
android:textColor="@color/color_cancel_txt"
android:textSize="28sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/ok_btn"
android:layout_width="312dp"
android:layout_height="80dp"
android:background="@drawable/ok_btn"
android:gravity="center"
android:text="确认"
android:textColor="@color/color_ok_txt"
android:textSize="28sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
效果图如下所示:
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- ovod.cn 版权所有 湘ICP备2023023988号-4
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务