温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

怎么在Android中实现一个日历控件

发布时间:2021-04-17 16:54:50 来源:亿速云 阅读:182 作者:Leah 栏目:移动开发

怎么在Android中实现一个日历控件?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

public class SelectDateDialog {  private static final String TAG = "SelectDateDialog";  private Dialog dialog;  private TextView dateText;  private int selectYear, selectMonth;  private AppCompatActivity mContext;  private DateAdapter adapter;  private List<String> selWeekList = new ArrayList<>();  private List<DateBean> list = new ArrayList<>();  public SelectDateDialog builder(AppCompatActivity mContext, int year, int month) {  this.mContext = mContext;  this.selectYear = year;  this.selectMonth = month;  // 获取Dialog布局  View view = LayoutInflater.from(mContext).inflate(R.layout.dialog_date, null);  // 定义Dialog布局和参数  dialog = new Dialog(mContext, R.style.AlertDialogStyle);  dialog.setCanceledOnTouchOutside(false);//点击外部是否取消  dialog.setCancelable(false);  dialog.setContentView(view);  Window window = dialog.getWindow();  WindowManager.LayoutParams params = window.getAttributes();  params.width = (ScreenUtils.getScreenWidth(mContext)); // params.height = (int) (ScreenUtils.getScreenHeight(mContext) * 0.5);  window.setAttributes(params);  window.setGravity(Gravity.BOTTOM);  RecyclerView recycler = view.findViewById(R.id.recycler_select_date);  dateText = view.findViewById(R.id.date_text);  dateText.setText(year + "年" + month + "月");  //下个月  view.findViewById(R.id.next_month).setOnClickListener(view13 -> {  if (selectMonth > 11) {  selectYear = selectYear + 1;  selectMonth = 1;  } else {  selectMonth++;  }  showNewData(selectYear, selectMonth);  });  //上个月  view.findViewById(R.id.last_month).setOnClickListener(view14 -> {  if (selectMonth < 2) {  selectYear = selectYear - 1;  selectMonth = 12;  } else {  selectMonth--;  }  showNewData(selectYear, selectMonth);  });  list = DataUtils.getCalendar(year, month);  adapter = new DateAdapter(mContext, list);  GridLayoutManager manager = new GridLayoutManager(mContext, 7);  recycler.setLayoutManager(manager);  recycler.setAdapter(adapter);  //取消  view.findViewById(R.id.middle_cancel).setOnClickListener(view1 -> {  dialog.dismiss();  });  //确定  view.findViewById(R.id.middle_determine).setOnClickListener(view1 -> {  initSelect();  });  //设置选中当天  adapter.setNowDay(year, month, DataUtils.getLastMonth(year, month));  return this;  }  private void showNewData(int year, int month) {  list = DataUtils.getCalendar(year, month);  //更新月数据  adapter.setList(list);  adapter.setNowDay(year , month, DataUtils.getLastMonth(year, month));  dateText.setText(year + "年" + month + "月");  }  /**  * 获取选中的日期  */  private void initSelect() {  selWeekList.clear();  for (int i = 0; i < list.size(); i++) {  if (list.get(i).isFlag()) {  //记录数量  selWeekList.add(selectYear + "-" + selectMonth + "-" + list.get(i).getWeek());  }  }  Log.e(TAG, "initSelect: "+ list.size());  Log.e(TAG, "initSelect: "+ selWeekList.size());  if (selWeekList.size() == 0) {  Toast.makeText(mContext, "未选则日期", Toast.LENGTH_SHORT).show();  return;  }  dialog.dismiss();  listener.date(DataUtils.returnList(selWeekList));  Log.e(TAG, "initSelect: " + DataUtils.returnList(selWeekList));  }  public void show() {  if (dialog != null && (!dialog.isShowing())) {  dialog.show();  }  }  private OnDateListener listener;  public SelectDateDialog setListener(OnDateListener listener) {  this.listener = listener;  return this;  }  public interface OnDateListener {  void date(String selectDate);  } }

ScreenUtils:

public class ScreenUtils {  public static int getScreenWidth(Context context) {  DisplayMetrics localDisplayMetrics = new DisplayMetrics();  ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(localDisplayMetrics);  return localDisplayMetrics.widthPixels;  } }

DateBean:

public class DateBean {  private int week;  private boolean sign;  //0 上月 1本月 2下月  private int month;  private boolean isFlag;  public boolean isFlag() {  return isFlag;  }  public void setFlag(boolean flag) {  isFlag = flag;  }  public int getWeek() {  return week;  }  public void setWeek(int week) {  this.week = week;  }  public boolean isSign() {  return sign;  }  public void setSign(boolean sign) {  this.sign = sign;  }  public int getMonth() {  return month;  }  public void setMonth(int month) {  this.month = month;  }  public DateBean(int week, boolean sign, int month) {  this.week = week;  this.sign = sign;  this.month = month;  } }

适配器:DateAdapter

public class DateAdapter extends CommonRecyclerAdapter<DateBean> {  private static final String TAG = "DateAdapter";  private Integer nowDay;  private int year;  private int month;  public DateAdapter(Context context, List<DateBean> list) {  super(context, R.layout.item_date, list);  }  public void setNowDay(int year, int month, int nowDay) {  this.nowDay = nowDay;  this.year = year;  this.month = month;  notifyDataSetChanged();  }  @Override  public void convert(RecyclerHolder holder, DateBean item, int position) {  TextView number = holder.getView(R.id.item_number);  number.setText(item.getWeek() + "");  //当前年月等于切换年月时才选中当天  if (position == nowDay) {  String date = year + "-" + month;  if (date.equals(DataUtils.timeInMillsTrasToDate(1))) {  number.setBackgroundResource(R.drawable.date_unsel_shape);  number.setTextColor(Color.WHITE);  }else {  number.setTextColor(Color.parseColor("#333333"));  }  } else {  number.setBackgroundResource(0);  number.setTextColor(Color.parseColor("#333333"));  if (item.getMonth() == 0 || item.getMonth() == 2) {  number.setTextColor(Color.parseColor("#CDCDCD"));  } else {  number.setTextColor(Color.parseColor("#333333"));  }  }  //点击事件  number.setOnClickListener(view -> {  //本月可以点击  int nowYear = Integer.parseInt(DataUtils.timeInMillsTrasToDate(2));  int nowMonth = Integer.parseInt(DataUtils.timeInMillsTrasToDate(3));  //只有在今天之后的日期才可以选中  if (year == nowYear) {  if (item.getMonth() == 1 && month == nowMonth && position > nowDay) {  onClick(item, number);  } else if (month > nowMonth) {  onClick(item, number);  }  } else if (year > nowYear) {  onClick(item, number);  }  });  }  private void onClick(DateBean item, TextView number) {  if (item.isFlag()) {  item.setFlag(false);  number.setBackgroundResource(0);  number.setTextColor(Color.parseColor("#333333"));  } else {  item.setFlag(true);  number.setBackgroundResource(R.drawable.date_sel_shape);  number.setTextColor(Color.WHITE);  }  } }

注意:CommonRecyclerAdapter之前写过,这里不再重复

数据源:DataUtils

public class DataUtils {  private static final String TAG = "DataUtils";  /**  * 日历  */  public static List<DateBean> getCalendar(int currentYear, int currentMonth) {  //实例化集合  List<DateBean> list = new ArrayList<>();  Calendar c = Calendar.getInstance();  c.clear();  /**  * 处理上个月月末  */  if (currentMonth - 1 == 0) {  c.set(Calendar.YEAR, currentYear - 1);  c.set(Calendar.MONTH, 11);  } else {  c.set(Calendar.YEAR, currentYear);  c.set(Calendar.MONTH, (currentMonth - 2));  }  int last_sumDays = c.getActualMaximum(Calendar.DAY_OF_MONTH);  c.set(Calendar.DATE, last_sumDays);  //得到一号星期几  int weekDay = c.get(Calendar.DAY_OF_WEEK);  if (weekDay < 7) {  for (int i = weekDay - 1; i >= 0; i--) {  Integer date = new Integer(last_sumDays - i);  list.add(new DateBean(date, true, 0));  }  }  /**  * 处理当前月  */  c.clear();  c.set(Calendar.YEAR, currentYear);  c.set(Calendar.MONTH, currentMonth - 1);  int currentsumDays = c.getActualMaximum(Calendar.DAY_OF_MONTH);  for (int i = 1; i <= currentsumDays; i++) {  Integer date = new Integer(i);  list.add(new DateBean(date, true, 1));  }  /**  * 处理下个月月初  */  c.clear();  if (currentMonth == 12) {  c.set(Calendar.YEAR, currentYear + 1);  c.set(Calendar.MONTH, 0);  } else {  c.set(Calendar.YEAR, currentYear);  c.set(Calendar.MONTH, currentMonth);  }  c.set(Calendar.DATE, 1);  int currentWeekDay = c.get(Calendar.DAY_OF_WEEK);  if (currentWeekDay > 2 && currentWeekDay < 8) {  for (int i = 1; i <= 8 - currentWeekDay; i++) {  list.add(new DateBean(i, true, 2));  }  }  return list;  }  /**  * 获取上个月大小  */  public static Integer getLastMonth(int currentYear, int currentMonth) {  //实例化集合  List<Integer> list = new ArrayList<>();  Calendar c = Calendar.getInstance();  c.clear();  /**  * 处理上个月月末  */  if (currentMonth - 1 == 0) {  c.set(Calendar.YEAR, currentYear - 1);  c.set(Calendar.MONTH, 11);  } else {  c.set(Calendar.YEAR, currentYear);  c.set(Calendar.MONTH, (currentMonth - 2));  }  int last_sumDays = c.getActualMaximum(Calendar.DAY_OF_MONTH);  c.set(Calendar.DATE, last_sumDays);  //得到一号星期几  int weekDay = c.get(Calendar.DAY_OF_WEEK);  if (weekDay < 7) {  for (int i = weekDay - 1; i >= 0; i--) {  list.add(i);  }  }  Log.e(TAG, "getLastMonth: " + Integer.parseInt(timeInMillsTrasToDate(0)));  return list.size() + Integer.parseInt(timeInMillsTrasToDate(0)) - 1;  }  /**  * list转string字符串  */  public static String returnList(List<String> list) {  if (null == list && list.size() == 0) {  return "";  } else {  //去除空格  String str = String.valueOf(list).replaceAll(" ", "");  return str.substring(1, str.length() - 1);  }  }  /**  * 时间转换  */  @TargetApi(Build.VERSION_CODES.N)  public static String timeInMillsTrasToDate(int formatType) {  DateFormat formatter = null;  switch (formatType) {  case 0:  formatter = new SimpleDateFormat("dd");  break;  case 1:  formatter = new SimpleDateFormat("yyyy-MM");  break;  case 2:  formatter = new SimpleDateFormat("yyyy");  break;  case 3:  formatter = new SimpleDateFormat("MM");  break;  }  Calendar calendar = Calendar.getInstance();  return formatter.format(calendar.getTime());  } }

使用:DateActivity

public class DateActivity extends AppCompatActivity {  private Button openDate;  @Override  protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_date);  openDate = this.findViewById(R.id.open_date);  openDate.setOnClickListener(view -> {  showDateDialog();  });  }  private void showDateDialog() {  int year = Integer.parseInt(DataUtils.timeInMillsTrasToDate(2));  int month = Integer.parseInt(DataUtils.timeInMillsTrasToDate(3));  new SelectDateDialog().builder(this, year, month)  .setListener(selectDate -> openDate.setText(selectDate)).show();  } }

对应布局:activity_date

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="match_parent"  android:layout_height="match_parent"  android:orientation="vertical">  <Button  android:id="@+id/open_date"  android:layout_width="match_parent"  android:layout_height="wrap_content"  android:text="打开日历" /> </LinearLayout>

2、资源文件:

date_sel_shape.xml

<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"  android:shape="oval"  android:useLevel="false">  <solid android:color="@color/colorAccent" />  <!--<stroke android:width="1dp" android:color="@color/white"/>-->  <size  android:width="30dp"  android:height="30dp" /> </shape>

date_unsel_shape.xml

<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"  android:shape="oval"  android:useLevel="false">  <solid android:color="@color/colorPrimary" />  <!--<stroke android:width="1dp" android:color="@color/white"/>-->  <size  android:width="30dp"  android:height="30dp" /> </shape>

dialog_shape.xml

<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android">  <corners android:radius="5dp" />  <solid android:color="#ffffff" /> </shape>

item_date.xml:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="match_parent"  android:layout_height="wrap_content"  android:gravity="center"  android:padding="5dp">  <TextView  android:id="@+id/item_number"  android:layout_width="35dp"  android:layout_height="35dp"  android:gravity="center"  android:text="10"  android:textSize="15sp" /> </LinearLayout>

颜色:

<color name="colorPrimary">#008577</color> <color name="colorPrimaryDark">#00574B</color> <color name="colorAccent">#D81B60</color>

样式:

<style name="AlertDialogStyle" parent="@android:style/Theme.Dialog">  <item name="android:windowBackground">@android:color/transparent</item>  <item name="android:windowContentOverlay">@null</item>  <item name="android:windowIsFloating">true</item>  <item name="android:windowFrame">@null</item>  <item name="android:backgroundDimEnabled">true</item>  <item name="android:windowNoTitle">true</item>  <item name="android:windowIsTranslucent">true</item> </style>

看完上述内容,你们掌握怎么在Android中实现一个日历控件的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注亿速云行业资讯频道,感谢各位的阅读!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI