欢迎来到入门教程网!

Android

当前位置:主页 > 软件编程 > Android >

Android日历控件的实现方法

来源:本站原创|时间:2020-01-10|栏目:Android|点击:

本文实例为大家分享了Android日历控件的实现代码,供大家参考,具体内容如下

1、效果图:

2、弹窗Dialog:SelectDateDialog:

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自定义View实现炫酷进度条

栏    目:Android

下一篇:Android通过ViewModel保存数据实现多页面的数据共享功能

本文标题:Android日历控件的实现方法

本文地址:https://www.xiuzhanwang.com/a1/Android/9111.html

网页制作CMS教程网络编程软件编程脚本语言数据库服务器

如果侵犯了您的权利,请与我们联系,我们将在24小时内进行处理、任何非本站因素导致的法律后果,本站均不负任何责任。

联系QQ:835971066 | 邮箱:835971066#qq.com(#换成@)

Copyright © 2002-2020 脚本教程网 版权所有