[音乐] 大家好，欢迎来到
我的 android 速成课程在布拉德的频道上
你需要了解 kotlin 才能参加我的这个速成课程
还在布拉德的频道上做了一个速成课，所以我相信他会链接
在这个视频的描述中，你真的应该确保
在开始之前了解这些 kotlin 基础知识
android开发速成课程，因为我可以解释
除了所有 kotlin 语言功能
android 框架，所以我们将在这里构建的内容本质上是这样的
待办事项列表应用程序在这里所以我们可以在这里添加待办事项，例如带出
垃圾桶然后我们点击添加来做它会被添加到
我们的待办事项列表我们可以添加另一个项目提要
猫点击添加来做，它也会被添加
然后我们可以只检查那些并取消选中那些
如果我们有一些检查，然后我们可以点击删除完成，它会
只需从我们的列表中删除所有要做的检查，然后
在这里重要的是要注意这个速成课程真的适合那些
以前从未使用过 android，只知道
kotlin 基础知识，所以我不会在这里实现一个真正的数据库，我们将它们保存到
在数据库中做一些对于速成课程来说太多的项目
所以这意味着当我们重新打开应用程序时，列表将是
再次空，但如果你有兴趣学习
android 中的这些更高级的主题然后一定要查看
我的频道我有一堆安卓教程
特别是使用 kotlin 我非常关注项目
基于播放列表，所以我有一个正在运行的跟踪器应用程序和音乐播放器应用程序
和一个新闻应用程序以及更多你可以在我的频道上学到的东西
所以就试一试看看吧
首先我想谈谈
为什么我们在这里使用棉花进行 android 开发，因为现在你有
制作安卓应用程序的许多选项，尤其是
现在非常流行使用像 flutter react native all 这样的选项
那个跨平台的东西，所以用颤振
react native 你只需要制作一个应用程序，你也可以在 ios 上使用它
如果你用 kotlin 做那不是这种情况，但我仍然不建议使用任何
这些跨平台框架至少可以
从这些开始，我总是建议从
原生 android 平台，即使用 kotlin
因为特别是对于更复杂的应用程序，没有真正的方法
围绕使用 kotlin 制作原生应用程序
实际上android是基于java的，kotlin也是基于java的
这就是为什么我们实际上可以使用 kotlin 进行 android 开发
您也可以使用 java 但这也不是真正推荐的
因为谷歌是android的所有者
只是推动棉花真的很难为 android 开发
而java现在几乎快要消亡了
所以这不仅是你可以用 kotlin 做几乎所有的事情比
使用 java 也是 kotlin 不断获得更多
以及更多 java 没有的功能，这些功能确实是
将完全改变方式的基本功能
我们将制作 android 应用程序，所以这只是我的建议，如果你
问其他人他们可能会告诉你其他的东西
但我总是说先学习真正的 android 开发，所以这意味着
了解真正的android框架原生android框架
如果你只是想尝试一下，那么使用 java 就可以了
但如果你现在真的想学习如何制作安卓应用程序，那么
真的没有办法绕过 kotlin 所以我们首先需要做的是
从android开发开始是我们需要安装一个名为的软件
android studio 如果你看过我的 kotlin 速成课程
我希望你这样做然后我们你知道我们使用了intellij
那里也是 jetbrains 的软件所以
android studio的软件风格
将与我们在那里使用的 intellij 非常相似
但是对于android开发，我们理论上也可以使用intellij
但是我们将在这里使用的这个 android studio 软件只是
我们可以直接构建针对 android 开发的更多优化
布局中，我们可以有一个模拟器，我们可以在其中测试我们的应用程序
默认情况下，它仅具有所有这些功能，并且
使android开发更容易，我们只需下载android studio
想去谷歌输入android studio下载
按回车键，我们只想访问这里的第一个链接
developer.android.com studio 点击它，一旦页面出现
加载我们可以在这里点击这个绿色的大按钮
我们需要接受许可协议选中此框并单击下载
android studio here 然后我们可以简单地点击保存
在这里，然后这需要一点时间
一旦完成，我会再见到你，我们只是想
运行这个文件点击运行并稍等片刻
直到安装程序打开，所以我们需要
在这里接受一些东西
按 yes 并稍等片刻，然后我们就可以进行设置了
容易，尤其是与 intellij 相比，它更容易，因为我们不需要
自己安装jdk，就是java开发包
只附带所有那些 java 和 kotlin
语言功能，因为 android studio 已经自带了
并为我们安装它，以便我们可以点击下一步
我们要安装 android studio 和 android 虚拟设备，所以这只是
android模拟器 因为我们当然在一个
这里的 windows 环境或 mac 或您使用的任何东西我们都不能
只需在那里测试我们的应用程序，我们将做的是安装一种
只是模拟 android 行为的虚拟机，我们
也会安装，否则我们无法测试我们的应用程序
如果你没有安卓手机，我们点击下一步
然后你可以选择一个路径来安装它，我会点击下一步
并安装然后我会再见到你
好的，一旦安装完成，我们只需点击下一步
我们想通过点击完成来启动 android studio
然后我们等到它启动我们需要在这里打开它
如果我们之前安装了 android studio，我们可以
在这里导入我们的旧设置，我们没有，所以我们点击不导入
设置，好的，然后这里的设置向导将
打开我们可以简单地点击下一步这里我们要选择标准
android studio的安装再次点击下一步
当然我们这里会选择深色主题
我们点击下一步，现在android studio会在这里下载一堆文件
运行 android 应用程序所需的 android
在此处模拟 sd sdk 工具，我们只需单击此处完成即可
一旦完成，android studio 会为我们做这件事，它会给
你在这里做一个小总结，对我来说我在这里有一个错误，因为我
在 Windows 虚拟机上的虚拟机上运行它
它只是无法安装这个 android 模拟器，它也是一个虚拟机
在虚拟机内部，所以如果你安装，这不应该发生在你身上
这是在你的真实电脑上，嗯，我会切换到我的真实电脑上
在我向您展示此安装后，我们只需单击“完成”即可
现在我们看到这个弹出窗口，我们可以
在这里开始一个新的 android studio 项目，让我们点击它
然后我们可以选择一个项目模板我们将在这里选择空活动
什么是活动我会在我们实际解释的时候
在这里浏览单个 android 组件，所以让我们先点击下一步
我们可以给我们的应用程序一个名字，我将称之为
待办事项列表你可以给它一个包名
我就让它在这里你可以在这里选择你的名字
而不是示例，然后我们要确保语言
是 kotlin，它只是这里的默认语言，但您可以看到我们可以
也选择java，最小sdk基本上是
我们希望将其设置为 api 21 的最低支持 android 版本。
如果你增加那个 api，那总是有点权衡
那个最低的 api 版本嗯，因为较新的 apa 版本当然有
更现代的功能和更新的语言功能
和旧版本当然那么你只是支持更多的设备
但现在几乎所有设备都至少在 api 级别 21 上运行，所以 android
棒棒糖在这里，然后我们可以简单地单击完成，android studio 将
为我们创建该项目，这样我们就可以得到一点
最新 android studio 版本的新功能摘要
我们可以将其最小化，乍一看这看起来非常
类似于我们在 intellij 中所拥有的，好吧，所以我现在切换回我的真实
机器脱离虚拟机，但这不应该做任何事情
对你来说不同我首先要完成这个项目
这里有点层次结构，所以你可以看到我们有一个项目
左侧的层次结构我们可以打开这个应用程序文件夹
你这是待办事项清单它是如何并不重要
调用，这里我们有一堆 android studio 的文件
自动为我们生成，当我们创建一个新项目时它总是这样做
所以你已经可以看到它在这里打开了这个主要的活动文件，如果你看
棉花速成课程你至少可以认识到这是
kotlin 代码在这里所以实际上是一个活动
android 一个活动最终只是我们应用程序中的一个屏幕，所以
在我们的应用程序中，在我们的待办事项应用程序中，我们将只有一个活动
它代表待办事项列表屏幕，我们将在其中拥有
不同的视图，所以单个视图只是一个内部的可见元素
活动或在我们的屏幕上例如一个按钮一个文本视图所以只是
一个文本标签我们的待办事项列表以及所有这些
被称为查看机器人的东西和
这样的活动只是我们应用程序中的一个屏幕
包含多个视图并具有这样的活动
我们通常有两个组件属于这个活动
一方面是这个 kotlin 文件，你可以看到它只是一个类
从应用程序兼容活动继承的 kotlin
这只是让它具有真实活动的行为
一个活动总是有一个生命周期，所以
你也可以看到它带有这个 oncreate 函数
这只是创建此活动后调用的函数
在android中，我们没有这个主要功能，因为我们在intellij中拥有它
kotlin 它也将具有该主要功能
在 android 框架的深处，但我们在这里看不到它
我们将把应该立即执行的代码
一旦我们的应用程序在此 oncreate 函数内启动
而这个 oncreate 函数基本上只是所谓的函数中的一个
活动生命周期，我不会在这里介绍，但例如还有
当该活动被销毁时的销毁功能以及更多
这些生命周期函数所以我们可以只对特定状态做出反应
我们的活动，所以这里的 kotlin 文件是一个
活动的组成部分，通常在我们进行活动时
我们还需要以某种方式设置该活动的设计
所以如果你有网络开发人员的背景，我猜你们很多人都有
如果您熟悉布拉德的频道，那么
作为 Web 开发人员，您通常使用 css 进行设计
在 android 中有点不同，所以在 android 中我们有 xml
文件你可以看到它已经打开了这个活动主xml
文件，在这个 oncreate 函数中，我们设置了内容视图
正是这个布局文件，如果我们切换到这个
活动主xml文件你可以看到这是android studio的布局编辑器
这里只包含一个文本视图
所以只是一个基本上属于的文本标签
到这里的主要活动，所以如果我们现在启动我们的应用程序
那么这个带有hello world文本视图的白色屏幕就会打开
所以这就是我们的应用程序现在所做的一切
好的，这就是 android 中的活动
但是我们这里还有一些对我们的应用程序很重要的文件
如果我们看看我们的项目层次结构，我们有这个清单文件夹
如果我们双击它，那么它也是一个 xml 文件
在 android manifest 中，我们实际上只是声明了一些
应用程序设置有点，所以你可以看到我们有
启动器图标，所以实际上这是我们的应用程序启动的图标，所以
单个应用程序图标我们有我们拥有的应用程序的名称
我们想要设置为我们有活动的应用程序的主题
在此清单中声明，如果我们需要，我们也可以声明
此处针对我们应用程序的特定功能的权限
需要，例如，如果我们需要互联网访问
那么我们需要在这个清单中声明一个权限
我们的应用程序需要此互联网功能
那么这个java文件夹我们已经介绍过了
那只是包含我们的文件夹
实际的纸箱文件，所以不要混淆，这被称为 java
这将在我们的应用程序中包含 kotlin 文件，然后您将拥有三个 com
那些对我们不重要的文件夹
与测试相关，这是一个非常高级的话题
但这里的第一个文件夹实际上是包含我们主要的文件夹
活动 kotlin 文件，然后我们有这个 raz 文件夹
代表资源，我们只是把各种资源
在这里，我们有一个 drawable 文件夹，其中包含我们有一个图像资源
布局文件夹，其中包含我们的布局文件，以便
例如活动，但我们也会有另一种层
我将在此视频中访问的文件，我们将有一个中间地图文件夹
包含这些我们不经常需要的启动器图标，我们有一个
此处的值文件夹还包含 xml 文件，因此颜色
例如，我们只声明主题的xml
我们的应用程序的颜色，所以你可以看到我们有一个颜色原色原色
暗，我们可以在我们的应用程序中引用这些颜色
所以我们并不总是需要在这里记住这个颜色代码
然后我们有一个字符串 xml 文件，我们可以在其中声明应用程序写入
字符串常量，我们有一个样式 xml 文件，我们可以在其中
为我们的应用程序创建样式，我也不会在本教程中这样做
在这里因为那需要更多
有关启动 android 的知识，但实际上还有一个文件
对我们来说重要的是在此 gradle 脚本文件夹中
所以 gradle 是 android 的构建引擎，所以这意味着 gradle 的工作只是
把所有这些文件所有的活动清单 xml 布局文件
并把它们放在一个可执行的应用程序中
这当然非常重要，你可以看到我们有一堆
这里的文件大部分对我们来说并不重要
这里需要，但是这个 build.gradle 模块冒号应用程序文件
这很重要，我们需要打开只包含一些应用程序的
在这里配置例如我们的最低sdk版本
我们在创建该项目时选择了但如果我们向下滚动，您可以看到我们
这里有依赖关系，这些实际上是指向
我们希望包含在我们项目中的第三方库
并且因为我们在此待办事项列表中使用的这个特定视图不是
默认包含在android框架中
我们需要为此添加这样一个依赖项，我实际上只是粘贴这个
这里与链接非常相​​似
有了这个android studio就可以获取信息
关于该视图并包含在我们的项目中
我敢肯定布拉德只会在此视频中包含此链接
描述但你也会找到源代码
到此视频描述中的此项目
来自我的 github 存储库，一旦我们在其中添加了一些东西
build.gradle 文件，我们在顶部看到这个蓝色条
我们现在需要点击同步，这样 android studio 才会同步
对我们项目的这种新依赖，并为我们包含这些资源和
一旦同步完成，我们实际上可以开始
构建我们应用程序的布局，我们将执行此操作
在我们的活动主 xm 文件中，因为正如我所说，这是布局文件
将与我们的实际主文件结合显示的样式文件
活动因此当我们启动我们的应用程序时将显示的屏幕和我已经
说这种类型的样式与 css 有很大不同，所以我们将有
你可以在android中看到这样的约束布局，我们总是处理
这些布局只是帮助我们使这个布局基本上对所有人都有响应
各种屏幕尺寸，您现在可以看到它包含
我们实际上不需要的单个文本视图，我们不想拥有
所以我们只需选择它并按下
删除以删除它，现在我们实际上有
这些项目这些不同的意见在这里所以每个
那个项目是一个单一的视图，我们可以简单地拖放它们
进入我们的布局以包含它们，我想要开始的是
这个 recyclerview 所以这就是为什么我们把它包括在内
在我们的 build.gradle 文件中的依赖项现在我们可以在这里使用这个 recyclerview
并且该接收器视图只是我们应用程序中的项目列表，为什么
这实际上称为 recyclerview 而不是列表视图，例如
会更不言自明 android 也有一个列表视图，但是
绝对不推荐使用
这在这里称为 recyclerview，因为它具有回收行为
这意味着当我们在该列表中滚动时
它只会加载用户当前可见的项目
还有一些基本上是关闭可见的
但是如果我们有一千个项目的列表，那么我们并不总是需要加载
要在我们的应用程序中显示的整个列表，这只会使这个回收站的视图更加丰富
比这个总是保留整个列表的旧列表视图性能更高
内存并在我们的屏幕中使用它，我们可以简单地拖动和
把它放到我们的领域，你现在就可以看到
它填满了整个屏幕，我们也可以
将这些属性放在右手边
我的意思是，如果我们打开它，那么你可以看到我们有
我们可以选择的一堆选项来改变它的方式
看起来像那个回收站视图，但我真正想做的是我想要的
单击此处拆分，以便也将显示
xml 基本上用于此布局的 xml 代码，我只是更喜欢
查看并更改此 xml 代码
因为它实际上更清楚它的作用所以我们实际上可以
在这里稍微增加宽度
现在我们一方面看到了我们的布局，另一方面我们看到了 xml
该布局背后的代码，现在您可以看到此布局是
基于约束布局或此屏幕基于约束布局
具有布局宽度和布局高度属性，它们被设置为匹配父级
这只是意味着这个约束布局的宽度
只填满我们屏幕的整个宽度和高度
如果我们从我们的受体视图中设置分层宽度和布局高度
在这个时候匹配父然后这个父
指的是这个约束布局，因为那是
这个回收者视图的父级，我们不仅在这里有匹配父级，我们还有
例如，包装内容将只是
仅根据需要使切除器视图变大，以便您可以看到
现在不是它只填满整个屏幕
它只是基本需要的那么高，实际上这些项目只是为了
预览 所以如果你现在打开我们的应用程序
这个列表不会有这些项目只是
在布局编辑器中显示一些东西
但是这种约束布局实际上对我们有什么帮助
是对齐这些项目并使我们的整个布局响应
所以如果我们在这个回收器视图上点击我们的布局编辑器，那么你可以看到它
有这四个气泡，所以每边一个气泡
我们可以把这些泡泡拖到这里
例如到底部然后你可以看到我们的recyclerview将被拖动
到底部，我们现在在这里设置这样的约束
在我们的 xml 文件中，如果我们采用，也会发生同样的情况
这个气泡现在这个顶部气泡并将其拖到顶部
现在我们的 recyclerview 将集中在我们的布局中，因为
每个气泡都拖到它自己的大小并且同样强大，所以这意味着我们的
recyclerview 将垂直居中，这里的这些线被称为
约束，这就是为什么这个层被称为约束布局
同样重要的是要知道每个视图
我们的布局内部至少需要一个垂直约束，所以要么
这个顶部的气泡或底部的瓶子气泡和
至少有一个水平约束，所以现在我们没有设置这两个
水平约束我们也只想将它们拖到
左侧和右侧也将其居中
水平，但这在这里真的不可见
因为我们的回收站视图填满了整个宽度
我们的布局实际上我们不想要这个接收器
视图居中，因为我们希望列表从顶部开始
所以我们能做的就是我们可以去除这个嗯这个底部的气泡
以便接收器视图不会被拖到底部
我们可以通过按住 control 并点击这个底部来做到这一点
气泡，然后您可以看到我们的回收站视图
移动到顶部，现在仍然可以，因为我们有顶部气泡，所以
我们至少需要一个垂直气泡和一个
水平气泡，但我们也可以有两个
现在我们还想在我们的 kotlin 中使用该回收器视图
代码，为此我们需要以某种方式指定
我们实际上想用哪个视图做一些事情，为此
我们给我们的视图所谓的 ids 所以只是唯一的标识符
然后我们可以在我们的 kotlin 代码中使用
更改这些视图的属性，我们可以通过简单地编写 id 来做到这一点
这里在这个 xml 标签和 android studio 会自动提示这里
我们只需要按回车然后我们要添加一个新的 id
所以我们使用这个 add plus id 斜线再次按下回车，在斜线之后我们
指定我们想要给这个视图的 id 和我的
这里的个人约定是用一种类型的开始这个id
查看所以 recyclerview 我将从这个开始
rv for recyclerview 然后是任何类型的受体视图
在我们的例子中只是为了做项目，所以我们也是为了做项目
当您在棉花代码中使用该 ID 时，您会立即知道
好的，这是一个回收器视图，包含待办事项
好的，我们在布局中还需要哪些其他视图，我们还需要一个字段
输入一些文本 所以如果我们想输入 如果你想输入
一个新的待办事项然后我们需要输入该文本
在某个地方，为此在 android 中我们使用所谓的编辑文本
所以我们在这里打开一个新标签，你可以看到它已经建议我们
在这里添加文本，我们只需按回车键，它就会自动插入那些
宽度和高度的两个属性，因为我们总是需要它们
对于这里的编辑文本，我们现在将设置宽度
包装内容，使其仅根据需要宽
所以只有在文本确实需要的范围内，我们稍后会改变它
但现在我们将保持原样，我们还将设置高度以换行
内容所以它和我们的文本一样高，然后我们可以关闭那个标签
这个然后我们实际上可以进行这个编辑
文本 id 以及因此 id 按 Enter 再次按 Enter
在此处添加一个新 ID，我们将其命名为 et
再次做标题的约定和编辑文本
这是一个添加的文本来编辑做项目标题
和另一个有用的属性，我们可以在此处附加到此编辑文本
是一个提示，所以我们基本上可以显示一个不是真正的文本只是一个文本
显示此编辑文本内容的小嗯文本
是为了但是一旦我们点击它就会
消失所以我确定你知道如果你是一个网络开发者
我们可以在此处正确提示按 Enter 并在此处输入文本
所以输入做标题，你现在可以看到
我们的编辑文本有点宽，因为它需要
我们刚刚输入的这个文本的空间，我们
这里仍然会出错，因为我们还没有为此设置任何约束
编辑文本，正如我所说，我们总是需要那些
让我们这样做，我们希望在左下角有那个，所以我们使用这个
此编辑文本的底部气泡将其向下拖动，然后将其向左拖动
左边的气泡所以我们可以简单地点击
如果它直接与左侧对齐
那么我们还需要两个按钮，一个是用我们输入的标题添加待办事项
在这个编辑文本和一个只是删除所有选中的待办事项
项目让我们在这里做打开一个新标签
右键按回车，我们给这个带包装
内容和高度，我们给它一个 vtn id
在做，我们给这个按钮一个文本，所以它应该显示的文本
添加待办事项，然后我们可以关闭该标签
然后我们必须再次设置该按钮的约束，以便我们单击
在那我们希望下一个按钮
到这里编辑文本就在右边
一方面，我们想要这个
底部约束在父底部我们将其向下拖动
在这里，然后我们实际上不想将其设置为左侧
约束到这个左边，因为最后我们想要这个编辑
文本尽可能宽，因为我们将添加两个
这里的按钮 一个用于添加介绍，一个用于
删除待办事项，这些按钮应该只有一样宽
根据需要，其余的空间应该
实际上用于在此处编辑文本
所以如果我们这样做 如果我们拖动这个按钮
左约束到我们编辑文本的右约束
那么这会将我们添加的文本的大小始终限制为
包装内容，所以我们不想删除这个约束
现在我们就这样离开，因为要真正完成我的工作
谈到我们需要先添加另一个按钮
删除待办事项，以便我们可以简单地复制此按钮标签
在这里并再次粘贴到下面
然后我们可以将第二个按钮的 id 更改为 button
删除完成使用我们给这个文本删除完成做的
你现在可以看到我们有那个额外的按钮
或者让我们实际上给这个文本删除
完成因为否则会有点宽
然后我们将设置这个删除完成按钮的正确约束
到父右侧底部到父底部
已经设置好了，因为我们复制了它，现在我们可以选择我们的
添加待办事项按钮并将其右侧约束到左侧
我们的删除完成按钮，所以现在它坚持
这个删除完成按钮总是你现在可以看到我们在这里有这个小差距
我们想用这个编辑文本填充，事情是如果
我们会选择正确的约束条件，然后
将其拖到此处的按钮上，然后这将使此编辑居中
这个父左和我们的按钮之间的文本，但我们
实际上希望此编辑文本与此处的这些约束一样正确
基本上，为此我们有一个新的财产
这被称为 0dp 所以 dp 代表密度像素
这是您应该在android中选择的宽度和高度单位
因为它指的是当前设备的密度，所以不是每个设备
如果涉及像素，则具有相同的密度
所以两个设备可能有相同的物理宽度
但其中一个设备可能有更多
其中的像素，为此我们使用这些密度像素来制作更多
相对于具有约束布局和具有约束布局的设备，我们有
如果我们设置宽度或高度的特殊行为
查看到零 dp 那么它只会拉伸
整个约束，所以在我们的编辑文本示例中，它只会
像这里的限制一样宽，所以如果我们去
将此编辑文本在 xml 中转到此处的宽度并将其设置为 0dp
你现在可以看到它的宽度和它基本上适合这个差距一样
正是我们在这里想要的，所以这也意味着我们是否会推出
这在具有更大屏幕的设备上
那么这里的这两个按钮只需要多少
需要的空间，仅与按钮中的文本一样多
需要和该行中的其余空间
这种编辑文本字段将使用种类
在这里，我们实际上想要相同的行为
对于我们的 recyclerview 因为现在它被设置为在高度上包裹内容
所以这里只占用尽可能多的空间
但是如果这个受体视图变得非常大
那么这将意味着回收器视图的高度只会是
将永远与我们拥有的物品一样高
所以这基本上会增长到底部，我们将无法滚动
在这个但我们想要滚动行为所以我们
将这个底部约束限制为任何
在这三个顶级约束中的任何一个
编辑文本或两个按钮之一这并不重要然后通常这个
只是在父顶部和其中之一之间将此接收器视图居中
两个是这里的三个视图之一，但我们想要
在这里填充整个高度，以便我们设置 resector 视图的高度
再次到 0 dp 现在这正是我们想要的高度
这实际上就是我们的主要活动布局
我们真的需要在我们的应用程序中使用另一种布局吗？
是的，我们确实需要它，因为我们还需要指定
我们的回收站视图中的每个项目都有这样的布局文件，所以基本上如何
这些项目看起来像，最后我们只想有一个
每个待办事项的文本和一个小复选框，所以我们还需要
定义并为此我们转到此布局文件夹
在此 res 文件夹中右键单击并创建一个新布局
资源文件然后这个窗口将打开，我们
将给这个文件名项目做，我们按回车
然后你可以看到一个新的布局文件将打开，我们也可以
把我们的观点放进去，所以我会再次点击这里的拆分
我们实际上只需要两个视图，一方面是文本视图
所以这只是一个显示的纯文本
我们现在将设置宽度来包装内容
和高度我们也会给这个文本视图一个 id
电视做标题我们会给这个文本
这里的例子是因为我们稍后会更改该文本
这仅适用于后面的图层编辑器，因此我们可以适当地限制它
所以一方面我们将左约束设置为父左
以及父顶部的顶部约束，现在我们实际放在哪里
这个底部约束我们将把它放在我们的父底部
在这里，但我们实际上不想要我们的单身
在我们的回收站视图中，我们列表中的项目与此处的整个屏幕一样高，因此
我们以某种方式需要限制大小，我们可以在这里设置这个高度
将根布局设置为固定数量的 dp 单位，以便
例如 80 dp 然后你现在可以看到这看起来
更像是我们现在想要的清单
每件物品只有 80 dp 高，我们也希望有一个
此处的复选框仅检查该鞋类商品是否为新标签
复选框，我们在布局高度包装中为其提供带有包装内容的布局
内容也是如此，我们给它一个id
cb done 然后我们可以关闭那个标签了
可以把这个复选框限制到这里的右边
从上到下，从下到下
然后我们可以再次使用此文本视图约束右侧
在我们复选框的左侧，现在我们不想让它居中
相反，我们想再次将此处的宽度设置为 0dp
以便它在水平方向上填充这些约束的整个宽度
然后让我们也稍微改变一下这个文本视图的文本大小
所以我们在这里进入这个文本视图并输入文本
大小，我将设置为 24 sp 这次你应该使用 sp
始终将其用于字体大小，因为这也
嗯，除了考虑当前用户的字体偏好
设备的密度，现在我们还想做的是
在这里应用一点间隙或一点空间，这样它就不会直接对齐
这个左侧和复选框以及现在非常类似于 web
开发我们可以只应用一点填充或边距
所以让我们进入这个根布局这里这个约束布局
并指定填充开始以将填充应用于左侧
并将其设置为 adp 例如，您将看到文本视图移动了一点
位到右侧，我们也可以这样做来填充
并且还将其设置为 adp ，这就是我们的布局文件
现在我们可以进入我们的主要活动或实际上我们的 kotlin 文件
并编写逻辑以实际添加执行
项目删除它们以检查它们等等所以我要做的是我会点击
在此处的主要活动 kt 上右键单击并单击关闭其他活动，以便
我们只是在这里稍微澄清一下，我们只打开主要活动
现在为了让这个 recyclerview 工作，我们需要创建一个所谓的 recyclerview
适配器基本上是一个类，我们在其中
定义我们想要用于那些的布局
受体视图项目，所以我们只定义我们想要使用
我们创建的要进行布局的项目我们需要定义我们的列表
实际上希望我们用
数据，我们需要定义我们想要如何用数据填充它的逻辑
所以我们想要查看哪些项目的哪些视图
设置哪些数据但一次一个步骤
首先我们要做的是创建一个类
那只代表一个待办事项，所以我们在这里转到我们的根包
主要活动是我们右键单击创建新棉花的包
跟随课程，我们将称之为只是为了做和
在这里选择课程，这将不是一个普通的课程
相反，它将是一个数据类，kotlin 中的数据类只是一个类
其主要目的是保存数据，所以我们不会
在这个类中编写任何逻辑，而不是它只有一个
构造函数在这里并在一个上包含两个属性
手是那个标题的val
做一个字符串的项目，另一方面
那是一个 val ，它只是确定这个要做的项目是否是
当前检查与否，所以我们指定 val 被检查
这是一个布尔值，所以要么是真要么是假，我们会给出这个
默认值为 false 因为当我们添加新的待办事项时
当然默认情况下不会检查，在这里我们可以使用这个工作室类
现在创建我谈到的这个 recyclerview 适配器
所以这也将是一个 kotlin 类，让我们再次访问这个包
创建一个名为做适配器的新类，我们选择类
在这里，这将基本上是类
这里包含了我们应用的主要逻辑，我们不会在其中加入太多逻辑
主要活动，因为我们的应用程序基本上包括
这个列表和最逻辑的将发生在那里
这个待办事项适配器类现在将采用实际的 kotlin 项目列表
我们想用它来填充这个列表，所以在这个的构造函数中做
适配器类我们将指定一个列表，以便将
私人 val，我想我没有涵盖这个私人
在我的 kotlin 速成课程中，这只是意味着
我们在这里声明的这个变量不能被访问
其他类只能在此内部访问以进行改编类
如此私人的val to do's so that will be the list of to do items
对于我们的列表，这将是一个可变列表
类的可变类型列表
我们在这里创建的，所以我们只需将一堆待办事项传递给这个
做适配器，在这个类中，我们定义了我们想要的逻辑
在我们的内部设置我们单个视图的数据
在此待办事项列表的帮助下的单个项目
下一步将是创建一个所谓的视图持有者一个视图持有者
好吧，它持有视图，它基本上将持有布局
一个特定的项目和这个视图持有者这个接收器视图只是
完成我们想要的行为，所以这个
仅显示必要项目的回收行为
这也是一个 viewholder 的类，但这只是一个单行类，并且
很简单，我们可以把这个类实际放在里面
这是做适配器类，我们只是指定要做的类
这里有一个viewholder，它将引用它应该持有的视图
所以最后如果我们看看我们的项目来做 xml
这就是最终这个约束布局，以便将
包含特定项目内的所有这些视图，我们
使用 android 中的 view 类型的 item view 来引用它，所以我们
需要导入，所以如果你正在查看你只需要按回车
你可以看到它会在这里自动添加这个导入语句，并将这个添加到
做 viewholder 类将从 recyclerview 继承
也按回车在这里导入那个点持有者和这个在这里和
现在我们需要指定那个viewholder的构造函数，这样你就可以看到
需要这个我们实际通过的项目视图，所以我们只通过项目视图
在这里，这已经是这个视图
搬运工那真的不复杂，现在借助这个来做
viewholder 我们现在需要定义这个类实际上指定或
实际上定义了我谈到的这样一个 recyclerview 适配器
about 并且我们通过让这个类继承来做到这一点
从 recyclerview 点适配器，你可以看到我们选择
此处带有此通用参数的适配器
所以我们可以为该适配器选择一种类型，在这里
这需要这个适配器需要的视图持有者
所以只是我们在这里创建的这个视图持有者
做 viewholder 并在此处添加两个括号
现在你可以看到我们在这里得到了一个小错误，因为
我们从这个 resectorview 适配器继承
它基本上要求我们实现一些默认功能
每个 recyclerview 适配器都需要，在这个函数中我们只是
定义我们希望如何用数据填充这个 recyclerview
我们想要选择哪种布局等等，所以我们只需点击进入
这里的空行基本上我们按 ctrl
然后我会打开这个窗口，这是我们要使用的三个功能
需要在这里实现以使其成为一个完整的 recyclerview 适配器
所以我们可以按 ctrl 和 a 来选择所有这些
然后按确定，android studio 将在此处插入所有这些
所以这现在看起来非常复杂，特别是如果你是编程新手
但别担心，我们会整理每一个
这里的三个函数我们首先会移除那些待办事项
因为我们不需要那些，而是我们会
从这个 oncreate viewholder 函数开始，作为名称
说这个函数将创建viewholder this来做viewholder
所以在这里我们只需要定义列表中特定项目的样子
你可以看到这个函数返回这样一个待办事项视图持有者的实例
所以我们也需要这样做，我们在这里写 return
做 viewholder 现在你可以看到我们需要传递一个项目
视图作为参数，因此我们的特定项目的视图
回收者视图并实际获得对此的引用
查看我们可以使用所谓的布局充气器
在 android 中使用的只是对特定视图的引用，我们只
关闭这个 xml 文件，所以这里当然没有 kotlin 代码
但是这个布局充气器只会接受这个 xml 代码并解析它或者
将其转换为 kotlin 类，我们可以在此处的代码中使用
所以我们可以使用 layout inflator 来做到这一点，也导入确保它添加了这个
此处用于布局充气器的导入语句
dot from and here 这需要现在有点太多的上下文
如果我深入了解上下文和 android，那基本上是
只是您能想到的我们应用程序的状态，我们可以通过
写父点上下文所以
parent 只是一个视图组，您可以看到视图组始终是一个布局
android 所以有了这个视图，我们可以得到一个
参考这个上下文，仅此而已
然后我们之后调用 dot inflate 所以这个 inflate 函数实际上会
膨胀我们的布局，它实际上会转换这个 xml 布局
到我们可以在代码中使用的真实视图，这里需要三个参数
一方面，它将获取资源 ID，因此这是我们的 ID
特定的布局文件每个 xml 文件都有一个内部
id，我们可以很容易地引用它
使用 r 表示资源也在这里按 Enter
从 example.to do list 导入它并在之后写一个点，你可以看到
我们有很多类型的资源，我们想要这里的布局资源和
然后我们简单地指定这个项目要做，因为那是
我们列表中每个项目的布局，我们想要
使用该布局充气器对其进行充气，然后作为第二个参数
所以写一个逗号我们需要传递我们想要附加的视图组
这只是我们已经拥有的父项
我们还需要指定我们不想附加这个
查看根布局，因为那不是重点
回收商的观点，我们会将其附加到
实际的根布局，因此您实际上永远不需要它用于回收站视图
所以我们明确地想把它设置为 false，这已经是这样了
oncreateviewholder 函数在这里，所以让我们来看看这个
getitemcount 函数在这里，我会腾出一点空间，以便您可以阅读
更好，因为这实际上是最简单的
我们需要在这里实现的函数它只返回我们的项目数量
在我们的列表中，在这里我们可以返回
我们的待办事项列表点大小，因为这正是
我们在该列表中的项目和我们的 recyclerview 适配器只需要
拥有该信息，以便它知道应该有多少项目
实际显示，现在这个 onbindviewholder 功能
缺少这实际上是什么，它将绑定来自我们的数据
待办事项列表到我们列表的视图中，所以它只会
嗯，这只会在新的视图持有者可见时调用，所以新的
我们列表中的列表项是可见的，在这个函数中我们定义
这个xml的待办事项的哪些视图
项目在这里所以我们只定义我们实际想要设置到这个文本视图的文本
如果我们想选中这个复选框，那么我们基本上只使用我们的列表
并将该列表的数据设置为我们的视图
你可以看到我们得到了对当前视图持有者的引用，我们使用它
可以访问它的视图，以便在我们的复选框中访问我们的文本视图
我们得到了当前视图持有者位置的引用，所以
有了这个位置，我们实际上也可以得到一个参考
到我们可变列表中对应的 to do 项，因此 val current to do
等于我们从外面传递过来的待办事项清单
在这里作为索引，我们将只选择位置，以便这是当前要做的
我们现在正在谈论的项目
如您所见，我们也可以访问该项目
检查状态和标题，现在我们要使用这两个
属性将它们设置为我们的文本视图和我们的
复选框 所以让我们按照我说的去做
我们将使用视图持有者所以我们的持有者点项目视图
因为项目视图包含这些视图
你现在可以看到我们可以例如写
tv to do 标题，这正是我们待办事项的文本视图
item 但因为我们需要多次参考它
在 kotlin 中有一个很酷的捷径，那就是写
应用你不需要这样做，但这只是防止我们总是需要
在引用之前预先添加该项目视图的持有者
这些视图，现在我们可以直接引用这些视图
在这个块里面基本上是电视做标题
我们已经完成了 cb 并且我们并不总是需要写 holder
dot item view dot cb done 例如，所以我们可以直接写 cb done 代替
所以首先你想要做的是我们想要设置
我们的标题或我们的文本视图的文本
到这个当前要做的项目的标题和
我们将通过写电视来做标题来做到这一点
确保导入它，所以如果你还没有这样做
如果我们在这里按 ctrl 空格，那么它会显示出来，我们需要按
在这里输入所以不要只写电视来做标题
然后它不会输入它而是显示它
如果你有，如果你有，那么你可以简单地在这里
把光标放在这个词后面按alt+
输入，你可以看到然后你可以点击导入
但否则 android studio 将无法识别这一点
基本上在这里做文本视图，如果你已经导入了
我们可以在之后编写点文本以将文本设置为新的内容，因此我们
设置它等于我们当前要做的点
title 所以我们现在将我们帐户的标题设置为 do item
到我们的文本视图的文本，我们将对选中的状态做同样的事情
我们的复选框所以 cvdone 点
被检查等于当前你做的点被检查所以如果我们现在有
要做我们列表中已经被检查过的项目，那么我们只需
在我们的回收者视图中更新特定的待办事项
然后这个复选框已经被选中
现在我也想实现这种行为
如果我们检查文本基本上被删除的项目
为此，我将创建一个附加功能
只是为了让我们在这里基本上切换这个状态
所以如果我们已经有一个文本
删除然后我们将删除那个删除
反之亦然 如果我们还没有突破
然后我们将添加这将是一个私有功能切换罢工
通过，这将只是一个参考
作为我们想要删除的文本视图的参数
所以电视做标题我们可以再次称之为文本视图类型
我们还需要该复选框的已选中状态
所以这实际上是一个布尔值，然后在这个函数内部我们可以
检查是否现在实际上已检查，因此如果要执行的项目是
实际上检查了我们是否要添加这个
在这里删除到这个文本视图，我们可以做
通过编写 tv 来做通道点绘制标志，这样我们就可以指定
我们想应用到这个文本视图的一些标志
你不必明白
详细说明这个标志的东西是如何工作的，因为现在这是一种二元运算
是的，我们基本上只是在这些钢笔标志上附加了一个特定的标志，所以
以前存在的所有标志都将保留，我们
再添加一个标志，以便将其设置为 tv 来做标题
点疼痛标志，所以我们以前有的 flex 或
所以这是这个二进制文件，或者我们想添加这个删除
标志所以一定要用大写字母写这个
我认为它实际上被称为删除线
text flag yes 一旦这里出现这个下划线，我们
只需按 alt 加 Enter 即可导入
一直在这里，然后我们就可以开始了，我们还需要做
对于我们的待办事项未选中的情况类似的事情
所以在 else 的情况下，我们想再次使用
tv to do title dot paint flex 我们将其设置为
tv 做 title.painflex 所以已经存在的窗格 flex
现在要恢复我们在这里的标志
我们将使用，所以现在这是一个二进制文件，
删除文本标志点倒置，因此此点在功能中
我们基本上可以从我们的窗格标志中删除这个标志，我知道这是一个
如果您不明白如何，请不要担心这里有点混乱
这很详细，我也知道这在 css 中要容易得多
但遗憾的是，这正是我们必须在 android 中做到的
但现在我们有了这个功能切换删除线
总是能够切换这个，我们将在我们的
onbindviewholder 函数，因为现在我们要调用它
最初是因为如果我们的待办事项被检查
最初我们当然都已经想附上这个
划线到我们的文本视图，所以我们通过我们的电视做标题
作为第一个参数，我们通过 current 来做 dot 被检查为第二个
参数，我们现在要调用这个函数
当我们再次单击此复选框时
我们基本上检查一个项目然后我们也
想调用这个函数，因为那时我们想实际切换这个
划线，我们可以通过写 cb done so 来做到这一点
我们的复选框点设置在选中的更改侦听器上，因此如果我们使用
这个和实际上这个版本的卷曲
括号在这里如果我们在这里按回车那么这是一个
kotlin 中的 lambda 函数，因此将调用此处的这段代码
当我们复选框的选中状态发生变化时
你可以看到我们得到了对这个按钮视图的引用，所以引用了这个
当前复选框，我们实际上可以用一个替换它
下划线这只是意味着在 kotlin 中我们不需要这个参数
在这个函数中，但我们需要在这里检查它，因为那是新的
选中状态，所以如果我们点击复选框，现在
复选框被选中，那么这将是真的，如果它是
已经检查过了，我们点击了它，然后就是现在
false 所以这个变量将是 false 所以我们可以在这个块内做什么
我们可以再次使用我们的切换删除线功能吗
通过我们的电视做标题文本视图，我们通过这个
这次是检查布尔值所以这次检查不是当前要做的
相反，我们使用这个新的检查状态并将其传递到这里
我们也想应用这是检查状态这是新的
这个新的在此处检查状态到我们当前的待办事项以将其更新为
那么目前做的是检查是平等的
to current to do 被选中，但这次
倒置，所以这只是意味着
如果这是假的，现在是真的，如果这是真的
它现在是假的，你可以看到我们在这里得到一个错误，那就是
因为我不小心把它变成了元音所以我们不能重新分配这个值
我们实际上希望这是一个 var 所以我们
只需将鼠标悬停在其上并单击更改为 var
这样只会更改值以便上课
到这里 var 就是这个 onbindviewer 函数
这三个中最复杂的功能在这里
如果你不明白我会经历我们在这方面所做的一切
教程最后所以当我们完成我们的应用程序时我
将再次解释它，就像一个小回顾
但现在我们需要添加另外两个小函数
不那么复杂别担心，一方面这将是一个函数
将待办事项添加到我们的待办事项列表中，以便当我们
实际上点击这个添加做项目按钮，我们想要一个
只是从这个列表中删除所有检查要做的项目的函数
我们将在这里定义这些函数
recyclerview 适配器让我们在这里做一个函数
添加待办事项并作为参数，我们只传递新的待办事项项
我们想通过这里，正如我所说，这个功能将非常
很简单，我们只需使用我们的待办事项列表并添加此项目即可完成此项目
哎呀不是这个只是这个在这里和之后做项目
因为我们在这个列表中插入了一些东西，这不会自动
更新我们的 recyclerview 以便将其添加到此列表中，但不会
它不会在我们的屏幕上可见，基本上它不会作为新的
我们屏幕上的项目，因为我们需要通知我们
适配器在这里我们插入了一个项目，我们可以做
这与插入的通知项目，我们需要
嗯在这里插入位置作为参数
我们插入该项目的位置，此添加命令将仅插入该项目
在列表的末尾，所以我们只传递了列表的最后一个索引
这是使用点大小 -1 并且这已经是这个添加要做的
函数我们还想定义一个函数
delete done to do's so function delete done to do's this will not take any
参数，因为我们已经拥有了所有这些
关于这些完成的信息在这个适配器里面，我们可以
使用我们的待办事项列表点删除
全部并再次使用这个 lambda 函数，所以这些大括号
我们可以在这里给出这个项目和名称，以便这样做
所以这基本上会做的是它只会
浏览我们的待办事项列表，并为我们提供每个待办事项的实例
在这个列表中，我们现在可以定义逻辑，如果我们想删除该项目或
如果你想保留它以便我们只需要定义一个布尔值
在这里，如果我们想删除这个项目，那么布尔值就是这样
待办事项被选中，所以如果选中了我们想要的
删除它，其余的将保留在列表中，之后我们
再次需要通知此适配器我们更改了列表中的某些内容
因为现在我们没有删除项目的所有索引，我们可以
只需调用将更新的通知数据集更改
我们的整个列表，现在我们几乎完成了我们的应用程序
我们实际需要放入这个主要活动的其余代码
只是定义一些行为，如果我们点击我们的
我们必须将此适配器连接到的按钮
我们实际的回收者视图，但主要逻辑实际上是
包含在此 recyclerview 适配器中
所以让我们切换到 mainactivity.kt 我们首先要在这里做
想要将这样的 to do 适配器附加到我们的实际回收站视图中，我们可以
用 rv 引用 recyclerview 来做项目，所以我们选择那个 make
确保再次在此处按 Enter 以自动导入
然后我们可以写点适配器等于
一个我还没有创建的 to do 适配器，所以我们会得到一个错误
但让我们在这里作为一个全局变量来做
我们将其定义为私有的后期初始化变量
所以如果你不知道什么是潜在的，我没有在我的 kotlin 崩溃中提到它
当然，这基本上只是一个承诺
kotlin 我们稍后会初始化它，所以我们不需要
全局初始化它并说我们稍后会这样做
这将被调用来做适配器，它是做适配器的类型，所以只是
就像那样，你可以看到我们不需要在这里初始化
并将其设置为某种待办事项适配器，因为我们会这样做
在这个 oncreate 函数的内部，这里我们可以设置做适配器
等于一个新的 to-do 适配器，你可以看到这现在把它带到
我们想要在我们的实际回收者视图中显示的列表
我们将在这里传递一个空列表，因为我们想要我们的
回收者视图默认为空，我们要添加这些项目
当我们点击添加做项目时动态地但当然你也可以
定义一个预定义的待办事项列表
在这里并已经添加这些然后当我们的时候这些将被包含
应用程序启动，但我不会在这里这样做，我只会
传递不可变列表并保留它
空，这样只会传递一个空列表
到我们的待办事项适配器，是的，如您所见，我们已经设置了
并在此处将该适配器分配给我们的回收站视图
我们需要分配给它的另一件事是所谓的布局管理器
这只是定义项目如何在我们的列表中排列的东西
我们将只使用所谓的线性布局管理器，它只会
像真正的列表一样显示它，所以一个项目下一个项目
下一个项目，但还有一个网格布局管理器，可以安排
这些项目在一个网格中，是的，你可以
试验一下，我将只使用一个普通的
线性布局管理器，因为这对这里的待办事项列表应用程序最有意义
所以 rv 做项目点布局管理器等于线性布局管理器和
这再次需要我谈到的这样一个背景
如果我们在一个活动中，我们可以只传递这个上下文的活动
所以就这样，然后就可以正常工作了
现在我们需要做的最后一步是我们需要分配所谓的
单击我们两个按钮的监听器，所以我们只需要定义应该做什么
如果我们点击这些按钮就会发生让我们从我们的按钮开始
在点击监听器和这个 lambda 函数上添加点集，这样我们就可以
在这段代码中很好地定义我们的逻辑
我们首先要获取我们写入编辑文本的当前文本
然后我们只想从该文本中创建一个待办事项并添加它
到我们的适配器到我们的列表所以 val 做标题
等于 et 做标题我们的编辑文本字段点文本，你可以
看到文本默认是可编辑的
另一个字符串，因为我们需要转换它
通过写入 tostring 到一个字符串，然后让我们在这里实际添加一个检查
检查这是否不是空的，因为我们不想
将空项目添加到我们的列表中，因此如果要执行的标题不是
空然后我们想将它添加到我们的列表中，因此我们创建了一个新的待办事项
我们在这里创建的类是因为我们的列表和我们的待办事项适配器
由这些待办事项组成，所以 val to do 等于 new 待办事项，这里
我们将此分配给标题作为标题，我们不需要
将此设置为已检查状态，因为它是错误的
默认然后我们可以简单地使用我们的
做适配器并调用我们的添加做功能并将其传递给项目
我们在这里创建，这只会将它添加到我们的列表中
我们实际上也可以通过以下方式清除编辑文本的内容
写作et to do title dot text dot
清除这样就可以清除我们的文本，我们可以输入一个新的待办事项
那里和我们的按钮删除完成要做的是
所以如果我们只想删除所有已完成的事情
我们还将这个点击监听器设置为那个来定义逻辑，如果我们
点击这个按钮然后我们只想用我们的来做
适配器不是这个做的声明做适配器
相反，只需调用 delete done 即可，因为我们
已经在我们的 to-do 适配器中定义了逻辑，所以我们不需要
单击此处执行其他步骤
听众，这就是我们现在需要做的一切
我们的应用程序工作，正如我所说，我只想通过
在我们实际尝试之前和我之前
向您展示如何设置模拟器来运行它
所以首先我们在我们的活动主 xml 文件中所做的我们只是
定义了我们活动的布局，因此应该显示在屏幕上
首先，我们有这个rec​​yclerview
只是一个用于显示列表的视图
android 中的项目和 android 中的每个列表项或我们的
应用程序实际上是由这个项目做的 xml 所以每个
项目将由一个文本视图组成，该视图显示待办事项的标题
语句，它会显示一个复选框，如果特定于
做是否被检查，为了使这个受体视图工作，我们
需要为每个要做的项目创建这个数据类来填充
嗯，列出我们的实际视图和数据，我们通过了这些列表来做
项目到这个做我们创建的适配器类
这里然后这个工作室适配器类包含
这是做 viewholder 的，它只是一个被包装的类
围绕这里的特定视图，以便该视图只是
这里的约束布局根布局
我们的项目要做 xml，这只是允许这个 recyclerview 有这个回收
如果我们滚动它只会显示的行为
这些项目，只加载这些当前可见的项目，即
只是非常高效，然后在这个 oncreateviewholder
函数，我们用我们的布局返回这样一个视图
我们给它充气，这样布局充气器就会得到一个
参考我们在此项目中定义的视图来做
所以它只会在此处获取此 xml 文件并进行转换
查看我们可以在 kotlin 中工作，然后我们有这个获取项目数
在这个函数中，我们只需要返回
我们列表的大小，以便回收者视图知道有多少
它应该显示的项目然后我们有了这个 onbindviewholder
我们在其中分配或设置数据的功能
我们的待办事项列表到我们的文本视图中
框，为此我们只使用了这个辅助函数这个切换
删除线功能只是添加了这个删除线标志
如果我们的如果我们的复选框被选中，如果它没有被选中
然后我们将再次删除它，然后我们
也有这两个辅助函数来向这个列表添加一个新的待办事项
并删除已完成的工作，然后我们只需
需要通知此适配器我们更改了列表中的某些内容
所以它也会改变我们的应用程序uri中的一些东西
最后在我们的主要活动中，这个 oncreate 函数就是
当我们在这里启动我们的应用程序时调用我们分配一个新的做适配器
这个做适配器我们分配这个适配器
我们将这个布局管理器分配给这个回收器视图
recycler view 所以只是为了定义这些物品的排列方式
在我们的列表中，这只会使它成为一个普通列表
我们添加了如果我们应该发生的行为
点击这个添加待办事项按钮，如果我们点击会发生什么
完成的这个删除是按钮，这是回顾一下让我们实际上
设置我们的虚拟设备我们的模拟器来运行它
应用程序，看看你的右上角是否一切正常
有这个虚拟设备助手，所以这个安卓小人在这里
我们点击那个设备，然后点击这个窗口
会打开，嗯，我这里已经有三个模拟器了
这些不会显示给你，但如果你想添加一个新的
您只需单击创建虚拟设备
然后另一个窗口将打开我将只使用这个像素
3a 设备在这里所以选择你可以选择任何
其他你喜欢点击下一步，在这里你可以选择一个android
这个设备应该运行的版本我不会选择android r
最新版本，因为它仍然更好，并且
模拟器还是有点问题，所以
确保选择android q，你可能会
需要下载它，这样你就可以看到我没有安装oreo和nuget
您需要单击下载并下载此特定版本的
android 但在我的电脑上这已经是
安装，所以我只需点击下一步和之后
你的下载完成了你可以选择这个然后点击下一步就可以了
给它一个名字，你可以给它一些设置，但是
我实际上只会保留您也可以显示的默认设置
这里的高级设置你可以定义你想要多少内存
给它你想要多少内部存储空间
给它，但我将保留它的默认设置，然后它
将正常工作，之后您只需单击
到此结束我不会那样做，因为我已经有了这样的模拟器
模拟器设置但之后它应该出现在你的
如果您添加了虚拟设备，请在此处列出
在这里，你也可以在这里关闭那个窗口
然后在 android studio 的顶部，你可以看到
在这里我们有一个下拉菜单，我们可以在其中选择要运行的虚拟设备
这个应用程序确保在这里选择你的模拟器我
将使用我的 pixel 3a api 29 模拟器
我建议我建议您创建然后只需单击此播放
符号，这将启动您的模拟器和
应用程序，所以我会真正打开我的
模拟器在这里你可以看到它只是一个普通的安卓设备，你可以在这里使用
是的，现在 gradle 正在构建
通常需要一点时间，因为它只需要全部
我们的资源在这里并将它们放在一起成为一个可执行文件
应用程序，如果您只对应用程序进行小的更改，那么这将
不像现在花那么多时间，但因为我们还没有启动我们的应用程序
但这只是需要一点时间，所以
现在它实际上已经完成，它将在这里安装我们的应用程序
在我们的设备上然后启动它，这样你就可以在这里看到我们是我们的待办事项
列出应用程序和我们的布局，以便一切正常
预计我们可以进入这里做标题带出
我们点击添加的垃圾桶然后该项目将被添加到我们的
列出我们可以和另一个人一起喂猫，我们甚至可以
在这里放一个小表情符号喂猫然后点击添加然后另一个
do 将被添加，让我们与比尔盖茨再开一次会
点击添加做，如果我们检查你可以看到的那些，我们现在就去
如果我们取消选中它再次删除的删除线，则删除线有效
假设我们检查这两个并单击
删除完成然后它将删除那些并更新我们的
相应地列出所以该应用程序仍然存在一些问题，例如，如果我
将在此处旋转设备并单击此旋转按钮然后
你可以看到它旋转但列表基本上被清除了
原因是android中的活动是在
屏幕旋转，因此它将再次启动 oncreate 和
只需用一个初始化这个rec​​yclerview
我无法处理的空列表
在这个速成课程中，因为我需要
更深入地了解 android 但如果你对更多感兴趣
先进的android开发以及如何处理
诸如此类的东西 如何实现数据库 如何与
android与apis一起工作如何做媒体的东西
然后真的看看我的频道我有很多关于android的东西
我相信你会发现一些对你来说真的很有趣的东西
所以在这种情况下，只需点击此视频说明中的第一个链接
除此之外，如果你对这个项目有任何问题，你也可以
在此视频的说明中找到指向我的 github 存储库的链接
所以如果您有任何错误，您可以将我的版本与您的版本进行比较
这有助于解决这些问题，因此感谢您关注此问题
很长，也感谢布拉德给我
这个平台只是教我最喜欢的开发主题android
我真的很想在我的频道上看到你们中的一些人
祝你有美好的一天，希望我能再见到你
另一个视频