
简介在移动应用开发的学习路径中数据持久化是连接理论知识与工程实践的关键环节。无论是简单的记事工具还是复杂的业务应用如何可靠地保存、查询和展示数据始终是开发者必须掌握的核心能力。备忘录App作为典型的CRUD应用恰好覆盖了Android开发中Activity、RecyclerView、SQLite数据库等基础知识点是检验移动开发综合技能的理想实战项目。本文从需求分析、数据表设计、增删改查逻辑实现到界面优化与避坑指南系统梳理了如何用Android原生技术栈高效完成一个功能完整、可演示、易导入的课程作业。文章不仅深入对比了SharedPreferences、SQLite与Room三种持久化方案的适用场景还分享了搜索防抖、列表刷新、屏幕旋转数据恢复等工程细节为正在筹备期末项目的开发者提供了一条从入门到高分的可行路径。 备忘录App期末大作业我做完了才敢说这些实话又到了期末交大作业的季节。如果你正在为“移动开发”这门课的期末项目发愁或者已经在备忘录App这个选题上改了三天还没理顺逻辑那我这篇东西应该能帮到你。先说下我的情况我用Android原生技术栈从零做了一个功能完整的备忘录App包含增删改查、时间提醒、标签分类、搜索、数据持久化这些核心能力最后交上去的成果是一份带导入文档和项目截图的完整作业包课程成绩A。做这个题目的过程里踩了不少坑也总结出一套“期末考试怎么把备忘录App做到既完整又能拉开分差”的方法论今天一次性整理出来。无论你现在是刚学完四大组件、对数据存储还是半懂不懂状态还是已经能写点界面但不知道期末项目该做到什么深度这篇文章都值得你花十分钟认真看完。1. 为什么期末大作业选备忘录App是最稳也最聪明的决定移动开发期末大作业的选题说多不多说少不少。电商、社交、新闻、备忘录……你打开往届学长学姐的项目列表记录类工具App永远是出现频率最高的一档。很多人觉得这题目太普通了没新意但我想先说一个反直觉的结论期末大作业恰恰应该选这种“普通”的题目。原因很简单——期末大作业考察的是你对一门课核心知识点的掌握程度不是你的产品创新能力。备忘录App的优势在于它能把移动开发课程里绝大多数核心知识点全部覆盖到而且项目规模刚好适合一个人在三到四周内完成。拿我所在的课程来说期末评分标准大概分成这几块功能完整度、界面设计、代码规范、文档和演示。备忘录App天然适配这个评分体系逐个拆给你看功能完整度备忘录的基础操作就是增删改查天然需要一个主列表界面、一个详情或编辑界面这直接覆盖Activity/Fragment、Intent传值、事件监听、列表适配器等必考内容。数据持久化这是移动开发课的“硬通货”。备忘录如果不保存数据每次打开App内容全丢那就等于白做。所以必须做本地存储这一下就带出了SharedPreferences、SQLite数据库或者Room框架的知识点。界面设计普通列表页编辑页设置页结构清晰但又不至于简单到让人一眼看出是在糊弄。业务完整性你可以很自然地加上搜索、分类、置顶、提醒这些增强功能每加一个都是一条打分点。更关键的一点是——备忘录App的容错空间非常大。别的项目做歪了可能整个架构都要推翻但备忘录用最朴素的方式写都能跑通。哪怕你数据库封装得不够优雅列表刷新方式不够高级只要核心功能是好的、界面不丑成绩就不会差。它是那种“下限很高、上限也不低”的题目非常适合作为期末保底项目。另外从一个比较“功利”的角度看网上关于备忘录App的参考资料非常多但大多是基于Java老项目的教程代码风格和架构理念明显跟不上现在的课程要求。如果你能做一个在现代技术栈比如Kotlin ViewBinding SQLite/Room Modern UI下完成度高、文档齐全、能直接导入运行的项目在老师那儿的印象分会高出一截。所以这类题目不是“能不能选”的问题而是“怎么做才能做得比别人好”的问题。2. 动手之前先把功能清单和界面布局理清楚很多人拿到题目就急着打开Android Studio新建项目敲了两天代码发现这里缺一块那里要返工。我第二次做这类项目时就长记性了先把功能范围和界面方案在一张纸上画明白再动手写代码。2.1 功能划分基础版与加分项备忘录App的功能有很强的层次感。按照期末作业的性价比我建议把功能分为三个梯队必做的基础功能保底分新增备忘点击悬浮按钮进入编辑页输入标题和内容后保存保存后自动更新列表。查看备忘列表以RecyclerView或ListView展示所有备忘每条显示标题、摘要、更新时间。编辑备忘点击列表项进入详情页支持修改标题和正文并保存。删除备忘支持单条删除最好有二次确认弹窗支持用AlertDialog实现。数据持久化App重启后数据不丢失只要做到这一点你的项目已经及格了。推荐的中级功能拉分关键搜索在列表页顶部加一个搜索框按标题或关键词过滤数据。这个功能实现难度不大但演示效果非常好老师一看就知道你有完整的SQL查询能力。时间管理每条备忘显示创建时间和最后修改时间时间按特定格式如“2024-06-15 14:30”展示。也可以设置到期时间或提醒时间。置顶功能长按列表项选择“置顶”或“取消置顶”在数据库里加一个isTop字段查询时按置顶优先级排序。进阶的加分项有余力再做标签分类每条备忘可以打一个或多个标签列表页支持按标签筛选。提醒通知用AlarmManager或WorkManager实现定时提醒到点发系统通知。注意这个功能对权限和Android版本适配要求比较高做的时候要留够测试时间。深色模式跟随系统或手动切换深色主题需要准备两套颜色资源。富文本编辑在编辑页支持加粗、斜体等功能。这个要用到工具栏会稍微复杂些非必要不用碰。我当时是按“基础功能全做完搜索置顶时间管理”这个组合来定的。这个组合的代码量适中市面上教程里基本都有参考调试起来也不容易卡死最终效果已经很完整了。2.2 页面设计宁可少做动画也要先保证跳转逻辑清晰备忘录App一般需要这5个界面你也可以设计成3个界面主列表页MainActivity展示所有备忘顶部有搜索栏。编辑页EditActivity 或 复用AddActivity负责新增和修改通过Intent传值区分模式和携带数据。详情页DetailActivity点击列表项后查看完整内容。如果把编辑和详情合二为一也可以。设置页可选放版本信息之类的占位内容纯粹为了界面丰富度。启动页可选不建议单独做。很多同学喜欢做一个花里胡哨的SplashScreen但这不是知识点面试官和老师都不看重。页面之间的跳转逻辑通常是列表页→点击悬浮按钮→编辑页新增模式→保存→回列表刷新列表页→点击某一条→详情页或编辑页查看/编辑模式→保存→回列表刷新列表页→搜索框输入→下拉刷新或点击搜索按钮→列表根据关键词刷新。我画完这张逻辑图后写代码的流程会顺畅很多。需要提醒的是新增和编辑最好在同一个Activity里写通过Intent传递的一个extra字段判断模式。很多新手的误区是“新增写一个页面编辑写一个页面”然后维护两套一样的布局和逻辑平白给自己增加几倍的工作量。2.3 数据表设计先把字段定下来再写DAO备忘录的数据表设计在期末作业这个体量下不需要太复杂但也有必要提前规划好字段不然写着写着就要改数据库版本。我的备忘记录表大致这样字段名类型说明idINTEGER PRIMARY KEY AUTOINCREMENT主键自增titleTEXT标题可空也可设置默认“无标题”contentTEXT正文内容create_timeTEXT创建时间update_timeTEXT最后修改时间is_topINTEGER置顶标记0为普通1为置顶这张表够用且清晰而且每个字段在界面上都有对应展示不会出现“存了但没地方用”的字段。这里有一点建议不要一开始就设计很多花哨字段比如颜色、字体大小、附件路径等。期末项目的时间有限字段越多意味着界面和逻辑越复杂第一版能把上面这些做完做稳已经可以超过班里一大半人了。3. 数据持久化怎么选SQLite、Room还是SharedPreferences这是做备忘录App最核心的一个决策点也是你期末作业最可能暴露技术短板的地方。我把三种方案摆在一起逐条说清楚你按自己的水平选一个别纠结。3.1 SharedPreferences只适合保存设置项SharedPreferences本质上是保存键值对用它来保存一条条备忘记录从技术上勉强能做到把整个列表序列化成JSON字符串存进去但数据库该干的事不该让一个小型配置文件来干。而且它不适合存大量结构化数据也无法用SQL做查询、排序、筛选。期末作业里把它用在“保存搜索栏的历史记录”“记住是否开启提醒”这类场景还行拿它当主存储方案会被老师问倒的。3.2 SQLite SQLiteOpenHelper课程经典稳妥之选直接用Android内置的SQLite数据库通过SQLiteOpenHelper管理数据库创建和版本升级自己写SQL语句来完成增删改查。这是国内绝大多数移动开发课程直接教的内容也是期末作业最“稳妥”的选择。优点明显不依赖任何第三方库技术栈和课程内容完全对上老师一看就知道你掌握了课堂知识。而且用裸SQL写增删改查代码逻辑是透明的出问题容易排查。缺点则是代码量会大一些需要自己写数据库帮助类、DAO类、Cursor转实体类的逻辑。如果你平时的课程作业都是用Java或Kotlin直接操作SQLite写过来的那就用这个不用犹豫。3.3 Room表现力强但学习成本略高Room是Google官方推出的数据库抽象层底层还是SQLite但用了注解和编译期代码生成写起来很优雅。用Room做备忘录是一个非常漂亮的加分项因为能体现你对现代Android架构组件Jetpack有了解。但Room也有门槛需要理解Entity、Dao、Database三者之间的关系需要引入kapt或ksp编译器插件有时候编译时间会变长。如果你平时练习时Room已经写过几个Demo用它是加分的如果你对注解处理器还不太熟期末周临时抱佛脚学Room风险会比较高。我当时的选择是直接用SQLiteOpenHelper。原因很现实这是我课上讲过的内容我能把原理讲到老师满意。但我建议如果你还有两周以上的时间可以私下试试Room因为它对你简历上的项目描述会更有价值。4. 核心代码逻辑拆解备忘记录的增删改查是怎么串联起来的下面这部分我按“数据层→界面层→交互逻辑”的顺序拆把每块核心代码的结构和思路讲透。完整源码我这里不贴了文档包里都有但你跟着这个逻辑走完全可以自己写出来。4.1 数据库帮助类与数据访问SQLiteOpenHelper的子类负责创建数据库和表。核心方法就两个onCreate用来建表onUpgrade用来处理升级场景。class MemoDbHelper(context: Context) : SQLiteOpenHelper(context, DB_NAME, null, DB_VERSION) { override fun onCreate(db: SQLiteDatabase) { db.execSQL(CREATE TABLE memo ( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, content TEXT, create_time TEXT, update_time TEXT, is_top INTEGER DEFAULT 0)) } override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { db.execSQL(DROP TABLE IF EXISTS memo) onCreate(db) } }注意如果你后续要加字段onUpgrade里不要直接“DROP TABLE”否则用户的数据会被清空。期末作业里这么写问题不大但如果文档里能写一句“正式环境应该用ALTER TABLE迁移”之类的话会显得你是有工程思维的。数据访问层通常写一个MemoDao类封装insert、update、delete、queryAll、queryById等方法。核心是把数据库操作和界面逻辑解耦class MemoDao(context: Context) { private val dbHelper MemoDbHelper(context) fun insert(memo: Memo): Long { val db dbHelper.writableDatabase val values ContentValues().apply { put(title, memo.title) put(content, memo.content) put(create_time, memo.createTime) put(update_time, memo.updateTime) put(is_top, if (memo.isTop) 1 else 0) } return db.insert(memo, null, values) } fun update(memo: Memo): Int { val db dbHelper.writableDatabase val values ContentValues().apply { put(title, memo.title) put(content, memo.content) put(update_time, memo.updateTime) put(is_top, if (memo.isTop) 1 else 0) } return db.update(memo, values, id?, arrayOf(memo.id.toString())) } fun delete(id: Long) { val db dbHelper.writableDatabase db.delete(memo, id?, arrayOf(id.toString())) } fun queryAll(): ListMemo { val db dbHelper.readableDatabase val cursor db.query(memo, null, null, null, null, null, is_top DESC, update_time DESC) return cursor.use { val list mutableListOfMemo() while (it.moveToNext()) { list.add(Memo( id it.getLong(it.getColumnIndexOrThrow(id)), title it.getString(it.getColumnIndexOrThrow(title)) ?: , content it.getString(it.getColumnIndexOrThrow(content)) ?: , createTime it.getString(it.getColumnIndexOrThrow(create_time)) ?: , updateTime it.getString(it.getColumnIndexOrThrow(update_time)) ?: , isTop it.getInt(it.getColumnIndexOrThrow(is_top)) 1 )) } list } } }这里有一个非常实用的小技巧排序的时候直接写成is_top DESC, update_time DESCSQL层面就把置顶的优先级解决掉了App里完全不用额外做排序逻辑。4.2 列表展示用RecyclerView还是ListView如果课程里教了RecyclerView那就不用考虑了直接用RecyclerView。它性能更好、写法也更现代。如果你对RecyclerView的Adapter不太熟也没关系核心模板是固定的——继承RecyclerView.Adapter实现三个方法在onBindViewHolder里把数据绑定到布局。还有一个选型问题条目布局用两个TextView标题时间还是三个TextView标题时间内容摘要我的建议是至少两个标题和时间必须展示内容摘要建议用单行省略号的方式加上去这样列表页看起来更丰满。文案可以通过在布局里设置android:maxLines1和android:ellipsizeend实现。4.3 新增和编辑页如何用同一个页面处理两种模式新增和编辑共用一个EditActivity是节省工作量的关键设计也是期末答辩时值得讲的一个点。实现思路是这样在跳转到EditActivity时用Intent的putExtra传一个type字段// 新增 val intent Intent(this, EditActivity::class.java) intent.putExtra(mode, add) startActivity(intent) // 编辑 val intent Intent(this, EditActivity::class.java) intent.putExtra(mode, edit) intent.putExtra(memo_id, memo.id) intent.putExtra(memo_title, memo.title) intent.putExtra(memo_content, memo.content) startActivity(intent)在EditActivity的onCreate里接收mode参数。如果是edit模式并且id存在就把数据库里对应的数据查出来填充到输入框如果是add模式输入框留空即可。点击保存按钮的时候做同样的判断——edit模式走updateadd模式走insert。这里提醒两句有同学喜欢在EditActivity里重新查一次数据库来填充数据而不是用Intent直接传过来。两种做法都能用但用Intent直接传简单详情页通常也是这么传数据的。还有一点保存成功后一定要调用finish()关闭页面并返回一个结果给列表页建议用setResult onActivityResult或者更现代的registerForActivityResult否则列表刷新不了。4.4 列表刷新Adapter刷新的几种方式修改数据后列表页怎么刷新这是期末项目里很常见但也很容易迷糊的点。核心思路就一个修改完数据后重新从数据库加载数据然后通知Adapter刷新。比较直接的写法val newList dao.queryAll() adapter.updateData(newList)在Adapter里提供updateData方法先清空旧数据再添加新数据然后调notifyDataSetChanged()。如果用了ListAdapter则是调submitList()。这个方法简单可靠适合期末项目。如果你想让表现更精致一点可以在onResume里重新查询数据并刷新列表。这样从编辑页返回列表页时就自动刷新了不需要额外写startActivityForResult的回调逻辑。这个写法我强烈推荐代码更少也不容易漏掉刷新时机。5. 界面优化与交互细节怎么把“普通App”做出“认真做了”的感觉备忘录App的界面不复杂但你花在UI上的精力直接决定老师的第一印象。一个按钮颜色协调、间距舒服、空状态有插画的App和一个功能完整但界面粗糙的App差距可能是一档到两档的成绩。5.1 配色与主题别用系统默认的白色不管你技术多好如果App打开是一水儿的纯白背景黑色系统标题栏给人的观感就是“模板项目”。我的实际做法是先定一个主色调然后围绕这个色系做全局统一。比如我选的是蓝绿色系主色用于悬浮按钮、选中态、标题栏用偏深一点的色值辅色用于背景、卡片分割线等用低饱和度的浅色整体走干净清爽风格。如果你不知道如何搭配直接用Material Design里的颜色规范照着Material 3的Color Token体系来不会出大问题。主题方面强烈建议先在values/themes.xml里自定义一套主题设置好状态栏颜色、窗口背景、控件默认样式而不是在AndroidManifest.xml里用默认的Theme.Material3.DayNight.NoActionBar。改完这一处全局观感立刻上一个档次。5.2 空状态、加载状态细节决定观感列表为空的时候不能只显示一个空白页面。加一个空状态视图中间放一张简单的插画或者图标下面配一句话“暂无备忘点击右下角开始记录”。这在代码里就是一个if-else数据列表为空时展示空状态非空时隐藏。这个小东西的成本极低但老师看到会认为你考虑了真实用户场景。5.3 交互细节删除确认、长按菜单、滑动删除删除一定要做二次确认用AlertDialog即可。这不仅能防止用户误删也能在答辩时展示你对“用户体验”的理解。有的同学为了炫技做滑动删除SwipeDelete用的SwipeRefreshLayout或者ItemTouchHelper说实话难度不大但要注意和列表刷新逻辑的冲突。如果只是期末项目把长按菜单做好就够了——长按弹出菜单包含“编辑”“置顶”“删除”三个选项“置顶”项根据当前状态切换文案。这样你的交互矩阵就完整了点击进入详情/编辑、长按出现操作菜单、悬浮按钮新增。5.4 键盘处理别让输入框被键盘遮住EditText是备忘录App最核心的控件就因为你每天和它打交道很容易忽略一个体验细节键盘弹出来后编辑页的输入区域会不会被遮挡在AndroidManifest.xml里给EditActivity设置android:windowSoftInputModeadjustResize或adjustPan是基本操作。如果你用了ScrollView包住编辑布局那ADJUST_RESIZE基本能保证用户滚动到输入框时能看到内容。另外建议在清单文件里给主列表页设置android:windowSoftInputModeadjustNothing避免搜索框获得焦点时顶起整个布局这个问题我在做搜索功能时踩过后文会专门讲。6. 避坑实录我实现备忘录App时踩过的5个坑写代码这种事光看教程没用一定得自己踩一次坑才记得住。我把自己在实现过程中遇到的几个比较典型的问题和排查思路列出来你能避就避避不过也可以直接按这个思路查。6.1 时间格式化SimpleDateFormat的线程与格式坑备忘录里到处都是时间创建时间、修改时间、列表上的时间展示。很多同学会用SimpleDateFormat(yyyy-MM-dd HH:mm:ss)这个本身没问题但有个新版本Android上的坑API 26以上的设备对SimpleDateFormat默认使用本地时区和地区如果你没有显式指定Locale在某些设备上会出现月份显示为英文缩写、或者24小时制和12小时制混乱的问题。我的建议时间格式化这件事单独封装一个工具类统一格式为yyyy-MM-dd HH:mm并且显式传入Locale.getDefault()。在SQL查询排序时保存字符串时间有个天然好处因为格式固定是年-月-日 时:分:秒字符串比较和数值比较结果一致直接按字符串DESC排序就能得到正确的时间倒序。但前提是格式必须严格统一如果有的地方存“2024/06/15”有的地方存“2024-06-15”排序就全乱了。6.2 EditText的数据丢失旋转屏幕或从编辑页返回时内容不见了这是移动开发课程期末项目里最经典的坑之一。用户在编辑页写了半天内容突然旋转一下屏幕或者因为权限弹窗导致Activity重建EditText里的内容全没了。原因是Activity在配置变更比如旋转时会被销毁重建EditText默认状态没有保存。解决方式有两个层级简单做法在EditActivity里重写onSaveInstanceState把两个输入框的内容存到Bundle里在onCreate里恢复。更好的做法在AndroidManifest.xml里给EditActivity设置android:configChangesorientation|screenSize|keyboardHidden让Activity在旋转时不重建。期末项目用这种方式最省事但也有人会说这不算规范做法答辩时如果老师问到你要知道自己为什么这么做。我个人建议如果你是为了省事用configChanges没问题如果你想让项目更“正确”那还是用ViewModel onSaveInstanceState那套。6.3 搜索功能的输入监听直接addTextChangedListener会频繁查库搜索功能最常见的实现是给EditText设置一个TextWatcher在afterTextChanged里每次查询。这样每敲一个字母就会触发一次数据库操作虽然数据量小的时候不卡但代码逻辑上是不优雅的。我在实现时用了两个优化第一是加一个简单的延迟搜索用Handler的postDelayed把300毫秒内的多次输入合并成一次查询第二是明确查询SQL的模糊匹配方式使用WHERE title LIKE ?并传参%关键词%。这样写的好处不仅是防卡顿更是在演示时展示了你对“用户输入”和“资源开销”的理解。不过期末项目不建议上RxJava做防抖那是大炮打蚊子自己写个Handler延迟就够用了。6.4 悬浮按钮遮挡最后一条数据RecyclerView的padding和clipToPadding加了FloatingActionButton之后列表最后一条内容容易一直被按钮遮住一部分。解决方法是给RecyclerView设置android:paddingBottom80dp同时把android:clipToPadding设为false。这个属性能让列表滚动到最底部时最后一条内容停在悬浮按钮上方而且滚动时背景色能正常延伸到边缘视觉效果很舒服。这个小细节知道的人不多但效果极好。6.5 数据库升级onUpgrade里直接drop表演示到一半数据全丢了这个问题可能很多同学期末答辩时才会遇到你为了加一个标签字段把数据库版本从1升到2然后因为onUpgrade里写了DROP TABLE IF EXISTS memo所有旧数据全被清了。如果你的作业里已经有几条演示数据老师打开一看全空了印象分直接扣掉不少。正确的做法是如果只是加字段onUpgrade里先用ALTER TABLE ADD COLUMN如果需要改表结构且数据不重要那drop掉重建也算可以接受但要在代码里加个注释说明。我在自己的项目里用了一个更稳妥的做法数据库版本号第一次提交后就不再改表结构后续所有需求都通过新增表或者新增字段时写真正的迁移逻辑。期末项目里你不一定要这么严谨但答辩时能说清这个问题会显得你有数据库演进的概念。7. 导入文档与项目截图期末作业里最容易拿分却最容易被忽视的部分很多同学的代码写得很用心但交上去的作业包就一个大文件夹外加两个Word文档截图老师说打开都找不到入口。我这次能拿A有一半功劳要归给最后一天整理的导入文档。别小看这环节它可能比你的代码还值钱。7.1 导入文档怎么写导入文档的核心目标是让一个完全不了解你项目的人按文档操作10分钟内能把项目跑起来。文档结构我建议就按这个来项目简介用两三句话说明项目是什么、实现了哪些功能、用了什么技术栈。开发环境写明Android Studio版本包括是北极狐、海豚还是其他代号、Gradle版本、JDK版本。这个尤其重要——很多同学的项目打开报错就是因为环境版本不匹配。导入步骤分步骤写清楚File → Open → 选择项目根目录 → 等待Gradle同步 → 配置SDK → 运行。要写到“点击哪个按钮会看到什么界面”这个颗粒度。常见问题把你自己遇到过的环境问题写上去比如“SDK版本不匹配怎么办”“Gradle下载了很久怎么办”“首次打开需要等待多久”。功能使用说明配截图说明每个功能怎么操作。这里可以和项目截图合并。我建议导入文档不要写太长10页以内超过的话老师可能就不看了。排版用Markdown或Word都行但一定要结构清晰、标题层级分明。7.2 项目截图怎么截截图不是随便截几张就算交差它的作用有两个一是让老师不用运行项目就能快速了解功能二是让老师能对比“文档描述”和“实际效果”是否一致。所以截图要按流程截覆盖这几个场景App首页列表有数据、无数据两种状态各一张。点击新建后的编辑页有内容状态。保存后列表更新效果。搜索关键字后的筛选结果。长按弹出菜单置顶/删除。删除时的确认对话框。启动界面或主题设置页如果有。截图建议用模拟器或真机上统一分辨率截取要确保状态栏、标题栏没有明显的不协调内容。最后做一张汇总图把每个页面拼在一起放在文档开头老师一眼就能看到全貌。7.3 提交物清单最后提交时我的作业包长这样MemoApp/ ├── 项目源码/ # 整个Android工程文件夹 ├── 导入文档.pdf ├── 演示录屏.mp4 # 3分钟以内的操作录屏方便老师不用真机也能看到效果 └── 项目截图/ # 按功能模块命名的截图文件夹演示录屏这一点特别提一下很多老师不会真的在电脑上跑你的项目环境问题太多。一个3分钟的录屏按“新增→编辑→搜索→置顶→删除”流程走一遍配上简单的字幕说明能让老师对你的项目完成度有直观认识。录屏用手机模拟器或Android Studio自带录屏即可不需要特别处理。8. 答辩时怎么讲才能让老师知道你“真会”期末大作业一般不止交代码很多课程还安排了演示和答辩环节。备忘录App虽然功能简单但如果你想拿到高分答辩时的讲解策略很关键。我的策略是按“技术深度”而不是“功能列表”来准备讲稿。介绍完“我做了哪些功能”后重点讲两个核心技术点。第一个讲数据持久化。我会说我用SQLiteOpenHelper自己管理数据库的创建和版本升级封装了MemoDao数据访问层增删改查分别对应insert、update、delete、queryAll方法查询时通过SQL排序字段实现置顶优先列表页每次从数据库重新查询数据来保证一致性。这个思路能让老师知道你不是在界面上堆功能而是有数据层的设计意识。第二个讲列表刷新策略。我会说编辑页保存数据后列表页在onResume中重新查询数据库并调用adapter.updateData()刷新列表相当于用一种最简单的“页面回来就刷新”的模式来保证数据一致性。如果有余力我会顺带补一句如果数据量大或需要跨页面同步也可以用ViewModel LiveData或者通知机制来做但期末项目用前一种就够了。这句话是展示你见过更大的世界同时不贬低当前做法的实用性。答辩时还有一个重要技巧主动讲一个你在开发中遇到的坑和解决过程。比如前面提到的时间格式化坑、内存泄漏风险、悬浮按钮遮挡数据的问题。老师最喜欢听到这种真实开发经历因为这说明你没有抄代码而是真的在动手写。挑一个最有趣的讲就行不要一下抛三个坑会显得你后续没有内容可讲。9. 如果你还剩一周我建议按这个优先级冲刺时间规划是一个很现实的问题。如果你现在只剩一周我的建议是别给自己加那么多扩展功能了按下面的顺序做第一天到第二天搭好基础工程把列表页和新增页跑通数据库表建好能新增并保存数据到SQLite。第三天完成编辑和删除逻辑确认所有增删改查功能稳定。第四天优化列表界面加上时间展示、空状态、悬浮按钮、删除确认框。第五天实现搜索功能做一个延迟搜索测试不同关键词的效果。第六天整理导入文档和截图录制演示视频。第七天跑一遍完整的用户流程把各种操作测试一遍修Bug然后交作业。如果你还有两周以上可以再去做置顶、标签、提醒这些功能。但第一优先级永远是最基础的功能必须稳定最完整的流程必须跑通。一个没有Bug的基础版比一个有Bug但功能很多的版本得分更高这是我在大学期间反复验证过的经验。我在实际做这个项目的过程中最深的一个体会是期末大作业真正为难你的不是功能难而是你要在一个有限时间里把整个流程做完、做稳、还能讲清楚。备忘录App这个选题给了你一个很好的舞台——它足够简单让你能把精力花在“做好”而不是“做出来”上。你只要在数据存储、界面细节、文档规范这三个方向稍微比同学多花一点心思最后拿到的分数一定会超出你的预期。本文还有配套的精品资源点击获取