经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » Android » 查看文章
Android自定义实现日历控件
来源:jb51  时间:2021/11/15 17:22:07  对本文有异议

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

1. Calendar类

2. 布局

创建calendar_layout.xml

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:padding="20sp"
  3. android:orientation="vertical"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent">
  6. <RelativeLayout
  7. android:id="@+id/titleRl"
  8. android:layout_width="match_parent"
  9. android:layout_height="30dp">
  10. <TextView
  11. android:id="@+id/lastTv"
  12. android:text="上一月"
  13. android:layout_alignParentLeft="true"
  14. android:gravity="center"
  15. android:layout_width="wrap_content"
  16. android:layout_height="30dp"></TextView>
  17. <TextView
  18. android:id="@+id/monthTv"
  19. android:text="十一月"
  20. android:gravity="center"
  21. android:layout_centerHorizontal="true"
  22. android:layout_width="wrap_content"
  23. android:layout_height="30dp"></TextView>
  24. <TextView
  25. android:id="@+id/nextTv"
  26. android:text="下一月"
  27. android:gravity="center"
  28. android:layout_alignParentRight="true"
  29. android:layout_width="wrap_content"
  30. android:layout_height="30dp"></TextView>
  31. </RelativeLayout>
  32. <LinearLayout
  33. android:id="@+id/weekLl"
  34. android:orientation="horizontal"
  35. android:layout_width="match_parent"
  36. android:layout_height="wrap_content">
  37. <TextView
  38. android:id="@+id/Tv7"
  39. android:text="日"
  40. android:gravity="center"
  41. android:layout_weight="1"
  42. android:layout_width="0dp"
  43. android:layout_height="30dp"></TextView>
  44. <TextView
  45. android:id="@+id/Tv1"
  46. android:text="一"
  47. android:gravity="center"
  48. android:layout_weight="1"
  49. android:layout_width="0dp"
  50. android:layout_height="30dp"></TextView>
  51. <TextView
  52. android:id="@+id/Tv2"
  53. android:text="二"
  54. android:gravity="center"
  55. android:layout_weight="1"
  56. android:layout_width="0dp"
  57. android:layout_height="30dp"></TextView>
  58. <TextView
  59. android:id="@+id/Tv3"
  60. android:text="三"
  61. android:gravity="center"
  62. android:layout_weight="1"
  63. android:layout_width="0dp"
  64. android:layout_height="30dp"></TextView>
  65. <TextView
  66. android:id="@+id/Tv4"
  67. android:text="四"
  68. android:gravity="center"
  69. android:layout_weight="1"
  70. android:layout_width="0dp"
  71. android:layout_height="30dp"></TextView>
  72. <TextView
  73. android:id="@+id/Tv5"
  74. android:text="五"
  75. android:gravity="center"
  76. android:layout_weight="1"
  77. android:layout_width="0dp"
  78. android:layout_height="30dp"></TextView>
  79. <TextView
  80. android:id="@+id/Tv6"
  81. android:text="六"
  82. android:gravity="center"
  83. android:layout_weight="1"
  84. android:layout_width="0dp"
  85. android:layout_height="30dp"></TextView>
  86. </LinearLayout>
  87. <GridView
  88. android:id="@+id/calendarCv"
  89. android:numColumns="7"
  90. android:layout_width="match_parent"
  91. android:layout_height="match_parent"></GridView>
  92. </LinearLayout>

创建item_layout.xml

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:layout_width="match_parent"
  3. android:layout_height="match_parent">
  4. <TextView
  5. android:id="@+id/itemTv"
  6. android:gravity="center"
  7. android:layout_width="match_parent"
  8. android:layout_height="match_parent"></TextView>
  9. </LinearLayout>

在activity_main.xml中

  1. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:app="http://schemas.android.com/apk/res-auto"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. tools:context=".MainActivity">
  7. <com.aye.newcalendar.NewCalendar
  8. android:id="@+id/calendarNc"
  9. android:gravity="center"
  10. android:layout_width="match_parent"
  11. android:layout_height="match_parent"></com.aye.newcalendar.NewCalendar>
  12. </androidx.constraintlayout.widget.ConstraintLayout>

3. 业务处理

创建NewCalendar类,继承LinearLayout

  1. public class NewCalendar extends LinearLayout {
  2. private TextView lastTv,nextTv,dateTv;
  3. private GridView calendarGv;
  4.  
  5. private Calendar calendar=Calendar.getInstance(); //日历控件初始化
  6. //重写三个构造方法
  7. public NewCalendar(Context context) {
  8. super(context);
  9. }
  10. public NewCalendar(Context context, @Nullable AttributeSet attrs) {
  11. super(context, attrs);
  12. initControl(context); //绑定控件
  13. }
  14. public NewCalendar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
  15. super(context, attrs, defStyleAttr);
  16. initControl(context); //绑定控件
  17. }
  18. private void initControl(Context context){
  19. bindControl(context); //绑定控件
  20. bindControlEvent(); //绑定控件事件
  21. }
  22.  
  23. //绑定控件事件方法
  24. private void bindControlEvent() {
  25. renderCalendar();
  26. //“下一月”点击事件
  27. nextTv.setOnClickListener(new OnClickListener() {
  28. @Override
  29. public void onClick(View v) {
  30. calendar.add(Calendar.MONTH,+1); //月份+1
  31. renderCalendar();
  32. }
  33. });
  34. //“上一个”点击事件
  35. lastTv.setOnClickListener(new OnClickListener() {
  36. @Override
  37. public void onClick(View v) {
  38. calendar.add(Calendar.MONTH,-1); //月份-1
  39. renderCalendar();
  40. }
  41. });
  42. }
  43.  
  44. private void renderCalendar() {
  45. SimpleDateFormat sdf = new SimpleDateFormat("MMM yyy"); //日期格式化
  46. dateTv.setText(sdf.format(calendar.getTime())); //设置月份
  47. ArrayList<Date> cells = new ArrayList<>();
  48. Calendar calendar1 = (Calendar) calendar.clone(); //克隆日历对象
  49. calendar1.set(Calendar.DAY_OF_MONTH, 1); //置于当月第一天;
  50. int prevDays = calendar1.get(Calendar.DAY_OF_WEEK) - 1; //获取上个月最后一天是星期几
  51. calendar1.add(Calendar.DAY_OF_MONTH, -prevDays); //第一天
  52.  
  53. int maxCount = 6 * 7; //设置每个月最大天数
  54. //循环存入集合中
  55. while (cells.size() < maxCount) {
  56. cells.add(calendar1.getTime());
  57. calendar1.add(Calendar.DAY_OF_MONTH, 1); //日期+1
  58. }
  59. //设置适配器
  60. calendarGv.setAdapter(new CalendarAdapter(getContext(),cells));
  61. }
  62. //适配器
  63. private class CalendarAdapter extends ArrayAdapter<Date>{
  64. LayoutInflater layoutInflater;
  65. public CalendarAdapter(@NonNull Context context,ArrayList<Date> days) {
  66. super(context, R.layout.item_layout,days);
  67. layoutInflater=LayoutInflater.from(context);
  68. }
  69. @NonNull
  70. @Override
  71. public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
  72. Date date=getItem(position);
  73. ViewHolder viewHolder;
  74. if (convertView==null){ //初始化绑定
  75. convertView=layoutInflater.inflate(R.layout.item_layout,parent,false);
  76. viewHolder=new ViewHolder();
  77. viewHolder.itemTv=convertView.findViewById(R.id.itemTv);
  78. convertView.setTag(viewHolder);
  79. }
  80. viewHolder= (ViewHolder) convertView.getTag();
  81. int day=date.getDate();
  82. viewHolder.itemTv.setText(String.valueOf(day)); //赋值
  83.  
  84. return convertView;
  85. }
  86. class ViewHolder{
  87. TextView itemTv;
  88. }
  89. }
  90. private void bindControl(Context context) {
  91. LayoutInflater inflater=LayoutInflater.from(context);
  92. inflater.inflate(R.layout.calendar_layout,this);
  93.  
  94. lastTv=findViewById(R.id.lastTv);
  95. nextTv=findViewById(R.id.nextTv);
  96. dateTv=findViewById(R.id.dateTv);
  97. calendarGv=findViewById(R.id.calendarGv);
  98. }
  99. }

3. 定制UI

在适配器getView()方法中,个性化日历界面

  1. Date now=new Date();
  2. Boolean isTheSameMonth=false; //是否与当前月份相同
  3. //判断显示的日期月份与当前月份相同
  4. if (date.getMonth()==now.getMonth()) { //月份相同
  5. isTheSameMonth = true;
  6. }
  7. //若显示的日期月份与当前月份相同,则设置字体颜色是黑色
  8. if (isTheSameMonth) {
  9. viewHolder.itemTv.setTextColor(Color.parseColor("#000000"));
  10. }
  11. //设置当前日期字体为红色
  12. if (now.getDate()==date.getDate()&&now.getMonth()==date.getMonth()&&now.getYear()==date.getYear()){
  13. viewHolder.itemTv.setTextColor(Color.parseColor("#ff0000"));
  14. }

4. 事件监听

在NewCalendar中,首先编写长按事件的接口,然后设置适配器点击事件

  1. //长按事件接口
  2. public interface NewCalendarListener{
  3. void onItemClick(Date date);
  4. }
  5.  
  6. //适配器长按事件
  7. calendarGv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
  8. @Override
  9. public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
  10. if (listener==null){
  11. return false;
  12. }else {
  13. //获取长按的位置,传入onItemClick方法中
  14. listener.onItemClick((Date) parent.getItemAtPosition(position));
  15. return true;
  16. }
  17. }
  18. });

在MainActivity中,实现长按事件接口并重写方法,实现长按某个日期弹出Toast显示当前长按日期。

  1. @Override
  2. protected void onCreate(Bundle savedInstanceState) {
  3. super.onCreate(savedInstanceState);
  4. setContentView(R.layout.activity_main);
  5. NewCalendar calendar=findViewById(R.id.calendarNc);
  6. calendar.listener=this;
  7. }
  8. //MainActivity实现长按事件接口
  9. @Override
  10. public void onItemClick(Date date) {
  11. DateFormat df= SimpleDateFormat.getDateInstance();
  12. Toast.makeText(this,df.format(date),Toast.LENGTH_SHORT).show();
  13. }

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

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号