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>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android实现可滑动的自定义日历控件

    最近用到的一个日历控件,记录下,效果如图 代码下载地址:点击打开链接 布局文件 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical&q

  • Android学习教程之日历控件使用(7)

    本文实例为大家分享了Android日历控件的使用方法,供大家参考,具体内容如下 MainActivity.java代码: package siso.timessquare; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; p

  • Android 一个日历控件的实现代码

    先看几张动态的效果图吧! 项目地址:https://github.com/Othershe/CalendarView 这里主要记录一下在编写日历控件过程中一些主要的点: 一.主要功能 1.支持农历.节气.常用节假日 2.日期范围设置,默认支持的最大日期范围[1900.1~2049.12] 3.默认选中日期设置 4.单选.多选 5.跳转到指定日期 6.通过自定义属性定制日期外观,以及简单的日期item布局配置 二.基本结构 我们要实现的日历控件采用ViewPager作为主框架,CalendarVi

  • Android使用GridLayout绘制自定义日历控件

    效果图 思路:就是先设置Gridlayout的行列数,然后往里面放置一定数目的自定义日历按钮控件,最后实现日历逻辑就可以了. 步骤: 第一步:自定义日历控件(初步) 第二步:实现自定义单个日期按钮控件 第三步:将第二步得到的控件动态添加到第一步的布局中,并实现日期逻辑 第四步:编写单个日期点击监听器接口 第一步:自定义日历控件(初步) <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmln

  • Android实现日历控件示例代码

    做的是一个酒店的项目,可以选择入住和离开的日期.声明为了省事在网上找的资料,自己修改的逻辑,希望对需要的朋友有帮助.喜欢的给个好评.谢谢啦!祝生活愉快! 先上图 第一步,搭建布局xml <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_w

  • Android自定义日历控件实例详解

    为什么要自定义控件 有时,原生控件不能满足我们对于外观和功能的需求,这时候可以自定义控件来定制外观或功能:有时,原生控件可以通过复杂的编码实现想要的功能,这时候可以自定义控件来提高代码的可复用性. 如何自定义控件 下面我通过我在github上开源的Android-CalendarView项目为例,来介绍一下自定义控件的方法.该项目中自定义的控件类名是CalendarView.这个自定义控件覆盖了一些自定义控件时常需要重写的一些方法. 构造函数 为了支持本控件既能使用xml布局文件声明,也可在ja

  • Android可签到日历控件的实现方法

    最近在公司的功能需求中,需要实现可以签到的日历,签到后在签到过的日期做标志.本功能参考了网上一些大神的日历控件,在此基础上进行修改,已满足本公司的需求,现已完成,记录一下. 布局文件: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_wi

  • Android日历控件的实现方法

    本文实例为大家分享了Android日历控件的实现代码,供大家参考,具体内容如下 1.效果图: 2.弹窗Dialog:SelectDateDialog: public class SelectDateDialog { private static final String TAG = "SelectDateDialog"; private Dialog dialog; private TextView dateText; private int selectYear, selectMon

  • ASP.NET中日历控件和JS版日历控件的使用方法(第5节)

    今天小编带大家以做任务的形式了解ASP.NET中日历控件的使用方法,主要任务内容: 1.添加一个日历,设置日期以蓝色的完整名称显示,周末以黄色背景红色文字显示,而当前日期使用绿色背景显示,用户可以选择一天.一周或整个月,被选的天/周/月使用灰色背景色来显示.当选中一个日期后,把时间显示在下面的一个文本框中,效果如图所示: 2.设计一个注册页面,使用js日历控件帮助用户输入出生日期.效果如图所示: 学习项目一  Calendar日历控件 1.在站点下创建一个Calendar页面,并在页面上拖放一个

  • Android基础控件RadioGroup使用方法详解

    本文为大家分享了Android基础控件RadioGroup的使用,供大家参考,具体内容如下 1.简单介绍 RadioGroup可以提供几个选项供用户选择,但只能选择其中的一个.其下面可以横着或者竖着挂几个RadioButton,也可以挂载其他控件(如TextView).RadioGroup的相应事件一般不由下面的RadioButton响应,而是直接由RadioGroup响应.实现RadioGroup.OnCheckedChangeListener接口即可监听RadioGroup.RadioBut

  • Android日历控件PickTime代码实例

    最近做项目,需要设置用户的生日,所以做这样一个功能. 开始发觉自带的DatePicker 很是不好用. 上代码: <DatePicker android:id="@+id/dpPicker" android:datePickerMode="spinner" android:calendarViewShown="false" android:layout_marginTop="150dp" android:spinners

  • Android树形控件的实现方法

    在PC上我们已经习惯了树形控件,因为其可以清晰的展现各个节点之间的层次结果,但是在Android平台上,系统并没有提供这样一个控件,而是只有ListView.不过通过改写与ListView绑定的Adapter可以实现这样一个效果. 一个ListView需要和一个Adapter绑定,用于管理数据.在这里以BaseAdapter为例,继承Adapter需要重写四个函数,其中较为重要的是两个:    1 public int getCount()://该函数返回ListView 的ListItem的条

  • Android重要控件SnackBar使用方法详解

    SnackBar是DesignSupportLibrary中的一个重要的控件,用于在界面下面提示一些关键信息,跟Toast不同的地方是SnackBar允许用户向右滑动消除它,同时,也允许在SnackBar中设定一个Action,当用户点击了SnackBar里面的按钮的时候,可以进行一些操作,所以,功能绝对是很强大的. SnackBar的构造: // 参数分别是父容器,提示信息,持续时间public static Snackbar make(@NonNull View view, @NonNull

  • Android第三方控件PhotoView使用方法详解

    PhotoView的简介: 这是一个图片查看库,实现图片浏览功能,支持pinch(捏合)手势或者点击放大缩小.支持在ViewPager中翻页浏览图片. PhotoView 是一款扩展自Android ImageView ,支持通过单点/多点触摸来进行图片缩放的智能控件.功能实用和强大. PhotoView的功能: 图片浏览查看 双指缩放 单点触摸缩放 图片缩放模式设置 基本用法: 导入jar包,布局XML里设置PhotoView 将ImageView传入PhotoViewAttacher 代码演

  • Android常用控件ImageSwitcher使用方法详解

    图像切换器使用ImageSwitcher表示,用于实现类似于Windows操作系统下的"Windows照片查看器"中的上一张.下一张切换图片的功能.在使用ImageSwitcher时,必须实现ViewSwitcher.ViewFactory接口,并通过makeView()方法创建用于显示图片的ImageView对象.makeView()方法将返回一个显示图片的ImageView.在使用ImageSwitcher组件时,还有一个非常重要的方法,那就是setImageResource()方

随机推荐