需求:
在一个打卡挑战的软件中
作为一个用户,我可以选择开始时间,结束时间,计算时间间隔,以便我可以知道我需要从什么时间开始,什么时间结束
逻辑:
1. 有两个时间选择对话框,可以选择两个不同的日期
2. 开始时间默认为今天,不能选择之前的时间(不能挑战之前的日期)
3. 结束时间默认和开始时间一致
4. 两者均选择后计算时间间隔,如果开始时间与结束时间相同,则间隔为1(今天也算一天,可以打卡)
5. 开始时间不能大于结束时间,如果出现此情况,例如结束时间选择了2024-9-1,开始时间选择了2024-9-15,则将结束时间同时设置为2024-9-15
页面效果:
页面布局:
代码:
activity_date_picker_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<Button
android:id="@+id/btn_datePickerDialog_start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="请选择开始日期"
android:textSize="30sp"/>
<TextView
android:id="@+id/tv_start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="这里显示选择的开始日期"
android:textSize="30sp"/>
<Button
android:id="@+id/btn_datePickerDialog_stop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="请选择结束日期"
android:textSize="30sp"/>
<TextView
android:id="@+id/tv_stop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="这里显示选择的结束日期"
android:textSize="30sp"/>
<TextView
android:id="@+id/tv_difference"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="这里显示开始到结束的总天数"
android:textSize="30sp"/>
</LinearLayout>
DatePickerDialogActivity.java
package com.example.myapplication;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.TextView;
import androidx.activity.EdgeToEdge;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
public class DatePickerDialogActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "error";
private TextView tv_start;
private TextView tv_stop;
private TextView tv_difference;
private int year;
private int month;
private int day;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_date_picker_dialog);
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
//设置两个按钮的点击事件
findViewById(R.id.btn_datePickerDialog_start).setOnClickListener(this);
findViewById(R.id.btn_datePickerDialog_stop).setOnClickListener(this);
//获取三个textview
tv_start = findViewById(R.id.tv_start);
tv_stop = findViewById(R.id.tv_stop);
tv_difference = findViewById(R.id.tv_difference);
//获取当前时间的年月日
Calendar calendar = Calendar.getInstance();
year = calendar.get(Calendar.YEAR);
month = calendar.get(Calendar.MONTH);
day = calendar.get(Calendar.DAY_OF_MONTH);
//设置格式为yyyy-MM-dd
String startTime = String.format(Locale.getDefault(),"%d-%02d-%02d", year, month+1, day);
//设置开始时间和结束时间为今天
tv_start.setText(startTime);
tv_stop.setText(startTime);
//计算两者的间隔 数字+1 (开始日期为9月1日 结束日期为9月1日也算间隔1天)
tv_difference.setText(daysBetween());
}
@Override
public void onClick(View view) {
if (view.getId() == R.id.btn_datePickerDialog_start){
//创建开始日期的DatePickerDialog对象,默认选择的日期是今天
DatePickerDialog dialog = new DatePickerDialog(this, dateSetListener, year, month,day);
//设置日期选择对话框的最小时间为今天,不能选以前的时间
dialog.getDatePicker().setMinDate(System.currentTimeMillis() - 1000);
dialog.show();
} else if (view.getId() == R.id.btn_datePickerDialog_stop) {
//获取开始日期中选择的日期
String dateString = tv_start.getText().toString();
//以下是为了设置默认选中日期为开始日期选择的日期
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
try {
Date date = formatter.parse(dateString);
Calendar calendar = Calendar.getInstance();
if (date != null) {
calendar.setTime(date);
}
int newYear = calendar.get(Calendar.YEAR);
int newMonth = calendar.get(Calendar.MONTH);
int newDay = calendar.get(Calendar.DAY_OF_MONTH);
//创建结束日期的DatePickerDialog对象,默认选择的日期是开始日期中选择的日期
DatePickerDialog dialog = new DatePickerDialog(this, dateSetListener2, newYear, newMonth, newDay);
dialog.getDatePicker().setMinDate(calendar.getTimeInMillis());
dialog.show();
} catch (ParseException e) {
Log.d(TAG, "error");
}
}
}
// 创建开始日期选择对话框的监听器
DatePickerDialog.OnDateSetListener dateSetListener = new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
//这里是点击日期对话框的确定按钮后做的事情
String dateString = String.format(Locale.getDefault(),"%d-%02d-%02d", year, monthOfYear+1, dayOfMonth);
tv_start.setText(dateString);
// 如果开始日期在结束日期之后,将结束日期设置为同样的日期
if (isDateAfterEndDate(year, monthOfYear, dayOfMonth)){
tv_stop.setText(dateString);
}
tv_difference.setText(daysBetween());
}
};
// 创建结束日期选择对话框的监听器
DatePickerDialog.OnDateSetListener dateSetListener2 = new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
String dateString = String.format(Locale.getDefault(),"%d-%02d-%02d", year, monthOfYear+1, dayOfMonth);
tv_stop.setText(dateString);
tv_difference.setText(daysBetween());
}
};
// 判断选择的日期是否在结束日期之后
private boolean isDateAfterEndDate(int year, int month, int day) {
month++;
String dateString2 = tv_stop.getText().toString();
String[] dateArr2 = dateString2.split("-");
int year2 = Integer.parseInt(dateArr2[0]);
int month2 = Integer.parseInt(dateArr2[1]);
int day2 = Integer.parseInt(dateArr2[2]);
return (year > year2) ||
(year == year2 && month > month2) ||
(year == year2 && month == month2 && day > day2);
}
//计算间隔
private String daysBetween(){
String dateString1 = tv_start.getText().toString();
String dateString2 = tv_stop.getText().toString();
String[] dateArr1 = dateString1.split("-");
int year1 = Integer.parseInt(dateArr1[0]);
int month1 = Integer.parseInt(dateArr1[1]);
int day1 = Integer.parseInt(dateArr1[2]);
String[] dateArr2 = dateString2.split("-");
int year2 = Integer.parseInt(dateArr2[0]);
int month2 = Integer.parseInt(dateArr2[1]);
int day2 = Integer.parseInt(dateArr2[2]);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDateTime date1 = LocalDateTime.of(year1,month1,day1,0,0,0);
LocalDateTime date2 = LocalDateTime.of(year2,month2,day2,0,0,0);
// 计算两个日期之间的天数
String diffString = String.valueOf(ChronoUnit.DAYS.between(date1, date2) + 1);
return "时间间隔为:" + diffString;
}
}
刚开始写,有很多地方写的比较臃肿,欢迎大家指正