实验目的

1、熟悉App开发常用的一些高级控件及相关工具,主要包括日期时间控件的用法、列表类视图及其适配器的用法、翻页类视图及其适配器的用法、碎片及其适配器的用法等;
2、熟悉四大组件之一广播Broadcast的基本概念与常见用法;

实验内容

1、万年历:最简单的时间功能仅能查看当前的年月日、时分秒,若要拓展它的功能,则可由日历变月历,在年月日之外补充星期几,再添加节假日描述。进一步升级扩展,由月历变年历,分别按公历与农历纪年,便成了万年历;
万年历的界面效果

2、日程表(日程提醒采用手机震动的方式):日程表不但支持基本的日历信息展示,而且支持用户设定每天的日程安排,还支持日程提醒时间。

日程表的主页面

日程安排/详情页面

实验过程(实验的设计思路、关键源代码等)

源代码:https://gitee.com/shentuzhigang/mini-project/tree/master/android-calendar

package io.shentuzhigang.demo.calendarimport android.annotation.SuppressLint
import android.graphics.Color
import android.os.Bundle
import android.util.TypedValue
import android.view.View
import android.widget.LinearLayout
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.viewpager.widget.PagerTabStrip
import androidx.viewpager.widget.ViewPager
import io.shentuzhigang.demo.calendar.util.DateUtil
import io.shentuzhigang.demo.calendar.widget.MonthPicker
import io.shentuzhigang.demo.calendar.adapter.CalendarPagerAdapter
@SuppressLint("SetTextI18n")
class CalendarActivity : AppCompatActivity(), View.OnClickListener {private var ll_calendar_main // 声明一个万年历区域的线性布局对象: LinearLayout? = nullprivate var ll_month_select // 声明一个月份选择区域的线性布局对象: LinearLayout? = nullprivate var mp_month // 声明一个月份选择器对象: MonthPicker? = nullprivate var vp_calendar // 声明一个翻页视图对象: ViewPager? = nullprivate var tv_calendar // 声明一个选中年份的文本视图对象: TextView? = nullprivate var isShowSelect = false // 是否显示月份选择器private var mSelectedYear = 2000 // 当前选中的年份override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_calendar)ll_calendar_main = findViewById(R.id.ll_calendar_main)ll_month_select = findViewById(R.id.ll_month_select)// 从布局文件中获取名叫mp_month的月份选择器mp_month = findViewById<MonthPicker>(R.id.mp_month)// 从布局文件中获取名叫pts_calendar的翻页标题栏findViewById<View>(R.id.btn_ok).setOnClickListener(this)val pts_calendar = findViewById<PagerTabStrip>(R.id.pts_calendar)pts_calendar.setTextSize(TypedValue.COMPLEX_UNIT_SP, 17f)pts_calendar.setTextColor(Color.BLACK)// 从布局文件中获取名叫vp_calendar的翻页视图vp_calendar = findViewById(R.id.vp_calendar)tv_calendar = findViewById(R.id.tv_calendar)with(tv_calendar){this?.setOnClickListener(this@CalendarActivity)}// 万年历默认显示当前年月的月历showCalendar(DateUtil.nowYear, DateUtil.nowMonth)}// 显示指定年月的万年历private fun showCalendar(year: Int, month: Int) {// 如果指定年份不是上次选中的年份,则需重新构建该年份的年历if (year != mSelectedYear) {tv_calendar!!.text = year.toString() + "年"// 构建一个指定年份的年历翻页适配器val adapter = CalendarPagerAdapter(supportFragmentManager, year)// 给vp_calendar设置年历翻页适配器vp_calendar!!.adapter = adaptermSelectedYear = year}// 设置vp_calendar默认显示指定月份的月历页vp_calendar!!.currentItem = month - 1}override fun onClick(v: View) {if (v.id == R.id.tv_calendar) { // 点击了年份文本// 重新选择万年历的年月resetPage()} else if (v.id == R.id.btn_ok) { // 点击了确定按钮// 根据月份选择器上设定的年月,刷新万年历的显示界面showCalendar(mp_month!!.getYear(), mp_month!!.getMonth() + 1)resetPage()}}// 重置页面。在显示万年历主页面和显示月份选择器之间切换private fun resetPage() {isShowSelect = !isShowSelectll_calendar_main!!.visibility = if (isShowSelect) View.GONE else View.VISIBLEll_month_select!!.visibility = if (isShowSelect) View.VISIBLE else View.GONE}companion object {private const val TAG = "CalendarActivity"}
}
package io.shentuzhigang.demo.calendarimport android.content.*
import android.graphics.Color
import android.os.*
import android.util.Log
import android.util.TypedValue
import android.widget.LinearLayout
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import androidx.viewpager.widget.PagerTabStrip
import androidx.viewpager.widget.ViewPager
import androidx.viewpager.widget.ViewPager.OnPageChangeListener
import io.shentuzhigang.demo.calendar.adapter.SchedulePagerAdapter
import io.shentuzhigang.demo.calendar.calendar.SpecialCalendar
import io.shentuzhigang.demo.calendar.util.DateUtilclass ScheduleActivity : AppCompatActivity() {private var ll_schedule // 声明一个日程表区域的线性布局对象: LinearLayout? = nullprivate var vp_schedule // 声明一个翻页视图对象: ViewPager? = nullprivate var mSelectedWeek // 当前选中的星期= 0private var mFestivalResid = 0 // 节日图片的资源编号override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_schedule)// 从布局文件中获取名叫pts_schedule的翻页标题栏val pts_schedule = findViewById<PagerTabStrip>(R.id.pts_schedule)pts_schedule.setTextSize(TypedValue.COMPLEX_UNIT_SP, 17f)pts_schedule.setTextColor(Color.BLACK)ll_schedule = findViewById(R.id.ll_schedule)// 从布局文件中获取名叫vp_schedule的翻页视图vp_schedule = findViewById(R.id.vp_schedule)val tv_schedule = findViewById<TextView>(R.id.tv_schedule)tv_schedule.setText(DateUtil.nowYearCN + " 日程安排")// 获取今天所处的星期在一年当中的序号mSelectedWeek = SpecialCalendar.todayWeek// 构建一个日程表的翻页适配器val adapter = SchedulePagerAdapter(supportFragmentManager)// 给vp_schedule设置日程表翻页适配器with(vp_schedule) {// 给vp_schedule设置日程表翻页适配器this?.setAdapter(adapter)// 设置vp_schedule默认显示当前周数的日程页this?.setCurrentItem(mSelectedWeek - 1)// 给vp_schedule添加页面变化监听器this?.addOnPageChangeListener(SheduleChangeListener())}// 延迟50毫秒再执行任务mFirstmHandler.postDelayed(mFirst, 50)}private val mHandler = Handler() // 声明一个处理器对象// 声明一个首次打开页面需要延迟执行的任务private val mFirst = Runnable {sendBroadcast(mSelectedWeek) // 发送广播,表示当前是在第几个星期}// 发送当前周数的广播private fun sendBroadcast(week: Int) {// 创建一个广播事件的意图val intent = Intent(ACTION_FRAGMENT_SELECTED)intent.putExtra(EXTRA_SELECTED_WEEK, week)// 通过本地的广播管理器来发送广播LocalBroadcastManager.getInstance(this).sendBroadcast(intent)}public override fun onStart() {super.onStart()// 创建一个节日图片的广播接收器festivalReceiver = FestivalControlReceiver()// 注册广播接收器,注册之后才能正常接收广播LocalBroadcastManager.getInstance(this).registerReceiver(festivalReceiver!!, IntentFilter(ACTION_SHOW_FESTIVAL))}public override fun onStop() {super.onStop()// 注销广播接收器,注销之后就不再接收广播LocalBroadcastManager.getInstance(this).unregisterReceiver(festivalReceiver!!)}override fun onResume() {super.onResume()if (mFestivalResid != 0) { // 在横屏和竖屏之间翻转时,不会重新onCreate,只会onResumell_schedule!!.setBackgroundResource(mFestivalResid)}}// 声明一个节日图片的广播接收器private var festivalReceiver: FestivalControlReceiver? = null// 定义一个广播接收器,用于处理节日图片事件private inner class FestivalControlReceiver : BroadcastReceiver() {// 一旦接收到节日图片的广播,马上触发接收器的onReceive方法override fun onReceive(context: Context, intent: Intent) {if (intent != null) {// 从广播消息中取出节日图片的资源编号mFestivalResid = intent.getIntExtra(EXTRA_FESTIVAL_RES, 1)// 把页面背景设置为广播发来的节日图片ll_schedule!!.setBackgroundResource(mFestivalResid)}}}// 定义一个页面变化监听器,用于处理翻页视图的翻页事件inner class SheduleChangeListener : OnPageChangeListener {// 在翻页结束后触发override fun onPageSelected(position: Int) {Log.d(TAG, "onPageSelected position=$position, mSelectedWeek=$mSelectedWeek")mSelectedWeek = position + 1sendBroadcast(mSelectedWeek)}// 在翻页过程中触发override fun onPageScrolled(position: Int,positionOffset: Float,positionOffsetPixels: Int) {}// 翻页状态改变时触发override fun onPageScrollStateChanged(arg0: Int) {}}companion object {private const val TAG = "ScheduleActivity"// 声明一个碎片选中事件的标识串var ACTION_FRAGMENT_SELECTED = "io.shentuzhigang.demo.calendar.ACTION_FRAGMENT_SELECTED"// 声明一个选择星期参数的标识串var EXTRA_SELECTED_WEEK = "selected_week"// 声明一个显示节日事件的标识串var ACTION_SHOW_FESTIVAL = "io.shentuzhigang.demo.calendar.ACTION_SHOW_FESTIVAL"// 声明一个节日图片参数的标识串var EXTRA_FESTIVAL_RES = "festival_res"}
}

实验结果(实验最终作品截图说明)


实验心得

1、熟悉App开发常用的一些高级控件及相关工具,主要包括日期时间控件的用法、列表类视图及其适配器的用法、翻页类视图及其适配器的用法、碎片及其适配器的用法等;
2、熟悉四大组件之一广播Broadcast的基本概念与常见用法;

参考项目

参考文章

《移动项目实践》实验报告——Android高级控件相关推荐

  1. 移动开发技术(Android)——实验5 Android高级控件的应用

    移动开发技术--实验5 Android高级控件的应用 一.实验目的 二.实验内容 1.Spinner.ListView控件与Adapter适配器(一) 2.Spinner.ListView控件与Ada ...

  2. 《移动项目实践》实验报告——Android中级控件

    实验目的 1.熟悉App开发常用的一些中级控件及相关工具,主要包括各种布局用法.特殊按钮的用法.下拉框与基本适配器的用法.编辑框的用法等: 2.掌握Activity的基本概念与常见用法: 实验内容 2 ...

  3. 《移动项目实践》实验报告——Android初级控件

    实验目的 1.掌握Android屏幕显示与初级视图的相关知识: 2.掌握包括屏幕显示基础.简单布局的用法.简单控件的用法.简单图形的用法 实验内容 以windows上的计算器为例,程序界面如下图所示: ...

  4. Android高级控件(二)——SurfaceView实现GIF动画架包,播放GIF动画,自己实现功能的初体现...

    Android高级控件(二)--SurfaceView实现GIF动画架包,播放GIF动画,自己实现功能的初体现 写这个的原因呢,也是因为项目中用到了gif动画,虽然网上有很多的架包可以实现,不过我们还 ...

  5. Android高级控件(一)——ListView绑定CheckBox实现全选,增加和删除等功能

    Android高级控件(一)--ListView绑定CheckBox实现全选,增加和删除等功能 这个控件还是挺复杂的,也是项目中应该算是比较常用的了,所以写了一个小Demo来讲讲,主要是自定义adap ...

  6. Android 高级控件(七)——RecyclerView的方方面面

    Android 高级控件(七)--RecyclerView的方方面面 RecyclerView出来很长时间了,相信大家都已经比较了解了,这里我把知识梳理一下,其实你把他看成一个升级版的ListView ...

  7. Android高级控件(四)——VideoView 实现引导页播放视频欢迎效果,超级简单却十分的炫酷

    Android高级控件(四)--VideoView 实现引导页播放视频欢迎效果,超级简单却十分的炫酷 是不是感觉QQ空间什么的每次新版本更新那炫炫的引导页就特别的激动,哈哈,其实他实现起来真的很简单很 ...

  8. Android高级控件----AdapterView与Adapter详解

    在J2EE中提供过一种非常好的框架--MVC框架,实现原理:数据模型M(Model)存放数据,利用控制器C(Controller)将数据显示在视图V(View)上.在Android中有这样一种高级控件 ...

  9. 《移动项目实践》实验报告——Android组合控件

    实验目的 1.熟悉App开发常用的一些组合控件,主要包括底部标签栏的实现和用法.顶部导航栏的用法.横幅轮播条的实现和用法.循环视图3种布局的用法.材质设计库3种布局的用法等: 实验内容 仿淘宝主页 上 ...

最新文章

  1. Java学习笔记二十五:Java面向对象的三大特性之多态
  2. 基于时间的访问控制列表
  3. pat德才论(java)
  4. 【python】并行化的又一种思路
  5. 从简入难makefile文件编写,Linux C++编程,简单vi命令
  6. Critical error detected c0000374
  7. android sdk build-tools_从零开始仿写一个抖音App——视频编辑SDK开发(一)
  8. nginx设置http强制跳转https
  9. 嵌入式Linux系统编程学习之二十八线程的等待退出
  10. mysql 表列表_一个MySQL表中的多列表显示
  11. 处理器指令编码可重定义的方法_RISC-V学习笔记1 《基于FPGA与RISC-V的嵌入式系统设计》第3章 RISC-V指令集...
  12. 多说评论如何显示最近访客
  13. win10系统任务栏透明方法
  14. 最小项标准式和卡诺图化简
  15. java课设迷宫游戏_Java课程设计走迷宫.doc
  16. 图形库LVGL v8.2版本移植
  17. 深度学习【使用pytorch实现基础模型、优化算法介绍、数据集的加载】
  18. 使用Wake On Lan远程唤醒
  19. 来自 Qt 官网的呐喊
  20. 关于时隙、RB、RE、REG、CCE、RBG等概念的笔记

热门文章

  1. Codeforces 264B Good Sequences ★ (分解素因子+DP)
  2. 如何通过css选取元素以及封装了获取,删除css的相关操作
  3. CG笔记之一——透视投影
  4. mysql delete返回值_Mybatis执行sql(insert、update、delete)返回值问题
  5. java arraylist初始大小_Java - ArrayList默认初始值
  6. gcc 删除elf_ELF文件格式解析器 原理 + 代码
  7. 冒泡排序代码及其思路(怕忘记才记录的_(:з」∠)_)
  8. oracle查询记录插入,我应该使用哪种查询语法在Oracle数据库中插入记录?
  9. Linux 访问文件的acl信息,linux文件权限管理与ACL访问控制列表
  10. 八十三、React简书项目:Styled-Components 与 Reset.css 的结合使用,完成Header布局