StudyTonight-移动开发中文教程-一-
StudyTonight 移动开发中文教程(一)
原文:StudyTonight
Android
介绍和设置
安卓编程入门
原文:https://www.studytonight.com/android/introduction-to-android
欢迎光临!你们正在阅读这篇文章,这意味着你们渴望学习如何自己编写一个安卓应用。在当今世界,移动应用市场正在爆炸式增长,特别是安卓在很短的时间内就崛起了,与 iOS、黑莓、视窗等其他竞争对手相比占据了领先地位。
每种技术(操作系统)都有自己的用户群,但安卓已经能够覆盖世界上最大的用户群。在第一个教程中,我们将看到什么是安卓,它的版本以及自 2005 年以来有哪些功能帮助它达到现在的水平?最后,我们还将尝试了解安卓架构。
安卓是什么?
安卓是一个修改后的基于 Linux 的移动操作系统,最初由同名的安卓公司启动。2005 年,谷歌收购安卓,接手开发工作,进军移动领域。
作为世界上最大的科技巨头的一部分,安卓是开源和免费的;因此,安卓的大部分源代码都是在开源 Apache 许可证下发布的。这使得任何人都可以下载源代码并根据自己的要求进行更改,因此他们可以拥有自己的安卓操作系统,例如: Cynogen 、 MIUI (小米)等只是安卓操作系统的不同风格。
在开发过程中,开发人员只需在软件层面进行编码,添加新功能,修改用户体验等,将不同设备配置的担忧和软硬件集成抛在脑后,这使得面向移动的安卓应用开发更加容易。
安卓版本
自发布以来,安卓经历了多次更新。以下是其不同版本及其代码名称的列表:
| 版本 | 出厂日期 | 代号 | 空气污染指数 |
| One | 2008 年 9 月 23 日 | 不适用的 | one |
| One point one | 2009 年 2 月 9 日 | 不适用的 | Two |
| One point five | 2009 年 4 月 30 日 | 纸杯蛋糕 | three |
| one point six | 2009 年 9 月 15 日 | 甜甜圈 | four |
| 2.0/2.1 | 2009 年 10 月 26 日 | 闪了闪了闪了闪了闪了闪了闪了闪了闪了闪了闪了闪了闪了闪了闪了闪了闪了闪了闪了闪了闪了闪了闪了闪 | 5-7 |
| Two point two | 2010 年 5 月 20 日 | 弗罗约 | eight |
| Two point three | 2010 年 12 月 6 日 | 姜饼 | 9-10 |
| 3.0/3.1/3.2 | 2011 年 2 月 22 日 | 蜂窝 | 11-13 |
| Four | 2011 年 10 月 18 日 | 冰淇淋三明治 | 14-15 |
| 4.1/4.2/4.3 | 2012 年 7 月 9 日 | 果冻豆 | 16-18 |
| Four point four | 2013 年 10 月 31 日 | KitKat | 19-20 |
| 5.0/5.1 | 2014 年 11 月 12 日 | 棒棒糖 | 21-22 |
| Six | 2015 年 10 月 5 日 | 棉花糖 | Twenty-three |
| Seven | 2016 年底 | 牛轧糖 | Twenty-four |
| Eight | 2017 年 8 月 21 日 | 奥利欧 | Twenty-six |
安卓的特点
作为一款开源免费的软件,厂商和开发者都是根据自己的需求来做定制的,所以安卓不需要特定的软硬件配置。安卓本身提供了如下一些功能,
- 存储:使用 SQLite 这种轻量级的关系数据库存储进行数据存储(考虑到移动内存存储有限的情况下确实很有帮助)。
- 媒体支持:包括对图像、音频以及视频的大量媒体格式的支持,如:H.263、H.264、MPEG-4 SP、AMR、AMR WB、AAC、MP3、MIDI、WAV、JPEG、PNG、GIF & BMP。
- 短信:支持短信和彩信。
- 网页浏览器:基于开源的 WebKit,现在被称为 Chrome。
- 连接性:支持大组网络,如:GSM/EDGE、IDEN、CDMA、EV-DO、UMTS、蓝牙、WiFi、LTE、WiMAX。
- 硬件支持:加速度传感器、摄像头、数字罗盘、接近传感器&全球定位系统等等。
- 多点触控:支持多点触控屏幕。
- 多任务:支持应用多任务。
- 支持闪存:支持闪存。
- 共享:支持作为有线或无线热点共享互联网。
安卓架构——安卓的软件栈
原文:https://www.studytonight.com/android/android-architecture
在之前的教程中,你学习了什么是 Android,Android 的不同版本以及它支持哪些功能。既然你已经对安卓有了基本的了解和认识,在本教程中,我们将学习安卓软件堆栈(见下图),这将有助于你理解安卓在设备内部是如何工作的。
安卓操作系统遵循分层架构方法。所有这些层负责我们在下面讨论的不同角色和功能。
Linux 内核
这一层是安卓平台的基础。
- 包含各种硬件组件支持的所有低级驱动程序。
- 安卓运行时依赖于 Linux 内核来提供核心系统服务,
- 内存、进程管理、线程等。
- 网络堆栈
- 驾驶员模型
- 安全等等。
硬件抽象层
- 在硬件和软件栈的其余部分之间提供抽象。
安卓运行时
- 旨在在电池、处理和内存等方面肌肉力量有限的受限环境中运行应用。
- 自安卓 5.0 以来,每个应用都在自己的 ART 虚拟机实例中运行自己的进程,这使得进程管理变得更加关键。
- ART 使用
DEX
文件,这是一种字节码,专门为 Android 设计,有助于 ART 更高效地管理内存。 - 包含一组核心库,使开发人员能够使用 Java 编程编写安卓应用。
- 在安卓 5.0 之前,Dalvik 被用作安卓运行时。
- ART 既能提前 (AOT)又能及时 (JIT)编译。
- 它还具有非常高效的垃圾收集功能。
图书馆
- 通过安卓应用框架向开发者公开。
- 包含安卓系统组件使用的 C / C++ 库。
- 少数特征包括,
- SQLite 库用于数据存储,在移动内存占用和任务执行方面很轻。
- 网络工具包库主要提供网络浏览引擎和更多相关功能。
- surface manager 库负责在屏幕上渲染窗口和绘制各种应用的表面。
- 媒体框架库为音频和视频提供媒体编解码器。
- OpenGl(开放图形库)和 SGL(可缩放图形库)分别是用于 3D 和 2D 渲染的图形库。
- 自由类型库用于呈现字体。
应用框架
- 它是用 Java 编写的 API 的集合,让开发人员可以访问 Android OS 的完整功能集。
- 开发人员可以完全访问核心应用使用的相同框架 API,这样他们就可以增强应用的功能。
- 支持并简化核心组件和服务的重用,例如:
- 活动管理器:管理应用的生命周期&提供常用的导航回栈。
- 窗口管理器:管理窗口和绘制曲面,是曲面管理器库的抽象。
- 内容提供商:使应用能够从其他应用访问数据或共享自己的数据,即它提供了在应用之间交换数据的机制。
- 查看系统:包含用于构建应用 UI 的用户界面构建块,包括列表、网格、文本、框、按钮等。并且还执行 UI 元素的事件管理(在后面的教程中解释)。
- 包管理器:管理与设备上当前安装的应用包相关的各种信息。
- 电话管理器:使 app 能够使用设备的电话功能。
- 资源管理器:提供对非代码资源(本地化字符串、位图、图形和布局)的访问。
- 位置管理器:处理位置感知能力。
- 通知管理器:让应用在状态栏显示自定义提醒。
应用
- 安卓应用堆栈的顶端是系统应用和用户可以从安卓官方游戏商店(也称为谷歌 Play 商店)下载的成吨的其他应用。
- 一组核心应用预装在手机中,如电子邮件客户端、短信程序、日历、地图、浏览器、联系人等。
- 该层使用其下的所有层来保证这些移动应用的正常运行。
因此,正如我们可以看到和理解的那样,安卓将分层或者我们可以说分组功能作为软件堆栈,使安卓在任何设备上都可以非常流畅地工作。
市面上的安卓设备
运行安卓操作系统的设备有各种形状和大小。运行安卓操作系统和应用的各种设备如下:
- 智能手机
- 智能手表
- 药片
- 电子阅读器设备
- 上网本
- MP4 播放器
- 网络电视等等。
安卓市场
2008 年 8 月,在收购安卓大约一年后,谷歌宣布了安卓应用市场——安卓设备的在线应用商店。这家在线商店后来被命名为 Play Store ,并于 2008 年 10 月向用户开放,允许用户直接将任何第三方应用下载到他们的设备中。付费和免费应用都可以在游戏商店上获得。
设置安卓开发环境
原文:https://www.studytonight.com/android/setup-android-dev-env
最后,摊牌时间到了。是时候开发你自己的安卓应用了。等等,你要在哪里输入代码?你需要一些环境来开发你的应用。因此,首先您需要下载必要的工具、SDK 和安装文件来设置开发环境。你可以使用苹果操作系统、视窗或 Linux 平台进行安卓应用开发。所有必需的包、工具和其他必需的文件都可以从互联网上下载。以下是这些文件的名称,以及它们的描述,这些描述是开发安卓应用所必需的。
Java 开发工具包(JDK)
安卓 SDK 在 Java SE 开发工具包(JDK)上运行。因此,首先您的系统必须安装 JDK。如果系统上没有,可以从这里下载。
注意:请确保根据您的系统配置下载适当的 JDK,因为对于 macOS、Windows 和 Linux 平台有单独的设置文件。
因此,设置环境的第一个要求是 JDK 必须安装在您的系统上。一旦你完成了这些,你就可以进行下一步了。
注意:一旦安装了 JDK,还需要设置 PATH 和 JAVA_HOME 变量。通常,这是由系统自动完成的。如果你在这方面遇到任何问题,你可以在这里阅读更多关于它的信息。
安卓 SDK/AndroidStudio/Eclipse
接下来是 Android SDK。它包含库、调试器、仿真器、文档、示例代码和针对安卓发布版本的每个应用编程接口级别的教程。
注:在 Android Studio 发布之前,SDK 是 Android Application 开发工具的独立部分,可以借助 Android ADT Bundle 与 Eclipse 等其他 IDE 集成。后来,谷歌将安卓 SDK 作为 AndroidStudio 的一部分,这是安卓开发的官方 IDE。
可以从这里的链接下载完整的安卓开发环境捆绑包(安卓 Studio + SDK)。
AndroidStudio 的设置和安装
一旦你完成了安装 JDK 和下载 AndroidStudioIDE 安装文件,双击。AndroidStudio 的. exe 文件(设置文件)。它将为安装准备文件,并询问您要安装的位置,如下图所示。
选择一个合适的位置,然后单击“下一步”按钮。
点击安装按钮。它将开始安装,如下所示。
点击下一步按钮。
AndroidStudio 已经直接安装,可以使用了。点击完成按钮,AndroidStudio 将打开。
注意:如果你已经安装了 AndroidStudio 的任何早期版本,AndroidStudio 安装程序将首先删除你的早期版本,然后安装新版本,如下图所示。在此过程中,不会删除设置和配置。
如果 AndroidStudio 和自己在同一个位置,它会自动获取安卓 SDK 的位置。但是如果它没有发现,那么它会要求你浏览到安卓 SDK 的位置。
在下一个教程中,我们将讨论 Android SDK 管理器以及 SDK 管理器中完成系统设置以进行开发所需的附加包。
安卓 SDK 管理器——下载所需工具和软件包
原文:https://www.studytonight.com/android/adding-tools-packages-android-studio
在之前的教程中,我们谈到了安卓应用开发所需的工具,并列出了在我们的计算机上配置这些工具的步骤。现在,在本教程中,我们将阐明安卓 SDK 管理器,这对安卓应用开发有多重要,以及开始安卓应用开发需要下载哪些包。
安卓 SDK 管理器,管理各种安卓 SDK 版本,工具和各种其他有用的包,您可以选择和下载,以保持您的开发环境最新。
一般当你第一次启动AndroidStudio时,它会打开安卓 SDK 管理器窗口,提示你安装安卓开发所需的软件包。但是如果没有出现这种情况,您可以通过转到工具→安卓→ SDK 管理器或点击 AndroidStudio 工具栏中的图标来打开 SDK 管理器。
启动您的 SDK 管理器,您将看到当前安装项目的列表。它还将列出您系统中已安装项目的所有新项目和可用更新。从这里,您可以查看所需的构建工具、SDK 工具、平台工具、SDK 平台、SDK 示例、系统映像(适用于 AVD)、文档、安卓 SDK 源和额外的开发包。它需要互联网连接来下载软件包(大多数是大尺寸的),所以请确保您有一个。
- SDK 工具和构建工具包含构建您的安卓应用的包和来自谷歌的几个更新/补丁,以更好地开发应用。
- 对于安卓的特定应用编程接口级别(版本),您必须从 SDK 平台部分下载额外的包。你很容易理解你要安装哪个 API Level/Android 版本,因为有一个列出 Android 版本名称的列表,你只需要选择一个,点击确定。在前面的图片中,您可以看到我们已经在系统上安装了一些 API 级别 22 的包,并且也有更新可供使用。让我们看看我们需要在机器上安装哪些软件包:
- SDK 平台:安卓 SDK 平台包含开发的包/库&为特定版本构建安卓应用。根据特定版本编译您的应用,加载特定的小部件、视图和工具进行编译,是由 SDK 平台完成的。因此,无论何时你想为任何新的安卓版本(如 8.0 或 7.0)下载软件包,一定要选择并下载 SDK 平台。
- 系统映像:要为任何特定的应用编程接口创建 AVD( 安卓虚拟设备 ) ,您应该根据您的系统类型(32 位或 64 位操作系统)下载系统映像。对于安卓智能手机,佩戴&电视,需要单独的图片,也可以下载。如果您的应用正在使用一些播放服务功能,如谷歌地图等,那么要用它们测试您的应用,您还必须下载谷歌应用编程接口系统映像。
- 可选包:SDK 示例,安卓 SDK 来源&应用编程接口级别的文档是可选的。SDK 管理器还允许您为任何特定的 SDK 平台下载一些示例,并为应用编程接口级别下载源代码。如果有文档,您可以下载包含该 API 级别的特定类和方法信息的文档。如果你需要它们,你可以选择下载,否则就不要。
- 在 SDK 管理器中向下滚动,您将看到 Extras 部分,其中包含应用开发所需/有帮助的附加包/库/服务。你可以下载,如果你认为你需要的话。从现在开始,我们建议你忽略它们。
我们希望您已经选择了需要安装的工具和软件包,点击确定或安装。这将打开另一个窗口,如下图所示,选择接受许可RadioButton
,然后点击 SDK 管理器窗口右下角的安装软件包按钮,这将开始下载您选择的软件包。安装需要时间,请耐心等待。当所有软件包安装到您的系统中时,系统会要求您重新启动 ADB ,单击是即可。
这都是关于 SDK 管理器的。在一行中:
它可以让你下载你需要的安卓版本包和应用开发工具”。
我们将在接下来的教程中了解安卓虚拟设备设备。
使用 Eclipse IDE 开发安卓应用
原文:https://www.studytonight.com/android/using-eclipse-for-android
在我们之前的教程中,我们了解了安卓 SDK 管理器。我们希望您已经学习了本教程,并成功地为应用开发配置了您的系统。如果没有,那就去查一下之前的教程。
正如本教程的标题所示,在本教程中,我们将学习如何为安卓开发设置和使用 Eclipse IDE。但事实并非如此。本教程只是为了更新你,谷歌不再支持 Eclipse IDE 进行安卓开发。
对于 Eclipse 中的安卓开发和调试支持,ADT Plugin 是扩展,由谷歌提供,直到 2015 年 6 月,他们停止了对它的工作,并标记为不支持。
如果您不相信我们,请查看此链接。
所以最好开始使用AndroidStudio,如果你一直使用 Eclipse IDE 的话。如果你是一个初学者,那么我们为什么要用一个旧的开发环境开始一段新的旅程。正确
AndroidStudio 就是那时!
设置 AndroidStudio
原文:https://www.studytonight.com/android/android-studio-for-android
在我们之前的教程中,我们谈到了 Eclipse IDE 不再被谷歌支持用于安卓开发,所以现在最好的用于安卓开发的 IDE 是 Android Studio。在本教程中,我们将了解 AndroidStudio,如何设置它及其功能。
在为 Eclipse 发布了许多 ADT 插件后,谷歌决定为安卓应用开发构建自己的 IDE。2014 年 12 月,谷歌发布了 AndroidStudio v1.0 的第一个稳定版本。在此之前,谷歌已经在 2013 年 5 月和 2014 年 6 月晚些时候为开发者提供了 AndroidStudio v0.1 的早期预览阶段。他们从 v0.8 开始发布了 beta 阶段。
从稳定发布之日起,Android Studio 就成为支持所有 Android SDKs 进行 Android 应用开发的官方开发工具。如果您一直在使用 Eclipse 进行安卓应用开发,那么是时候转到 AndroidStudio 享受谷歌即将推出的升级了,因为谷歌已经停止为 Eclipse 插件或 ADT 提供更新,所以 Eclipse 不会提供这些升级。
你可以从这里下载 AndroidStudio。
注:不要担心上图中看到的安卓 Studio 版本。它可能与当前的稳定版本不匹配。但是你必须下载最新稳定版本的 Android Studio。
AndroidStudio 的特点
AndroidStudio 为应用开发提供了许多出色的功能。从发展的角度来看,这里有一些我们喜欢的特性:
格拉德尔
与 Eclipse IDE 非常新且最显著的区别是 Gradle 。这使您可以在同一项目和模块下为具有不同功能的安卓应用创建多个目标(移动、电视和穿戴)。开发人员还可以自定义和配置应用的构建过程。所以最后你可能会有一个项目,所有的模块 apk 都在你的桶里。
线头
在开发过程中,Lint 会检查您的项目源代码,并确定性能改进、兼容性问题(如果有)、bug、安全性改进等,以及与正在进行的应用项目相关的其他问题,这有助于更好地开发应用。
要了解更多关于 Lint 的信息,请查看此链接。
云集成和 Firebase
有了谷歌应用引擎,你可以直接从 AndroidStudio 用最少的努力连接到不同的谷歌云服务。通过使用 Firebase 助手,您可以轻松连接到 Firebase,使用其快速身份验证、通知和其他功能。
应用编程接口集成
在 Android Studio 中,已经配置了各种可以直接用于应用开发的 API。附加的应用编程接口也可以集成到 AndroidStudio 中(见下图)。要添加或删除一个或多个库,您可以点击右侧的绿色+
和红色–
按钮。
动态布局视图
布局编辑器允许拖放功能来构建与 Eclipse 相同的用户界面。此外,当您编辑 XML 时,它还提供了用户界面的预览。
代码帮助
非常快速和支持性的代码帮助Ctrl + Space
是开发人员在输入非常少的代码字母时从项目列表中选择合适的选项。
文档视图
对于每个建议的类、接口或代码,您可以参考其文档,在代码编辑器本身的单独弹出窗口中获得更多帮助。
版本控制
AndroidStudio 已经集成了 Github 和 Bitbucket。所以你的代码可以通过 AndroidStudio 直接推送到像 Github 或者 BitBucket 这样的在线存储库。
内置示例
开发人员获得现成的代码样本,可以直接用于实践和应用开发。
使用 AVD 管理器创建安卓虚拟设备
原文:https://www.studytonight.com/android/android-virtual-device
在本教程中,我们将学习什么是 AVD 管理器,以及如何创建 AVD(安卓虚拟设备)来测试您的第一个安卓应用。
一个安卓虚拟设备 (AVD)是一个运行在安卓模拟器上的设备配置。它提供了特定于虚拟设备的安卓环境,我们可以在其中安装&来测试我们的安卓应用。AVD 管理器是 SDK 管理器的一部分,用于创建和管理创建的虚拟设备。
打开 AVD 管理器,进入工具→安卓→ AVD 管理器,如下图所示。
它将打开 AVD 管理器,并显示创建的虚拟设备列表,如下图所示。它现在对您来说可能是空的,因为您还没有创建任何设备。要创建新设备,点击左下角的创建虚拟设备按钮。
它将打开一个窗口,为您的虚拟设备选择硬件类型。这个列表包含了几乎所有安卓设备及其各自的设置。根据您需要的配置(如屏幕尺寸、分辨率和密度)从列出的所有设备中选择任意一个,然后点击下一步。
接下来,您将被要求为您新创建的虚拟设备选择运行中的安卓版系统映像。您可以选择任何已经在您的AndroidStudio中可用的安卓系统图像,或者通过点击名称可用的下载选项下载您想要的图像。推荐部分将根据可用的最新更新列出可用的最佳选择。 x86 图像包含最常用的图像,其他图像部分包含带有 Google Play Services 的系统图像。根据您需要的配置进行选择(我们选择了 API 级别 21)。完成后点击下一步。
Next window will list down all the configured settings for final verification. Here, you can give your AVD a name for identification, can change device type and API configuration and can also setup size, orientation as well as Graphics for your AVD.
点击显示高级设置,您将看到虚拟设备的更多高级设置,如下图所示。这里有相机、网络、内存(内存&堆)和存储(内部&外部)和虚拟设备框架的设置。
您可以根据自己的要求配置设备,点击完成。AndroidStudio 将立即开始用选定的配置构建 AVD&可能需要一些时间。完成后,AVD 管理器将在可用设备列表中列出您的虚拟设备,如下图所示。
从动作栏(表格最后一栏),可以执行启动 AVD 和编辑 AVD 配置等多个动作。通过单击开始图标(绿色播放图标)启动您的第一个 AVD。它将启动一个虚拟设备,就像安卓设备一样,如下图所示。侧工具栏包含按钮,用于执行诸如上下音量、改变方向、返回、回家或最近的&等操作。您也可以使用电源按钮关闭虚拟设备的电源,并选择关闭按钮关闭虚拟设备。
现在,您的系统上运行了自己的安卓虚拟设备,您可以在其中测试各种安卓应用项目。根据您的项目要求,您的 AVD 管理器中可以有多个虚拟设备。同样,您也可以为安卓电视和安卓穿戴等设备创建 AVD 进行测试。
创建简单安卓应用项目的步骤
原文:https://www.studytonight.com/android/first-android-application
在之前的教程中,我们学习了如何为安卓应用开发设置系统,以及如何创建一个 AVD(安卓虚拟设备)来测试我们的应用。因此,现在在本教程中,我们将创建我们的第一个安卓应用,并尝试了解安卓应用开发的基础知识。
应用基础
我们的第一个应用将是一个简单的应用,有一个活动和一个布局,其中我们将只打印 Hello World!设备屏幕上的。以下是一些你必须知道的事情,不要担心,随着我们的前进,你会明白所有这些:
- 一个活动是
Activity
的一个实例,一个安卓 SDK 中的类。活动负责管理用户与屏幕信息的交互。每当我们创建一个新的活动时,我们实际上是在编写Activity
类的子类。一个简单的应用可能只需要一个子类,而一个复杂的应用可以有很多子类。在我们的第一个应用中FirstAppActivity
将是我们的活动子类。 - A 布局 定义一组用户界面(UI)对象(视图和小部件)及其在设备屏幕上的位置。布局由用 XML 编写的定义组成。每个定义都用来创建一个出现在设备屏幕上的对象(用户界面),比如按钮、文本或图像。
简单来说,我们可以说后端将由扩展Activity
类的类来处理,前端即用户界面在布局 XML 文件中定义。
创建安卓应用的步骤
第一步是创建一个新的安卓项目。安卓项目包含组成应用的所有文件。打开AndroidStudio,转到文件→新建→新项目...
您应该会看到新建项目向导。输入 FirstApp 作为应用名称。对于公司域名,今晚进入网上学习或者你可以使用你自己的名字,例如网上约翰威克。当您进入公司域时,您将看到软件包名称自动生成,就在公司域字段下方。让项目位置保持原样,您可以根据需要进行更改。
请注意,软件包名称(在“公司域”字段下方生成)使用了反向域名系统约定,在该约定中,您组织的域名被反向,并以其他标识符(如应用名称)作为后缀。这种约定保持包名的唯一性,并在设备和谷歌游戏上区分应用。
点击下一步。接下来是AndroidStudio向我们询问目标安卓设备,我们正在为其开发应用。我们的第一个应用将只支持手机,所以只需检查手机和平板电脑。选择 API 16 的最低 SDK 版本:安卓 4.1(果冻豆)。最低 SDK 版本指定了设备上运行我们的应用所需的最低安卓版本。
在下一步中,您将被要求为您的应用的第一个屏幕选择一个模板,选择空活动,然后单击下一步。
在该向导的最后一个对话框中,您将被要求命名您的活动子类。命名为FirstAppActivity
。请注意类名上的活动后缀。这不是必需的,但这是一个很好的惯例。
布局名称将自动更新为activity_first_app
以反映活动名称。布局名称颠倒了活动名称的顺序,全部小写,单词之间有下划线。
点击完成,AndroidStudio 会花一些时间为你准备项目。
在 AndroidStudio 导航
AndroidStudio 将在如下所示的窗口中打开您的项目:
AndroidStudio 中不同的窗格被称为工具窗口。
左侧视图是项目工具窗口。从这里,您可以查看和管理与项目相关联的文件。
中间视图是编辑器。为了让你开始,AndroidStudio 已经在编辑器中打开了activity_first_app.xml
和FirstAppActivity.java
文件。
当布局 xml 打开时,您也可以通过单击编辑器窗口左下角的设计选项卡切换到设计模式,查看您的布局将如何显示。在设计模式下,你可以直接拖放元素,AndroidStudio 会自动在你的布局 xml 文件中为添加的小部件编写代码。
也可以进入视图→工具窗口→预览,打开预览工具窗口。
默认的活动布局定义了两个小部件:一个RelativeLayout
和一个TextView
。
当我们说小部件时,小部件是您用来组成用户界面的构建块。小部件可以显示文本或图形,与用户交互,或者在屏幕上排列其他小部件。按钮、文本输入控件和CheckBox
都是小部件的类型。在接下来的课程中,我们将学习视图和小部件。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:background="@android:color/white"
tools:context="com.example.android.myfirstandroidapp.FirstAppActivity" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@strings/hello_world"
android:layout_centerHorizontal="true"
android:layout_margin="10dp"
android:textSize="15sp"
android:paddingTop="5dp" />
</RelativeLayout>
我们的FirstAppActivity.java
类将覆盖onCreate()
方法,并且正在扩展ActionBarActivity
。ActionBarActivity
是 Android SDK 的Activity
类的子类,其中默认增加了一个动作栏(Top navbar)。
// Some import statements
public class FirstAppActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first_app);
}
}
这就是你的第一份申请。希望你已经了解了开发安卓应用的相关基本概念,现在知道如何使用 AndroidStudio 了。
如果你不理解代码,不要太担心它。我们将在接下来的教程中详细解释每一个细节。从现在开始,只要记住任何扩展Activity
类的类都会在 App 中创建一个视图,并且该视图的设计是使用layout.xml
文件设置的。在FirstAppActivity
类中,setContentView(R.layout.activity_first_app);
行链接布局 XML 文件和FirstAppActivity
类。
安卓应用项目包结构(AndroidStudio)
原文:https://www.studytonight.com/android/android-app-package-structure
在我们之前的教程中,我们学习了如何创建我们的第一个安卓应用以及如何运行它。当我们创建一个安卓项目时,AndroidStudio用一些默认的包和文件夹生成应用项目。在本教程中,我们将讨论安卓应用的项目结构。
以前很多安卓应用都是在 Eclipse IDE 上开发的,但是现在一天只能用 AndroidStudio 开发一个安卓应用,否则谷歌不会允许这个应用公开,甚至拒绝来自谷歌 Play 商店的应用。对于那些使用 Eclipse 开发的应用,现在计划将代码转移到 AndroidStudio 的人来说,这一课将帮助你理解这两个开发工具的结构。
首先我们将了解 Eclipse IDE 的项目结构(如果你是初学者,可以跳过这一部分)。为此,我们将假设你有一个基本的“你好世界!”在 Eclipse IDE 中创建的安卓应用。Eclipse 和 Android Studio 都需要相同的步骤来创建一个应用项目,只有细微的区别。
在 Eclipse 中,每个安卓项目结构都包含以下文件夹,
- 科学研究委员会
- 情报
- 安卓版本
- 资产
- 激光诱导击穿光谱仪
- 表示留数
- 可拉的
- 布局
- 生命
- 价值观念
- AndroidManifest.xml
- 默认值.属性
这些是默认文件夹,它们和另外两个文件一起共同构成了一个安卓应用项目,一个是AndroidManifest.xml
和default.properties
。还有其他文件夹,如 bin 和参考库。
由于在 Eclipse 中创建的大多数文件夹仍然是在 AndroidStudio 中创建的,目录结构有一些变化,因此我们将在下一节解释 AndroidStudio 中安卓应用的包结构。
AndroidStudio 中的包结构
在 Android Studio 中,现代的 Android App 包结构发生了一点变化,但变化非常微妙。
以下是创建的文件夹列表,当你在 AndroidStudio 创建一个安卓应用项目,并在项目查看模式下看到它时:
- app
- 建设
- 激光诱导击穿光谱仪
- src
- androidTest
- 主
- java
- 无
- AndroidManifest.xml
- 毕业生
注: 用黑体字书写的包裹是重要包裹。
src 文件夹
src 文件夹保存任何安卓项目上最重要的两个文件夹,即安卓测试和主。
创建 androidTest 包是为了保存测试应用代码和运行的测试用例。
而主文件夹,有 2 个文件夹和 1 个文件。它们是:
-
java directory
该文件夹包含
.java
(JAVA)文件。在这里,您可以为应用创建接口、活动、片段或适配器。这个文件夹只包含 java 代码。您可以为其中的每一个创建单独的包,并在其中创建类,从而为您的应用项目提供一个定义良好的结构。 -
AndroidManifest.xml
这个文件是任何安卓应用的必备文件。在这个文件中,我们提供了应用的所有活动、服务、广播接收器等信息,以及应用安装在任何设备上时所需的所有权限,如互联网、联系人、摄像头等。请记住,这个文件是任何安卓应用的核心。
-
res directory
此文件夹包含所有与我们的应用项目相关的资源,如图标、图像等,它包含以下子文件夹:
- 可抽拉
该文件夹包含 xml、png、jpg 和 jpeg 文件。在这个文件夹中,您可以存储应用中使用的图像和其他
.xml
文件,这些文件用于许多目的,如创建按钮背景或阴影效果等。- 布局
该文件夹仅包含应用不同屏幕和部分的布局
.xml
文件。-
values
该文件夹包含
strings.xml
、dimens.xml
、colors.xml
、styles.xml
等默认文件。- 在 strings.xml 中,您可以指定所有字符串常量,如屏幕标题或应用中经常使用的任何其他标签。
- 在 dimens.xml 中,您可以创建不同的
.xml
文件,根据屏幕分辨率和尺寸定义尺寸,并在该文件中给出填充、高度、宽度、边距的任何尺寸。 - 在 color.xml 中,您可以使用应用中使用的 hashcodes 来提及颜色列表。如果默认情况下没有创建,您可以自己创建。
- 在style . XML中,您可以定义不同的现成样式,以便在您的安卓应用中的任何地方直接使用它们。
生成文件夹
该文件夹包含R.java
文件,这是一个自动生成的文件。这个文件索引了安卓应用项目的所有资源,如布局 xml 、字符串 xml 等,并且是自动生成的。
在构建文件夹中,您将拥有应用的调试和发布 apk 文件,这是在您构建项目时创建的。
libs 文件夹
如果你想使用任何外部库,你所要做的就是将.jar
文件复制粘贴到 libs 文件夹中,然后你就可以直接在你的.java
代码文件中使用它了。
gradle 文件夹
在这个文件夹中有与 gradle 相关的文件,这些文件可以被修改以改变项目构建过程。例如:如果您希望在构建.apk
文件之前运行所有可用的测试用例,您可以通过在 gradle 文件中提及它来实现。
所以现在你知道了你的安卓应用项目的每个现成文件夹的细节。随着我们继续学习课程,您将会对这些文件夹及其包含的文件类型有更多的了解。即将到来的课程包含关于 Gradle (为 AndroidStudio 构建系统)的信息。
AndroidStudio Gradle 简介
原文:https://www.studytonight.com/android/introduction-to-gradle
在AndroidStudio中,Gradle 用于构建我们的安卓应用项目,因此扮演了构建系统的角色。在 AndroidStudio 之前,在 Eclipse 中,我们使用命令行工具编译和构建应用,该工具很快被基于 GUI 的步骤所取代,以使用 ANT 在 Eclipse 中构建和运行安卓应用。每个 android 应用开发工具都必须编译资源、java 源代码、外部库,并将它们组合成最终的 APK。
Gradle 是一个构建系统,负责代码编译、测试、部署以及将代码转换成.dex
文件,从而在设备上运行应用。
由于 AndroidStudio 自带预装的 Gradle 系统,所以不需要安装额外的运行时软件来构建我们的项目。每当你点击 android studio 中的 Run 按钮时,一个 grade le 任务会自动触发并开始构建项目,在 grade le 完成任务后,app 开始在 AVD 或连接的设备中运行。
像 Gradle 这样的构建系统不是编译器、链接器等,但它控制和监督编译、文件链接、运行测试用例的操作,并最终为你的 Android 应用将代码捆绑到一个apk
文件中。
每个 AndroidStudio 项目都有两个build.gradle
文件,一个是应用文件,另一个是项目级(模块级)构建文件文件。
构建过程如下图所示。
在构建过程中,编译器获取源代码、资源、外部库 JAR 文件和AndroidManifest.xml
(包含关于应用的元数据)并将其转换为.dex
(Dalvik 可执行文件)文件,其中包括字节码。所有安卓设备都支持字节码来运行你的应用。然后 APK 管理器将.dex
文件和所有其他资源合并成单个 apk 文件。 APK 打包程序使用各自的调试或发布密钥库签署调试或发布 APK。
Debug apk 一般用于测试目的或者我们可以说只是在开发阶段使用。当您的应用具有所需的功能并且您准备发布您的应用供外部使用时,您需要使用发布密钥库签署的发布 apk 。
现在让我们来看看这些文件。
setting.gradle
设置.梯度(梯度设置)文件用于指定您的应用中使用的所有模块。
build.gradle(项目级)
顶层(模块) build.gradle 文件是项目级构建文件,定义项目级的构建配置。该文件将配置应用于 android 应用项目中的所有模块。
build.gradle(应用级)
应用级 build.gradle 文件位于安卓项目的每个模块中。该文件包括您的软件包名称applicationID
、版本名称(apk 版本)、版本代码、特定应用模块的最低和目标 sdk。当您包含外部库(而不是 jar 文件)时,您需要在应用级别的 gradle 文件中提到它,以便将它们作为应用的依赖项包含在项目中。
注意:如果某个应用是针对智能手机、平板电脑或电视等单个模块开发的变体,则必须为所有模块创建单独的梯度文件。
你甚至可以通过命令行工具启动你的梯度系统。它使用以下命令:
./gradlew build
-(建设项目)./gradlew clean build
-(构建项目完成从头开始)./gradlew clean build
-(运行测试)./gradlew wrapper
-(查看所有可用任务)
艺术-安卓运行时
达尔维克虚拟机死了。是的,谷歌在 2014 年就停止使用了,虽然你会在网上找到大部分的安卓教程,仍然没有更新,但是请注意 Dalvik Virtual Machine 已经不在安卓使用了。
新的运行时被称为 ART 或 Android Runtime,它与它的前身 Dalvik 非常兼容,但确实有很多新功能,比如:
- 提前编译
- 改良垃圾收集
- 改进的调试和诊断。
在模拟器或设备上运行您的第一个安卓应用
原文:https://www.studytonight.com/android/running-first-android-application
在之前的教程中,我们学习了如何创建我们的第一个安卓应用项目以及如何创建一个安卓虚拟设备用于测试。现在我们将在一个创建的模拟器上运行我们的第一个安卓应用。所以如果还没有启动 AVD,就去 AVD 管理器启动一个 AVD(虚拟设备)。
接下来,打开你的安卓应用项目(我们之前创建的项目)&让 Gradle 第一次完成它的构建。然后点击运行菜单选项,查找编辑配置。见下图。
点击编辑配置选项将打开如下图所示的窗口。将有两个配置选项,一个用于我们的安卓应用项目,另一个用于默认配置。点击安卓应用&中的应用,我们将看到为我们的安卓应用项目配置的其他几个选项。
如我们所见,在常规部分,我们可以指定模块(选择我们的第一个应用像手机、平板电脑、电视、穿戴的哪种应用)、安装选项(部署默认 APK 或其他)、启动选项(启动时启动应用的特定活动)和部署目标选项(是在仿真器上运行还是在物理(USB 连接)设备上运行)。
在杂项选项中,日志和安装选项可用。Logcat 向我们显示了当我们的应用在仿真器或 USB 设备上运行时触发的各种事件的日志。使用 Logcat 日志,我们可以检查我们的应用执行的状态和在我们的项目中使用的各种对象、字符串&实例的值。从这里我们可以配置自动启动 LogCat&在应用开始运行时清除之前的执行日志。
同样,当安装在测试过程中进行时,如果我们的应用与以前的安装相比没有任何变化,我们可以跳过新的安装。如果我们做了一些更改,然后开始测试我们的应用,我们总是可以选择选项来停止我们之前执行的运行活动。
另外两个选项是调试器和分析。从调试器中,我们可以选择调试器的类型来测试我们正在运行的安卓应用项目。它有几个可用的选项,如 Java、原生和混合。
而另一方面,概要分析将让我们选择图形跟踪选项,从这里我们可以删除预编译的着色器和要由 Graphics Tracer 跟踪的程序。
另一方面,默认配置部分包含了我们安卓应用项目的几个可配置设置。从上图中我们可以看到,类似安卓应用(与上一个相同)安卓原生(用于原生开发)安卓测试(测试目的配置)应用引擎 DevAppServer (应用引擎模块配置)应用(应用级别设置)复合、gradlee(用于项目构建的配置)等选项在这里都有。从这些选项中,我们可以为我们的 android 应用项目设置默认配置。这些都是我们在运行/调试应用时可以更改的可用可配置设置。
接下来,如果您对默认设置进行了任何更改,则点击应用,否则选择确定作为默认设置。现在点击运行菜单下的下拉菜单选项,选择应用,然后点击运行选项,绿色三角形(播放按钮)就在它的右边。
它将显示带有系统连接设备列表的窗口。在这里,我们可以选择应用部署目标,并在所需的仿真器或通用串行总线设备上运行我们的应用进行测试。如我们所见,如果我们需要的话,可以在左下角选择创建新模拟器。选择所需的连接设备,点击确定,AndroidStudio 将开始构建您的项目,并在最后在选定的模拟器上安装调试apk
。构建过程需要时间,所以我们应该有耐心,但最后我们会得到一个糖果破解如下图。
希望这个教程教你一些新的关于安卓应用项目的运行/调试配置,我们可以设置。按照程序,在模拟器中测试你的 android 应用项目。
幕后发生了什么?
最后,你已经在你的模拟器上运行了你的第一个 HelloWorld 应用,祝贺你!但是这里有一些当你点击播放按钮时发生的事情。
- 你所有的 Java 源代码都会被 Java 编译器编译成
.class
文件。 - 你所有的
.class
文件被 dx 工具转换成一个单一的.dex
文件,这是安卓 SDK 工具的一部分。 .dex
文件是一个 Dalvik 可执行文件,在应用启动时运行在 Android Runtime(ART)内部。- 该
.dex
文件由安卓应用打包工具 (aapt)与安卓 Manifest 等应用资源文件打包,生成安卓包文件.apk
- 只有经过签名的应用才能在设备/仿真器上运行,以确保其真实性,因此使用 jarsigner 实用程序对
.apk
文件进行签名。 - zipalign 实用程序用于优化
.apk
文件,并最终使其准备好安装。
Android 布局
安卓打字指示器
原文:https://www.studytonight.com/android/android-typing-indicator
我们在脸书、Instagram、Messenger、Twitter 等各种应用中看到了打字指标。如果我们想做一个聊天应用,那么打字指示器是其中一个功能,我们希望在我们的应用中。它将有助于实现更好的 UI。
为了了解它的实现,让我们在我们的安卓应用中添加一个安卓打字指示器。
步骤 1:创建新项目
-
打开你的 AndroidStudio 点击“开始一个新的 AndroidStudio 项目”(学习如何设置 AndroidStudio创建你的第一个安卓项目)
-
从项目模板窗口中选择空活动,点击下一步。
-
输入 App 名称、包名、保存位置、语言(Java/Kotlin,本教程我们将使用 Java )以及最小 SDK (我们使用的是 API 19: Android 4.4 (KitKat))
-
填写以上详细信息后,点击完成按钮。
-
现在,等待项目完成建设。
步骤 2:添加依赖项
转到梯度脚本- >构建.梯度(模块:应用)部分,导入下面的依赖项,点击顶部的“立即同步”。
dependencies
{
//Adding typing indicator
implementation 'com.qifan.typingIndicator:typingIndicator:0.1.0'
}
第三步:用户界面部分
在对 activity_main.xml 文件进行任何更改之前,我们需要一个圆形矩形图像作为打字指示器背景,您可以下载任何圆形矩形图像,并将该图像放入app->RES->drawing able,中,并给它一个合适的名称。
现在,转到app->RES->layout->activity _ main . XML并添加 ChatTypingIndicatorView 并将 RelativeLayout 的背景颜色更改为# 2d 2d,如下所示。
<?xml version = "1.0" encoding = "utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#2d2d2d"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".MainActivity">
<!-- typing indicator -->
<com.qifan.library.ChatTypingIndicatorView
android:backgroundTint="#ffff"
android:layout_centerInParent="true"
android:gravity="center"
android:id="@+id/oklIndicatorView"
android:layout_width="160dp"
android:layout_height="80dp"
android:minHeight="40dp"
android:padding="12dp"
android:background="@drawable/round_rect"
app:dotSize="12dp" />
</RelativeLayout>
第 4 步:编码部分
打开MainActivity.java文件,然后创建并初始化聊天指示器视图对象确定指示器视图,,然后使用该对象调用开始点动画。MainActivity.java的代码如下所示:
package com.studytonight.project;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import com.qifan.library.ChatTypingIndicatorView;
public class MainActivity extends AppCompatActivity {
ChatTypingIndicatorView oklChatIndicatorView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
oklChatIndicatorView=(ChatTypingIndicatorView)findViewById(R.id.oklIndicatorView);
oklChatIndicatorView.startDotAnimation();
}
}
输出:
在下面的快照中,您可以看到 ChatTypingIndicatorView 在 android 应用中的外观。
首次打开应用时:
布局或视图组简介
原文:https://www.studytonight.com/android/introduction-to-layouts
用户与安卓应用的所有交互都是通过用户界面进行的,因此了解安卓应用用户界面的基础知识非常重要。我们已经了解了安卓操作系统中的各种视图,可以用来创建你的安卓应用的各种用户界面组件。
但是您将如何安排所有那些视图组件以有序的方式出现在设备屏幕上。安卓布局用于排列设备屏幕上的视图。
ViewGroup
是所有布局和视图容器的基类。
view group-检视群组
A ViewGroup
是可以包含其他视图的特殊视图。ViewGroup
是安卓布局的基类,如LinearLayout
、RelativeLayout
、FrameLayout
等。
换句话说,ViewGroup
一般用来定义视图(小部件)将在安卓屏幕上设置/排列/列出的布局。
视图组充当一个不可见的容器,在其中放置其他视图和布局。是的,一个布局可以包含另一个布局,或者换句话说,一个视图组可以包含另一个视图组。
类ViewGroup
扩展了类View
。
我们将在接下来的课程中学习布局。
最常用的安卓布局类型
是的,ListView
和GridView
既可以作为视图,也可以作为视图组。你会问怎么做?嗯,如果我们使用ListView
视图以列表形式显示一些数据,它就像一个视图。但是如果我们用它来创建其他视图的列表,例如ImageView
,那么它就像一个视图组。
此外,视图组子类扩展了类ViewGroup
,进而扩展了类View
,所以在某种程度上所有的ViewGroup
子类实际上都是视图,带有一些额外的特性。
编程和声明方法
要在安卓应用中创建/定义视图或视图组,有两种可能的方法:
-
The Programmatic Approach: In this we define/create our Views in the Java source file. We will learn about this approach in details later, as of now here is a sample code to add a Button to our view.
Button myButton = new Button(this); myButton.setLayoutParams(new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)); myLayout.addView(myButton);
所以
addView()
是用来给 UI 添加任意视图的功能,setLayoutParams()
是用来设置各种属性的功能。 -
声明性方法:在这里,我们直接在设计 XML 文件中定义视图和视图组,就像我们将在接下来的几个教程中学习的各种常用视图一样。
在混合教程中,我们将了解每种流行的布局类型,以及如何使用它们来排列不同的视图组件,从而定义您的安卓应用的用户界面。
安卓系统中的线性布局
原文:https://www.studytonight.com/android/linear-layout-in-android
LinearLayout
是一个视图组,负责在其中保存视图。它是一种布局,将子视图(即各种视图和布局)线性(一个接一个)排列在一列(垂直)或一行(水平)中。
所有的孩子是水平排列还是垂直排列取决于属性android:orientation
的值。默认情况下,方向为水平。
垂直线性布局
在垂直线性布局中,顾名思义,线性布局中定义的视图是一个接一个真实排列的,就像在一列中一样。为此,我们需要在 LinearLayout 标签中提到值为垂直的android:orientation
属性。
为了更清楚地理解,让我们检查下面的代码及其显示的输出。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.android.studytonightandroid.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="Welcome"
android:background="@color/colorAccent"
android:textAllCaps="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="to"
android:background="#E65100"
android:textAllCaps="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:background="#25f"
android:text="Studytonight"
android:textAllCaps="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="android"
android:background="#76FF03"
android:textAllCaps="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="is"
android:background="#FDD835"
android:textAllCaps="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="fun"
android:background="#E040FB"
android:textAllCaps="true"/>
</LinearLayout;>
正如我们所看到的,线性布局里面有 6 个孩子,都是 TextView 。此外,由于方向属性设置为垂直,所有 6 个子对象将一个接一个地垂直显示。
水平线形布局
在水平线性布局中,顾名思义,线性布局中定义的视图将一个接一个地水平排列,就像一行一样。默认情况下,方向设置为水平。但是通过在 linear layout 标签中将属性android:orientation
设置为值水平,来明确指定线性布局的方向是一个很好的做法。
为了更清楚地理解这一点,让我们检查下面的代码及其显示的输出。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context="com.example.android.studytonightandroid.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="Welcome"
android:background="@color/colorAccent"
android:textAllCaps="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="to"
android:background="#E65100"
android:textAllCaps="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:background="#25f"
android:text="Studytonight"
android:textAllCaps="true"/>
</LinearLayout>
如我们所见,线性布局中有 3 个子元素。此外,由于方向属性设置为水平,所有 3 个子视图(即TextView
)将一个接一个地水平显示。
线性布局中的线性布局
线形布局是一个视图组,也可以包含其他布局。让我们试试下面的代码,其中我们在另一个线性布局中添加了一个线性布局,以及一些视图。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#FFEB3B"
tools:context="com.example.android.studytonightandroid.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="Welcome"
android:textAllCaps="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="to"
android:textAllCaps="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="Studytonight"
android:textAllCaps="true"/>
<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="horizontal"
android:background="#FF6E40">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="android"
android:textAllCaps="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="is"
android:textAllCaps="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="fun"
android:textAllCaps="true"/>
</LinearLayout>
</LinearLayout>
第一个线性布局(黄色)有 3 个TextView
和 1 个线性布局作为其子元素。由于它被设置为垂直方向,它的所有子对象将垂直出现。
第二个线性布局(橙色)有 3 个TextView
作为其子视图。由于它被设置为水平方向,它的所有子对象将在这个线性布局中水平显示。
安卓中的相对布局
原文:https://www.studytonight.com/android/relative-layout-in-android
相对布局是根据其他视图/小部件/视图组的位置排列视图/小部件/ 视图组的布局,即新视图相对于已经存在的视图放置。
例如,在一堂课上,如果学生 A 坐在椅子上,该班的老师要求学生 B 坐在学生 A 的右边,学生 B 将知道他/她必须坐在哪里。
类似地,每个视图的位置可以相对于它的兄弟元素(例如在另一个视图的左边或下面)或者相对于父视图的位置来指定。
相对布局是 GUI 设计中最常用的布局。为了了解 RelativeLayout 是如何工作的,让我们来看看并理解 RelativeLayout 最常见的属性。
RelativeLayout 的公共属性
相对于父视图居中
当您想要将视图相对于父视图放置在中心时,可以使用以下 3 个属性:
在我们了解不同的属性之前,我们想指定我们例子中的父项也是一个相对布局,高度和宽度设置为match_parent
,因此它将覆盖手机的整个屏幕。所以整个屏幕就是我们的父视图。
-
android:layout_centerHorizontal="true"
这将视图水平放置在父视图的中心。由于我们的父视图覆盖了移动设备的整个屏幕,因此视图被水平放置在移动设备屏幕的中间。(见上图黄色视图)
-
android:layout_centerVertical="true"
这将视图垂直放置在父视图的中心。由于父视图覆盖了移动设备的整个屏幕,因此视图被垂直放置在移动设备屏幕的中间。(见上图蓝色视图)
-
android:layout_centerInParent="true"
该属性将视图放置在父视图的中心。因为在我们的例子中,父屏幕覆盖了移动设备的整个屏幕,所以视图被放置在移动设备屏幕的中间,无论是水平的还是垂直的。(参见上图中的奶油色视图)
按父视图对齐
这些类型的属性使视图像口香糖一样,因为它可以使用这些属性固定到父视图的任何一侧。
再举个例子,我们考虑我们的父视图是一个 RelativeLayout,高度和宽度设置为match_parent
,因此它将覆盖手机的整个屏幕。所以整个屏幕就是我们的父视图。
-
android:layout_alignParentTop="true"
如果您为视图编写了此属性,则该视图将固定在其父视图的顶部。由于父屏幕覆盖了移动设备的整个屏幕,因此视图将出现在移动设备屏幕的左上角。
-
android:layout_alignParentBottom="true"
如果您为一个视图编写这个属性,那么该视图将停留在其父视图的底部。因为我们的父母覆盖了手机的整个屏幕,所以视图会出现在手机屏幕的底部。
-
android:layout_alignParentLeft="true"
如果为视图编写此属性,则该视图将停留在其父视图的左侧。由于我们示例中的父对象覆盖了移动设备的整个屏幕,因此视图将出现在移动设备屏幕的左侧。
-
android:layout_alignParentRight="true"
如果您为视图编写此属性,则该视图将停留在其父视图的右侧。
注意:这些属性你可以一直使用一个以上。假设使用
android:layout_alignParentLeft="true"
和android:layout_alignParentBottom="true"
,那么视图会贴在屏幕左下角,如上图粉色视图所示。
相对于现有同级视图放置新视图
在相对视图中,您可以保持新视图相对于其他现有视图的位置。以下属性可用于此目的。
假设中心有一个视图,其id
为android:id="@+id/main"
,那么其他新视图可以相对于该视图放置如下:
-
android:layout_toLeftOf="@id/main"
这告诉新视图,您必须位于视图的左侧,该视图的
id
是主视图。 -
android:layout_toRightOf="@id/main"
这告诉新视图,您必须在视图的右侧,该视图的
id
是主。 -
android:layout_above="@id/main"
这告诉新的观点,你必须在
id
为主的观点之上。 -
android:layout_below="@id/main"
这告诉新的观点,你必须在
id
为主的观点之下。
注:给视图分配
id
时,写安卓:id="@+id/main" 即在@
符号后写+
符号,表示给该视图分配id
。但是当您将id
用于其他目的时,如上所述,您相对于具有指定值id
的现有视图添加了一个新视图,因此我们不必提及+
符号。我们简单称之为安卓:layout_below="@id/main" 即没有+
标志。
相对于现有同级视图对齐新视图
如果要相对于任何现有视图对齐新视图,则可以使用以下属性。
-
android:layout_alignTop="@id/a"
这将使新视图的上边距与视图的上边距对齐,其中
id
为a
。 -
android:layout_alignBottom="@id/a"
这将使新视图的底边与视图的底边对齐,视图的
id
为a
。 -
android:layout_alignLeft="@id/a"
这将使新视图的左边距与视图的左边距对齐,其中
id
为a
。 -
android:layout_alignRight="@id/a"
这将使新视图的右边距与视图的右边距对齐,视图的
id
为a
。 -
android:layout_alignBaseLine="@id/a"
这将使新视图的文本 1 与视图的文本 2 对齐,视图的
id
为a
。
在布局 XML 中定义相对布局
现在让我们理解以下代码:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFEB3B"
tools:context="com.example.android.studytonightandroid.MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:textStyle="bold"
android:textAllCaps="true"
android:textSize="17sp"
android:text="Two Button will use me as a reference" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Aligned to the\nsecond button"
android:layout_below="@+id/textView"
android:layout_alignLeft="@+id/textView"
android:layout_margin="5dp"
android:layout_alignStart="@+id/textView" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Aligned to the\nfirst button"
android:layout_toRightOf="@id/button"
android:layout_alignTop="@id/button"
android:layout_below="@+id/textView"
android:layout_marginRight="21dp"
android:layout_marginEnd="21dp" />
<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/button"
android:layout_alignStart="@+id/button"
android:layout_below="@+id/button"
android:layout_marginTop="70dp"
android:textStyle="bold|italic"
android:textSize="20sp"
android:textColor="#25c"
android:text="I want to align by base\nline with you" />
<TextView
android:id="@+id/textView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/textView5"
android:layout_alignTop="@+id/textView5"
android:layout_margin="10dp"
android:textSize="20sp"
android:textStyle="bold|italic"
android:textColor="#25c"
android:layout_marginTop="70dp"
android:layout_alignBaseline="@id/textView5"
android:text="Okay,let me use the attribute" />
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentLeft="true"
android:textAllCaps="true"
android:textStyle="bold"
android:textSize="20sp"
android:textColor="#D50000"
android:text="I have used 3 chewing gum like attributes and now I am stuck at the bottom"/>
</RelativeLayout>
输出屏幕:
在上面的代码中:
- 我们使用
android:layout_alignParentTop="true"
属性在屏幕顶部放置了一个带有id
TextView
的视图。 - 这两个按钮位于具有
id
TextView
的TextView
下方。这是通过在两个按钮标签中使用android:layout_below="@+id/textView"
属性来完成的。 - 我们已经使用
android:layout_alignTop="@id/button"
属性从上边距对齐了两个按钮。 - 我们还尝试根据文本对齐两个
TextView
,即对齐两个视图的文本。 - 最后,我们使用了粘性属性
android:layout_alignParentBottom="true"
、android:layout_alignParentRight="true"
和android:layout_alignParentLeft="true"
将TextView
4 粘贴在屏幕底部。就像口香糖是可拉伸的一样,本例中的 TextView 也是可拉伸的,因此它的边界会被拉伸并粘到屏幕的左侧、右侧和底部。
安卓表格布局
原文:https://www.studytonight.com/android/table-layout-in-android
一个TableLayout
是一个视图组,它以表格的形式排列其子视图和其他布局,表格中有行和列。要定义一行,可以在该布局中使用<TableRow>
标记。
没有必要提及 TableLayout 中的列数,因为 Android 会根据表行中添加的视图和其他布局的数量自动添加列。
表格布局:需要记住的要点
- TableRow 不需要提供
layout_width
和layout_height
,因为默认情况下,它的宽度是match_parent
,高度是wrap_content
。 - 一个表行,其中有最多的视图,创建了许多列。
- 列的宽度会根据具有最大宽度的列的大小自动调整。
现在让我们看看TableLayout
中使用的一些常见属性。
| 属性 | 使用它的地方 | 为什么使用它 |
| android:stretchColumns
| 表格布局 | 当列宽较小时,需要扩展(或拉伸)它时,可以使用该属性。 |
| android:shrinkColumns
| 表格布局 | 当您不需要列中的额外空间时,可以使用此属性来收缩和移除空间。 |
| android:collapseColumns
| 表格布局 | 它在 TableLayout 中隐藏给定索引的列。 |
| android:layout_span
| 表格行中的任何视图 | 如果视图只占用一个列宽,但希望视图占用多个列空间,则可以使用此属性。 |
| android:layout_column
| TableRow 中的任何视图 | 当您希望第一个表行中的视图显示在另一个表行的视图下方时,可以使用该属性。 |
在布局 XML 中定义表格布局
现在,让我们理解如何在尤拉 XML 及其输出中定义一个表布局。
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
android:background="#FFFF00"
android:stretchColumns="*"
android:shrinkColumns="*">
<!-- first row -->
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:background="@color/colorAccent">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="NAME"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<EditText
android:id="@+id/edtName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Enter you name"
android:inputType="textPersonName"/>
</TableRow>
<!-- second row -->
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:background="#0091EA">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Password"
android:textAllCaps="true"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<EditText
android:id="@+id/edtPwd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Enter your Password"
android:inputType="textPassword"/>
</TableRow>
<!-- third row -->
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:padding="16dp">
<Button
android:id="@+id/btnSubmit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="SUBMIT"/>
</TableRow>
</TableLayout>
输出屏幕:
正如您在 XML 文件中看到的,根元素是TableLayout
,因此您的布局将有一个以行和列的形式呈现的元素表。
表格布局中的行是用标记 TableRow 定义的。您必须使用属性layout_width
和layout_height
指定行的宽度以及高度。
接下来,如果您想要在 TableLayout 中添加一个新行,您可以添加新的 TableRow 标记,并在其中定义您想要的组件/视图。表格行的工作方式与线性水平布局相同,其中组件并排放置。
我们为 TableLayout 设置了三个属性,即:
-
collapseColumns
此属性定义要折叠的列,即隐藏指定索引的列。
-
shrinkColumns
此属性用于通过为列提供 indes 值来收缩一列或多列。
-
stretchColumns
此属性用于拉伸列。
索引值从0
开始,即第一列将有索引0
,然后是1
等等。
对于所有这三个属性,列索引可以显示为单个值,或者如果要将此属性应用于多个列,可以在索引之间使用逗号(,)来实现。1,2,5。您也可以使用值*
拉伸所有列,而不用提及列的索引。
可以看到,在布局 e 中,第一行添加了两个组件——一个是 AndroidStudio (显示名称作为标签),另一个是EditText
(从用户那里获取名称)。我们已经将该行的gravity
设置为中心,这样元素就被放置在显示屏的中心。
同样,我们添加了第二行TextView
(将密码显示为标签)和EditText
(从用户那里获取密码)。
第三行只包含一个提交按钮。
使用多个布局和视图设计 GUI
原文:https://www.studytonight.com/android/hierarchical-arrangement-in-android
正如我们在之前的教程中学习过的不同视图视图组和布局,现在是时候研究如何在我们的安卓项目中一起使用它们来设计出色的用户界面了。在本教程中,我们将学习如何将不同的布局、视图和视图组放在另一个布局(分层排列)中,为您的安卓应用设计完美的 GUI。
下面我们有一个非常基本的例子来演示如何一起使用多个布局、视图和视图组。
在布局 XML 文件中定义设计
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFF59D"
tools:context="com.example.android.myapplication.MainActivity">
<!--Light Yellow Color-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="@+id/l1"
android:background="#FF9E80">
<!--Light Pink Color-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Studytonight"
android:textAllCaps="true"
android:textSize="40dp"
android:textColor="#F44336"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Android"
android:textAllCaps="true"
android:textSize="40dp"
android:textColor="#F44336"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_below="@id/l1"
android:background="#039BE5"
android:id="@+id/l2">
<!--Light Blue Color-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Studytonight"
android:textAllCaps="true"
android:textSize="30dp"
android:textColor="#76FF03"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Android"
android:textAllCaps="true"
android:textSize="30dp"
android:textColor="#76FF03"
/>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/l2"
android:background="#7E57C2"
>
<!--Light Purple Color-->
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Toast 1"
android:id="@+id/b1"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Toast 2"
android:layout_toRightOf="@id/b1"
android:id="@+id/b2"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Toast 3"
android:layout_below="@id/b1"
android:id="@+id/b3"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Toast 4"
android:layout_below="@id/b2"
android:layout_toRightOf="@id/b3"
/>
</RelativeLayout>
</RelativeLayout>
- 在上面的 UI 设计中,我们有一个根元素 RelativeLayout 。这意味着它的所有子元素,无论是布局还是视图,都将以相对的方式排列。因此,仔细选择我们的根布局非常重要。
- 接下来,我们有一个线性布局,其方向设置为垂直。这意味着该线性布局中的所有元素将以垂直方式排列。
- 接下来,我们有另一个线性布局,其方向设置为水平。因此,如您所见,我们可以在根布局中放置不同的布局。
- 接下来,我们将另一个相对布局放置在根相对布局中。这个相对布局里面有 4 个按钮,以相对的方式排列。
- 请记住,所有这些布局都放置在相对布局中。因此,所有这些布局都是相对的。
安卓提供了一种非常结构化和可扩展的用户界面设计方式。既然你已经理解了如何使用各种布局、视图和视图组,那就继续为你的应用设计一些出色的用户界面屏幕吧。
安卓视图(和小部件)
安卓WebView
安卓 WebView 用于在安卓中加载和显示网页。
当我们需要增加对应用中用户界面和高级配置选项的控制时,网络视图非常有用。
在这里,我们将学习在我们的安卓应用中添加一个安卓网络视图。那么,让我们开始吧。
步骤 1:创建新项目
-
打开你的 AndroidStudio 点击“开始一个新的 AndroidStudio 项目”(学习如何设置 AndroidStudio创建你的第一个安卓项目)
-
从项目模板窗口中选择空活动,点击下一步。
-
输入 App 名称、包名、保存位置、语言(Java/Kotlin,本教程我们将使用 Java )以及最小 SDK (我们使用的是 API 19: Android 4.4 (KitKat))
-
填写以上详细信息后,点击完成按钮。
-
现在,等待项目完成建设。
步骤 2:添加互联网权限
现在转到app->mainfestics->androidmanifest . XML并添加互联网权限,现在我们的 AndroidManifest.xml 文件将如下所示:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.studytonight.project">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.StudyTonight">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
第三步:将网络视图添加到安卓活动中
现在转到 app - > res - >布局- > activity_main.xml 并添加 Webview ,现在我们的 activity_main.xml 文件将如下所示:
<?xml version = "1.0" encoding = "utf-8"?>
<RelativeLayout xmlns:android = "http://schemas.android.com/apk/res/android"
xmlns:app = "http://schemas.android.com/apk/res-auto"
xmlns:tools = "http://schemas.android.com/tools"
android:layout_width = "match_parent"
android:layout_height = "match_parent"
tools:context = ".MainActivity">
<!-- webview -->
<WebView
android:id="@+id/oklWebView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
在上面的代码中,我们已经在我们的安卓活动中添加了默认的网络视图。
第四步:修改活动
这是我们 app 中添加 webview 的主要部分,首先我们打开MainActivity.java文件,导入一些基础类,如下图
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.webkit.WebView;
接下来,我们在 MainActivity 类中创建 WebView 类的对象,如下所示:
//creating object of WebView
WebView oklWebView;
现在,在 onCreate
方法内部,我们初始化 WebView 如下图所示。
//initializing the WebView objects
oklWebView=(WebView)findViewById(R.id.oklWebView);
初始化网络视图后,我们只需加载网址。
//load the url
oklWebView.loadUrl("https://www.studytonight.com/");
MainActivity.java的完整代码如下:
package com.studytonight.project;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.webkit.WebView;
public class MainActivity extends AppCompatActivity {
//creating object of WebView
WebView oklWebView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//initializing the WebView objects
oklWebView=(WebView)findViewById(R.id.oklWebView);
//load the url
oklWebView.loadUrl("https://www.studytonight.com/");
}
}
现在,我们的应用已经准备好了,运行该应用并查看输出。
输出:
在下面的快照中,您可以看到 Webview 在安卓应用中的外观。
当第一次打开应用时:我们可以看到 https://www.studytonight.com/在我们的应用中打开
当滚动WebView
时,它会转到页面底部。
安卓视图和视图组简介
原文:https://www.studytonight.com/android/introduction-to-views
用户与安卓应用的所有交互都是通过用户界面进行的,因此了解安卓应用用户界面的基础知识非常重要。在本教程中,我们将介绍各种Views
和ViewGroups
,并尝试解释如何使用它们来设计安卓应用的用户界面。
视图
视图是安卓系统 UI(用户界面)的基本构件。视图指的是android.view.View
类,对于TextView
、ImageView
、Button
等所有 GUI 组件来说都是超级类。
View
类扩展Object
类,实现Drawable.Callback
、KeyEvent.Callback
和AccessibilityEventSource
。
视图可以被认为是屏幕上显示某种类型内容的矩形。它可以是一张图片、一段文字、一个按钮或任何安卓应用可以显示的东西。这里的矩形实际上是不可见的,但是每个视图都占据一个矩形形状。
可能会困扰你的问题是,这个长方形的大小是多少?
答案是,我们可以手动设置它,通过指定确切的大小(用适当的单位)或通过使用一些预定义的值。这些预定义值是match_parent
和wrap_content
。
match_parent
表示它将占据设备显示屏上的全部可用空间。而wrap_content
意味着它将只占用显示其内容所需的空间。
在安卓系统中,视图也被称为小部件。任何视觉的(我们可以在屏幕上看到的)和交互的(用户可以与之交互的)被称为小部件。
用于创建视图的 XML 语法
现在,正如我们之前解释的,要在 android 应用中绘制任何东西,您必须在设计 XML 文件中将其分离。为了增加功能,我们将创建 Java 文件。
XML 中的每个视图都有以下格式:
<ViewName
Attribute1=Value1
Attribute2=Value2
Attribute3=Value3
.
.
AttributeN=ValueN
/>
- 它总是以一个尖括号开始,后面跟着视图名称。我们将很快向您介绍各种类型的视图。
- 然后我们编写属性,它将定义视图在应用屏幕上的外观,以及属性的值。每个视图都有自己的属性,我们将在接下来的几个教程中讨论,这些教程将涵盖各种类型的视图。
- 最后被
/>
关闭
所以,每个View
子类都需要遵循这种格式,这样才能出现在 app 的屏幕上。这种格式只是默认的 XML 样式。没错。
每个View
都需要两个属性。这些是:android:layout_height
和android:layout_width
。
这些属性定义了视图形成的不可见矩形的大小。使用这些属性,我们可以轻松控制安卓应用中每个视图的大小。
除了上面提到的属性,像gravity
、layout_gravity
、padding
、margin
等属性也是一些常用的属性。
最常用的安卓视图类
这里我们有一些最常用的安卓View
类:
- 文字检视
EditText
- 按钮
- 影像检视
ImageButton
CheckBox
RadioButton
- 列表浏览
- GridView
- 日期选择器
Spinner
等。
编程和声明方法
要在安卓应用中创建/定义视图或视图组,有两种可能的方法:
-
The Programmatic Approach: In this we define/create our Views in the Java source file. We will learn about this approach in details later, as of now here is a sample code to add a Button to our view.
Button myButton = new Button(this); myButton.setLayoutParams(new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)); myLayout.addView(myButton);
所以
addView()
是用来给 UI 添加任意视图的功能,setLayoutParams()
是用来设置各种属性的功能。 -
声明性方法:在这里,我们直接在设计 XML 文件中定义视图和视图组,就像我们将在接下来的几个教程中学习的各种常用视图一样。
Android TextView
TextView
是最广泛使用的视图用来在显示屏上显示预定义的文本。
这不仅是一个单独使用的视图,也可以和其他视图一起使用,比如当你创建一个表单时,你有EditText
视图、CheckBox
视图等,那么要提到标签和其他信息,我们就必须旁边使用TextView
。
以下是一些最常用的主要属性:
| 属性 | 描述 |
| android:text
| 用于指定要在TextView
中显示的文本 |
| android:textSize
| 使用这个属性,我们可以控制文本的大小。 |
| android:textColor
| 使用这个属性,我们可以指定文本的颜色。 |
| android:textAllCaps
| 如果设置为真,这将使文本以大写形式出现。 |
| android:letterSpacing
| 使用这个属性,我们可以设置文本字母之间的间距。 |
| android:hint
| 如果TextView
中没有设置文本,该属性用于显示默认文本。通常,当我们使用来自服务器的动态数据(使用编程方法)填充TextView
时,我们设置该属性以在TextView
中显示一些默认文本,直到从服务器获取数据。 |
现在让我们看看如何在设计布局 XML 中定义TextView
:
<TextView
android:id="@+id/st"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Studytonight"
android:textSize="45sp"
android:padding="20dp"
android:textColor="#DD2C00"/>
首先,我们用<
打开标签,输入TextView
,表示我们正在创建一个TextView
,它将显示在应用中。现在让我们看看上面提到的属性是做什么的。
如前所述,安卓:layout _ width =“wrap _ content”和安卓:layout _ height =“wrap _ content”必须为每个视图编写,因为我们必须为创建的每个视图定义宽度和高度。
-
android:id="@+id/tv_text_gender"
这给了这个
TextView
一个id
(标识),可以在 Java 文件中使用它来访问这个TextView
,并动态地对其进行任何更改。例如,假设我们将一些初始文本设置为“研究”。但是我们希望触摸屏幕后,文本显示为“今晚学习”。因此,我们在我们的 Java 类中使用这个id
,并使用一些预定义的函数在运行时更改TextView
的文本,当用户点击它时。我们将很快学会如何做。 -
android:text="StudyTonight"
TextView
将属性中的给定值显示为文本。 -
android:textSize="45sp"
这用于确定
TextView
中显示的文本大小。 -
android:padding="20dp"
这为文本提供了 20dp 的填充。本教程中有更多关于填充的内容。
-
android:textColor="#DD2C00"
这将设置文本的颜色。
#DD2C00
是颜色有些暗红的六进制代码。您可以从colorshexa或官方材料设计网站- 材料颜色轻松查找各种颜色的 Hexa 代码此外,AndroidStudio 中有一些预定义的颜色存储在值目录中的 color.xml 文件下。要访问这个,可以使用
"@android:color/your_color_name"
作为上述属性中的值。您也可以在 color.xml 样式文件中定义您在应用中经常使用的颜色。这样做是一个非常好的做法,因为如果您决定更改颜色代码/色调,您所要做的就是在 color.xml 文件中更改它,它将在任何地方都被更改。
输出屏
安卓中的EditText
视图
原文:https://www.studytonight.com/android/android-texteditview
EditText
是可编辑的TextView
。它几乎和 T2 有着相似的属性。当您希望在应用中有一个用户可以输入任何文本的文本字段时,可以使用EditText
。可以是单线或多线。触摸文本字段位置会激活该字段,放置光标并自动显示键盘。
以下是一些最常用的属性:
| 属性 | 描述 |
| android:inputType
| 用于指定输入的文本应该是什么样的,以及用于什么目的。如果设置为none
,则文本无法编辑。此属性的一些常用常量值如下:
- 文字
- 文本自动完成 -这为用户输入文本提供了建议。
- 文本自动更正 -这将启用用户输入文本的自动更正。
- 文本密码 -以点或星的形式显示输入的文本。
- 纹理
- 文本电子邮件地址
- 电话 -这将只向用户呈现数字键盘。
- 日期时间等。
所有可用的常量值都可以在这里检查。我们可以使用多个常量值,通过使用|
将它们分开,例如:
android:inputType="textCapSentences|textAutoCorrect"
|
| android:imeOptions
| 在大多数输入法中,如键盘或短信发送表单,键盘右下角有一个适合该输入法的操作按钮。可以是搞定、下一个、发送、去等。要指定键盘动作按钮,使用带有动作值的android:imeOptions
属性,如动作发送或动作搜索等。 |
| android:minLines
| 它提供的视图的高度相当于屏幕上指定的行数。因此,如果您输入一个值2
,那么默认情况下,EditText
视图将有 2 行高,即使没有添加任何文本。它将是默认高度。 |
| android:maxLines
| 它设置EditText
视图可以容纳的最大行数,可视化。换句话说,当我们说maxLines
的值为 3 时,这意味着EditText
视图字段将有 3 行高,此后,随着越来越多的文本添加到其中,它将停止增加大小,通常当行数超过设置的限制时,会显示滚动条。 |
| android:hint
| 它在任何人输入EditText
之前显示一条提示消息。 |
| android:maxLength
| 它允许指定用户可以在字段中输入的最大字符数。 |
以下是默认EditText
字段的示例:
<EditText
android:id="@+id/et_address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Write your email Address here"
android:textSize="20sp"
android:inputType="textWebEmailAddress"
android:imeOptions="actionDone"
android:maxLines="3"/>
-
android:hint="Write your email address here"
该属性向用户提示应该在框中输入什么。这是一条临时消息,一旦用户开始在字段中写入任何内容,该消息就会消失。
-
android:inputType="textWebEmailAddress"
此属性指定输入的文本应该是什么样的,以及它将用于什么目的。这里,我们使用了
textWebEmailAddress
,它将只允许电子邮件输入。 -
android:maxLines="3"
这显示在最大值。只有 3 行文字。如果您的文本超过 3 行,则第一行文本将上移,即它将不可见,第 2 行到第 4 行的文本将可见。虽然我们应该将电子邮件地址字段的值保持为 1,但我们将其设置为 3 只是为了解释它在这里的用途。
输出屏
安卓系统中的RadioButton
视图和Checkbox
视图
原文:https://www.studytonight.com/android/android-radiobutton-and-checkbox
当你在安卓应用中创建一个接受用户输入的表单,并且你必须列出几个选项供用户选择时,CheckBox
和单选框就派上了用场。
因此,单选框和CheckBox
之间的功能区别在于,当用户在多个选项中只能选择一个选项时,我们使用单选框,如果允许多选,则应使用CheckBox
。
安卓系统中的Checkbox
视图
当您必须向用户显示多个选项,并且用户可以通过点击选择任意多个选项时,使用Checkbox
。您可以将其默认检查状态设置为真或假,其他属性与TextView
相同。
<CheckBox
android:id="@+id/myCheckbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Studytonight"
android:checked="true"
android:textColor="@android:color/black"
android:layout_marginLeft="30dp"/>
-
android:checked="true"
该属性检查,即默认情况下在
CheckBox
中放置勾号。
这涵盖了我们如何在应用屏幕上显示 CheckBox 视图。它是如何工作的,我们很快就会知道。
输出屏
安卓系统中的RadioButton
视图
当您必须允许在多个选项列表中只选择一个选项时,使用RadioButton
。它在其父视图–RadioGroup
下使用,因此我们可以从所有列出的RadioButton
中选择一个值。
<RadioGroup
android:id="@+id/rg_gender"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginLeft="20dp">
<RadioButton
android:id="@+id/rb_male"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Male"
android:textColor="@android:color/black"/>
<RadioButton
android:id="@+id/rb_female"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:text="Female"/>
</RadioGroup>
我们也可以使用微调视图来显示选项列表,其中只能选择一个。但是在 Spinner 中,并不是所有的选项都同时显示给用户,它更像是一个下拉菜单。
还有RadioGroup
是LinearLayout
的子类,垂直排列RadioButton
,因为默认是垂直方向。但是您可以通过在布局 XML 文件中将属性android:orientation="horizontal"
添加到您的RadioGroup
中来更改它。
输出屏
检查RadioButton
或Checkbox
视图的当前状态
为了检查RadioButton
或CheckBox
是否被选中,我们可以在 Java 代码文件中编写一个简单的代码。
// initiate the radio button
RadioButton maleRadioButton = (RadioButton) findViewById(R.id.rb_male);
// check current state of the radio button (true or false)
Boolean RadioButtonState = maleRadioButton.isChecked();
代码的第一行使用布局 XML 中为RadioButton
视图指定的id
来创建该视图的实例。这段代码对于所有类型的视图都是一样的。
同样,我们也可以选中相同的CheckBox
,
// initiate the check box
CheckBox myCheckbox = (CheckBox) findViewById(R.id.myCheckbox);
// check current state of the check box (true or false)
Boolean CheckBoxState = myCheckbox.isChecked();
常用属性
这里我们有一些常用的属性,你可以用它们来设计你的RadioButton
和Checkbox
视图。
-
android:textColor
:改变文字的颜色。 -
android:textSize
:调整文字大小。 -
android:textStyle
:文本样式,可能的值有Bold
或Italic
等。 -
android:background
:给RadioButton
一个背景色。 -
我们也可以在
RadioButton
的文本旁边使用图像。要添加图像,我们可以使用android:drawableTop
、android:drawableBottom
、android:drawableRight
和android:drawableLeft
,分别在文本的顶部、底部、右侧或左侧设置图像。android:drawableRight="@drawable/any_picture"
安卓系统中的Button
视图
Button
,顾名思义,是用户可以按下或点击来执行动作的组件。它具有与TextView
相同的属性,只有几个按钮特定的属性。
下面我们已经指定了如何使用布局 XML 在您的 android 应用中定义Button
视图:
<Button
android:id="@+id/btn_submit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Submit"
android:textColor="@android:color/holo_blue_dark"
/>
Button
视图的主要用途是,每当我们单击一个按钮时,我们可以设置一个方法来处理该特定的按钮请求并执行必要的操作。这可以在 Activity
类内完成,如下所示:
注意:如果你现在还不知道
Activity
班的情况,不用担心。我们很快会解释的。
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// creating instance of button
Button b = (Button) findViewById(R.id.btn_submit);
// setting on click event listener
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
}
});
}
}
因此,每当我们按下带有id
btn_submit 的按钮时,就会调用上面的方法,执行其中的代码。
使用android:onClick
为按钮添加行为
我们还可以在布局 XML 中直接分配一个方法,同时使用android:onClick
属性定义按钮,如下所示。
<Button
android:id="@+id/btn_submit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Submit"
android:textColor="@android:color/holo_blue_dark"
android:onClick="study"
/>
当用户点击上述布局 xml 文件中定义的按钮时,安卓系统将调用MainActivity.java
文件中定义的study(View)
方法。为了实现这一点,方法必须是public
并接受一个View
类型作为其唯一参数。
public void study(View view) {
//Perform action on click
}
类似地,android:onClick
属性可以用于所有可用的视图子类,如TextView
、EditText
、RadioButton
、CheckBox
等。
输出屏
按钮的常用属性
以下是一些常用的Button
视图样式属性
android:gravity
:可以用来设置 app 屏幕上任意 View 的位置。可用值有右、左、中心、中心 _ 垂直等。您也可以使用|
符号一起使用到值。android:textSize
:设置按钮内部文字大小。android:background
:设置按钮的背景颜色。- 可以分别使用
android:drawableRight
、android:drawableLeft
、android:drawableTop
和android:drawableBottom
将图片添加到按钮上,与文本并排。:
安卓系统中的ImageView
和ImageButton
ImageView
和ImageButton
在安卓应用中用于在视图中放置图像。ImageButton 用于将图像用作 android 应用中的按钮。
安卓系统中的 ImageView
ImageView
用于在用户界面上显示任何图片。
以下是一些最常用的主要属性:
| 属性 | 描述 |
| android:maxHeight
| 用于指定此视图的最大高度。 |
| android:maxWidth
| 用于指定此视图的最大宽度。 |
| android:src
| 将可绘制的设置为此ImageView
的内容。 |
| android:scaleType
| 控制如何调整图像的大小或移动图像以匹配ImageView
的大小。 |
| android:tint
| 在ImageView
中淡入图像的颜色。 |
因此,我们想要在应用中显示的任何图像都应该放在可绘制文件夹下。这个文件夹可以在 app → res →可绘制下找到。要插入图像,只需复制图像,然后右键单击可绘制→粘贴。
下面是我们需要添加到布局 XML 文件中的代码,以便将 ImageView 添加到我们的应用屏幕中。
<ImageView
android:id="@+id/img"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:src="@drawable/img_nature"/>
ImageView 中还有一些常用的属性
以下是一些常用的属性:
android:background
:这个属性给你的 ImageView 一个背景色。当您的图像不能完全填充ImageView
时,背景色用于填充图像未覆盖的区域。android:padding
:在 ImageView 内部为图像提供填充或额外空间。
ImageView 中的所有scaleType
这里我们已经为属性scaleType
指定了所有可能的值,这些值可以在您的 ImageView 应用中使用:
- 居中:将图像放在中央,但不缩放。
- CENTER_CROP :均匀缩放图像。
- CENTER_INSIDE :这样会把图像放在容器里面,图像的边缘不会和容器的边缘重叠,图像会在里面。
- FIT_CENTER :从中心开始缩放图像。
- FIT_END :从容器的末端,也就是右手边开始缩放图像。
- FIT_START :从容器开始,即从左手边开始缩放图像。
- FIT_XY :这将使用图像填充整个容器。这通常会以不成比例的比例拉伸/扭曲图像。
- 矩阵:用于绘图时使用图像矩阵缩放图像。
将图像用作按钮
ImageButton
has the same property as ImageView
. Only one feature is extra, which is, images set through ImageButton are clickable, and actions can be attached with them upon clicking.
以下是如何在布局 XML 文件中定义ImageButton
:
<ImageButton
android:id="@+id/imgButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:src="@drawable/img_nature"/>
就像按钮一样,setOnClickListener()
可以用来设置点击事件的事件监听器。
imageButton = (ImageButton)findViewById(R.id.imgButton);
imageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// do anything here
}
});
安卓吐司
你是否在你使用的任何应用中遇到过如下图所示的消息格式?
这在安卓系统中被称为吐司。它用于在安卓应用中显示短消息和临时消息。所以让我们先看看它有什么特点,然后我们会弄脏我们的手,学习如何做这样的祝酒词。
吐司的特点
- 这是一个用于短时间显示消息的安卓小部件。
- 过了一会儿就消失了。
- 它不会在运行时阻止“活动”或“片段”。
- 它可以用来给用户关于任何操作的反馈,如表单提交等。
如何制作吐司?
可以使用扩展了java.lang.Object
类的android.widget.Toast
类创建吐司。
在此之前,我们继续学习如何创建吐司,让我们花一些时间探索android.widget.Toast
类。
吐司类的内容
常量 | 描述 |
---|---|
公共静态最终 int LENGTH_LONG | 这可用于长时间显示吐司。 |
公共静态最终 int LENGTH_SHORT | 这可用于长时间显示吐司。 |
常量LENGTH_LONG
为吐司设定 3.5 秒的显示持续时间,而常量LENGTH_SHORT
为吐司设定 2 秒的显示持续时间。
吐司课的方法
以下是Toast
类中可用的方法,用于创建吐司。
方法 | 描述 |
---|---|
公共静态吐司制作文本(上下文上下文,字符序列文本,int 持续时间) | 此方法使吐司小部件具有指定的文本并持续指定的时间。 |
公共作废显示() | 这个方法显示了吐司。 |
公共空隙设置边距(水平浮动,垂直浮动) | 此方法可用于设置水平和垂直边距 |
现在让我们看看如何创建一个吐司:
-
成为
Toast
类的对象。Toast t = new Toast(this);
-
调用需要三个参数的
makeText(Context c, CharSequence text, int duration)
方法。上下文 c :上下文是应用环境全局信息的接口。这是一个抽象类,其实现由 Android 系统提供。它允许访问特定于应用的资源和类,以及对应用级操作的调用,如启动活动、广播和接收意图等。我们可以通过
getApplicationContext()
方法得到这个上下文对象字符序列文本:这是吐司中显示的信息。它可以是任何文本。
int duration :这是您希望消息出现在屏幕上的持续时间。有两个值:
Toast.LENGTH_SHORT
和Toast.LENGTH_LONG
使用我们的 Toast 实例/对象,我们需要以如下方式调用
maketext()
方法:t.makeText(getApplicationContext(),"StudyTonight Toast",Toast.LENGTH_SHORT);
-
然后调用
show()
方法在屏幕上显示吐司t.show();
完整的代码将是:
Toast t = new Toast(this);
t.makeText(getApplicationContext(),"StudyTonight Toast",Toast.LENGTH_SHORT);
t.show();
将吐司放在屏幕上
默认情况下,吐司消息出现在屏幕底部的中央。如果想在其他位置显示,可以使用setGravity(int gravity, int x, int y)
方法,该方法有以下参数:
- int gravity :可以使用 gravity 类来使用像
Gravity.RIGHT
、Gravity.TOP
这样的预定义值,也可以使用管道(| ) 符号来使用多个值。例如Gravity.LEFT|Gravity.BOTTOM
- int x :可以用这个设置水平距离。从哪里开始测量该距离取决于您设置的
int gravity
参数。 - int y :你可以用这个来设置垂直距离。同样,距离的测量取决于您设置的
int gravity
参数。
例如,如果您选择了Gravity.CENTER
,您的x=100
和y=200
,那么它会将吐司放在以下位置:
显示吐司的活动类别的完整代码
package com.studytonight.toast;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Displaying Toast with 'Studytonight is Best' message
Toast.makeText(getApplicationContext(),"Studytonight is Best",Toast.LENGTH_LONG).show();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
输出屏
在安卓应用中创建自定义Snackbar
原文:https://www.studytonight.com/android/create-custom-snackbar-in-android-app
为了给用户展示一些反馈,我们可以在安卓中使用不同的方法,比如在安卓中展示一个吐司,一个小吃店,或者一个对话框等。因此在本教程中,我们将使用 Snackbar 向用户显示一些消息。
Snackbar 在很多应用中都有使用,比如 YouTube(当没有互联网连接时,YouTube 会向我们显示一条消息,让我们查看下载的内容)、google photos(当我们将任何图像上传到 Google photos 时)、Google drive(当我们想要删除一些文件时)等。这里有一个例子:
什么是小吃店?
Snackbar 是一个轻量级的小部件,我们可以用它来替代 Toast (在某些情况下,Toast 比 snackbar 更有用,但这取决于不同的项目)。Snackbar 用于在应用屏幕底部向用户显示消息。Snackbar 还包含一个可选操作按钮。
为了在我们的安卓应用中实现 Snackbar,我们将使用素材库。
Snackbar 主要有 3 个部分,如下所示:
-
文字标签:包含手机和平板的单行文字或多行文字(最多 2 行)。
-
容器:snackbar 显示在矩形容器中,默认为灰色背景。容器应该是完全不透明的,这样用户就可以看到文本标签。
-
动作按钮:这个是可选的,我们也可以用它来隐藏或者解除 snackbar。如果文本标签较长,第三行将显示动作按钮。我们必须为动作按钮和文本标签使用不同的颜色,以便用户可以区分两者。
吐司和小吃的区别
以下是吐司和小吃之间的一些主要区别:
吐司 | Snackbar |
---|---|
吐司显示在屏幕的底部中央。 | 屏幕底部还会显示 Snackbar。 |
吐司可以定制为在屏幕的任何地方显示。 | Snackbar 不能自定义为显示在屏幕的任何地方,它只显示在屏幕的底部 |
Toast 消息没有任何用于记录用户反馈的操作按钮 | Snackbar 有一个可选的操作按钮,但只支持一个操作按钮。 |
将显示一条吐司消息,直到其时间结束(吐司的持续时间变量为:Length.Long 和Length.Short ) |
用户可以通过轻扫、操作按钮或使用 Java 代码来提前取消 Snackbar。 |
如何设置 Snackbar 的持续时间?
以下是可用于设置 Snackbar 持续时间的常量:
-
LENGTH _ unlimited:无限长时间显示 Snackbar,直到被用户取消或添加另一个 Snackbar。
-
LENGTH_LONG :长时间(10 秒)显示 Snackbar。
-
LENGTH_SHORT :短时间(4 秒)显示 Snackbar。
Snackbar 的一些重要方法:
以下是一些有用的 Snackbar 方法:
方法 | 描述 |
---|---|
void dismiss() |
它会取消 Snackbar,并且不返回任何内容。 |
int getDuration() |
它返回 Snackbar 的持续时间。 |
boolean isShown() |
用于检查是否显示 Snackbar。如果 snackbar 显示给用户,它将返回真,否则返回假。 |
make() |
它用于制作 Snackbar,有 3 个参数: |
-
视角
-
字符序列或 resId
-
持续时间
语法:
make (View view, CharSequence text, int duration);
示例:
make(constraintLayout, " some text ", Snackbar.LENGTH_SHORT);
|
| setAction()
| 它用于设置 snackbar 中的操作按钮,它需要 2 个参数:
-
字符序列或
resId
-
View.OnClickListener
语法:
setAction(CharSequence text, View.OnClickListener listener);
示例:
setAction("Yes", new View.OnClickListener() {
@Override
public void onClick(View view) {
// define what to do on click
}
});
|
| setActionTextColor()
| 用于设置动作的文字颜色,只需 1 个参数:
- 颜色列表或
int
语法:
setActionTextColor(int color);
// or
setActionTextColor(ColorStateList colors);
示例:
setActionTextColor(Color.GREEN);
|
| setBackgroundTint()
| 它用于设置 Snackbar 背景的色调,它还采用 1 个参数:
int
或颜色列表
语法T2:
setBackgroundTint(int color);
// or
setBackgroundTint(ColorStateList colors);
示例:
setBackgroundTint(Color.RED);
|
| setText()
| 它用于设置 Snackbar 的文本,它也只接受一个参数:
- 字符序列或
resId
语法:
setText(CharSequence text);
// or
setText(int resId);
示例:
setText("hello world it is a simple snackbar");
|
| setTextColor()
| 它用于设置 snackbar 的文本颜色,它也只接受一个参数:
- 颜色状态列表或
int
语法:
setTextColor(int color);
// or
setTextColor(ColorStateList colors);
示例:
setTextColor(Color.BLUE);
|
| void show()
| 它用于显示 Snackbar。它不返回任何内容,也没有参数。 |
因此,我们已经了解了 Snackbar 的一些基本知识,现在是时候在我们的安卓应用中添加这个惊人的功能了。我们必须遵循一些基本步骤,在我们的应用中添加 snackbar,如下所示。
步骤 1:创建新项目
-
打开你的 AndroidStudio 点击“开始一个新的 AndroidStudio 项目”(学习如何设置 AndroidStudio创建你的第一个安卓项目)
-
从项目模板窗口中选择空活动,点击下一步。
-
输入 App 名称、包名、保存位置、语言(Java/Kotlin,本教程我们将使用 Java )以及最小 SDK (我们使用的是 API 19: Android 4.4 (KitKat))
-
填写以上详细信息后,点击完成按钮。
-
现在,等待项目完成建设。
步骤 2:添加物料依赖关系
要在我们的应用中显示工具栏,我们必须在我们的应用中实现****素材 l 库,为此,请遵循以下步骤。
转到梯度脚本- >构建.梯度(模块:应用)部分,导入下面的依赖项,点击顶部显示的“立即同步:
dependencies {
// Adding the material library to add snackBar in our app
implementation 'com.google.android.material:material:1.0.0'
}
第三步:修改活动
现在转到app->RES->layout->activity _ main . XML并添加一个 LinearLayout 方向垂直,内部 LinearLayout 我们为不同类型的 snackbar 添加了不同的按钮。现在我们的 activity_main.xml 文件将如下所示
<?xml version = "1.0" encoding = "utf-8" ?>
<androidx.constraintlayout.widget.ConstraintLayout
android:id = "@+id/constraintLayout"
xmlns:android = "http://schemas.android.com/apk/res/android"
xmlns:app = "http://schemas.android.com/apk/res-auto"
xmlns:tools = "http://schemas.android.com/tools"
android:layout_width = "match_parent"
android:layout_height = "match_parent"
tools:context = ".MainActivity">
<!-- simple linear layout containing different button -->
<LinearLayout
android:orientation = "vertical"
android:layout_width = "match_parent"
android:layout_height = "wrap_content">
<!-- button with single line snackbar -->
<Button
android:id = "@+id/snackBar1"
android:textAllCaps = "true"
android:textStyle = "bold"
android:textSize = "16dp"
android:background = "@color/colorPrimary"
android:textColor = "#ffffff"
android:text = "Simple Single Line Snackbar "
android:layout_margin = "16dp"
android:layout_width = "match_parent"
android:layout_height = "80dp"/>
<!-- button with multi line snackbar -->
<Button
android:id = "@+id/snackBar2"
android:textAllCaps = "true"
android:textStyle = "bold"
android:textSize = "16dp"
android:background = "@color/colorPrimary"
android:textColor = "#ffffff"
android:text = "Simple Multiple Line Snackbar "
android:layout_margin = "16dp"
android:layout_width = "match_parent"
android:layout_height = "80dp"/>
<!-- button with single line snackbar with action button -->
<Button
android:id = "@+id/snackBar3"
android:textAllCaps = "true"
android:textStyle = "bold"
android:textSize = "16dp"
android:background = "@color/colorPrimary"
android:textColor = "#ffffff"
android:text = "Single line Snackbar With Action Button "
android:layout_margin = "16dp"
android:layout_width = "match_parent"
android:layout_height = "80dp"/>
<!-- button with multiline snackbar with action button -->
<Button
android:id = "@+id/snackBar4"
android:textAllCaps = "true"
android:textStyle = "bold"
android:textSize = "16dp"
android:background = "@color/colorPrimary"
android:textColor = "#ffffff"
android:text = "MultiLine line Snackbar With Action Button "
android:layout_margin = "16dp"
android:layout_width = "match_parent"
android:layout_height = "80dp"/>
<!-- button with custom snackbar with action button -->
<Button
android:id = "@+id/snackBar5"
android:textAllCaps = "true"
android:textStyle = "bold"
android:textSize = "16dp"
android:background = "@color/colorPrimary"
android:textColor = "#ffffff"
android:text = "Custom Snackbar With Action Button"
android:layout_margin = "16dp"
android:layout_width = "match_parent"
android:layout_height = "80dp"/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
现在,我们的应用界面将如下所示:
第四步:MainActivity.java 文件
这是我们 app 中添加 snackbar 的主要部分,首先我们打开MainActivity.java文件,导入一些基础类,如下图:
//import the basic library
import com.google.android.material.snackbar.Snackbar;
import android.graphics.Color;
import android.os.Bundle ;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
接下来,我们在 MainActivity 类中创建 Android 按钮 的对象,如下所示:
//creating 5 different object of Button class
private Button b1, b2, b3, b4, b5;
现在我们创建不同的方法来显示不同类型和风格的 Snackbar ,如下图:
private void showSnackBarSingleLine() {
ConstraintLayout constraintLayout = (ConstraintLayout) findViewById(R.id.constraintLayout);
Snackbar snackbar = Snackbar.make(constraintLayout, "SnackBar Single Line", Snackbar.LENGTH_SHORT);
snackbar.show();
}
private void showSnackBarMultipleLine() {
ConstraintLayout constraintLayout = (ConstraintLayout) findViewById(R.id.constraintLayout);
Snackbar snackbar = Snackbar.make(constraintLayout, "SnackBar Multiple Line with some text so that the example is completed ", Snackbar.LENGTH_SHORT);
snackbar.show();
}
private void showSnackBarSingleLineWithActionButton() {
ConstraintLayout constraintLayout = (ConstraintLayout) findViewById(R.id.constraintLayout);
Snackbar snackbar = Snackbar.make(constraintLayout, "Want to delete file", Snackbar.LENGTH_SHORT);
snackbar.setAction("Yes", new View.OnClickListener() {@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this, "Your file is deleted ", Toast.LENGTH_SHORT).show();
}
});
snackbar.show();
}
private void showSnackBarMultipleLineWithActionButton() {
ConstraintLayout constraintLayout = (ConstraintLayout) findViewById(R.id.constraintLayout);
Snackbar snackbar = Snackbar.make(constraintLayout, "Are you sure Wanted to delete the file , it is a simple multiple line snackBar ", Snackbar.LENGTH_SHORT);
snackbar.setAction("Yes", new View.OnClickListener() {@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this, "Your file is deleted ", Toast.LENGTH_SHORT).show();
}
});
snackbar.show();
}
private void showCustomSnackBar() {
ConstraintLayout constraintLayout = (ConstraintLayout) findViewById(R.id.constraintLayout);
Snackbar snackbar = Snackbar.make(constraintLayout, "You are not connected to internet ", Snackbar.LENGTH_LONG).setAction("RETRY", new View.OnClickListener() {@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this, "Waiting for connection ", Toast.LENGTH_SHORT).show();
}
});
//setting action text color o red
snackbar.setActionTextColor(Color.RED);
View sbView = snackbar.getView();
//getting the textview of the snackbar
TextView textView = (TextView) sbView.findViewById(com.google.android.material.R.id.snackbar_text);
//setting snackbar text color to green
textView.setTextColor(Color.GREEN);
snackbar.show();
}
现在在onCreate()
方法中,我们初始化按钮并添加 OnClick Listener 并调用onClick()
中相应的方法:
b1 = (Button) findViewById(R.id.snackBar1);
b2 = (Button) findViewById(R.id.snackBar2);
b3 = (Button) findViewById(R.id.snackBar3);
b4 = (Button) findViewById(R.id.snackBar4);
b5 = (Button) findViewById(R.id.snackBar5);
b1.setOnClickListener(new View.OnClickListener() {@Override
public void onClick(View view) {
showSnackBarSingleLine();
}
});
b2.setOnClickListener(new View.OnClickListener() {@Override
public void onClick(View view) {
showSnackBarMultipleLine();
}
});
b3.setOnClickListener(new View.OnClickListener() {@Override
public void onClick(View view) {
showSnackBarSingleLineWithActionButton();
}
});
b4.setOnClickListener(new View.OnClickListener() {@Override
public void onClick(View view) {
showSnackBarMultipleLineWithActionButton();
}
});
b5.setOnClickListener(new View.OnClickListener() {@Override
public void onClick(View view) {
showCustomSnackBar();
}
});
一旦您在您的主活动中添加了所有上述代码,我们就可以运行我们的应用了。
Snackbar 的输出屏幕:
在下面的快照中,您可以看到 SnackBar 在安卓应用中的外观。
简单单线蛇形线:
简单多线 Snackbar:
带动作按钮的简单单线 Snackbar:
带动作按钮的简单多线 Snackbar:
带操作按钮的自定义 Snackbar:
在本教程中,我们学习了如何使用素材库向我们的安卓应用添加 Snackbar。我们学习了如何编写代码在安卓应用中显示 Snackbar,以及如何在其中添加各种功能。
安卓切换开关按钮
原文:https://www.studytonight.com/android/android-toggle-switch-button
在各种安卓应用中,我们看到了不同类型的开关,比如 YouTube(切换到自动播放下一个视频)、Truecaller(切换到启用暗主题、阻止通话、通话录音开关等。),在脸书设置,Gmail,WhatsApp(为安全启用指纹锁定)和许多其他应用。
什么是开关?
在 AndroidStudio开关是一个双态切换开关小部件,可以用来在两个选项之间进行选择。它主要用于显示选项的开和关状态,对于用户来说,它看起来像一个简单的滑块控件。用户可以前后拖动“拇指”来选择所选选项,或者我们可以简单地点击来切换开关的状态。
常用于选择开/关热点、手电筒、WiFi 等。是android.widget.CompoundButton
类的子类。
开关在功能上类似于一个切换按钮,但两者都有一些区别,比如开关有一个蜘蛛来控制开关的状态,开关和切换按钮的用户界面都不一样。
现在我们已经对 switch 有了足够的了解,让我们在安卓应用中添加一个 switch。
步骤 1:创建新项目
-
打开你的 AndroidStudio 点击“开始一个新的 AndroidStudio 项目”(学习如何设置 AndroidStudio创建你的第一个安卓项目)
-
从项目模板窗口中选择空活动,点击下一步。
-
输入 App 名称、包名、保存位置、语言(Java/Kotlin,本教程我们将使用 Java )以及最小 SDK (我们使用的是 API 19: Android 4.4 (KitKat))
-
填写以上详细信息后,点击完成按钮。
-
现在,等待项目完成建设。
第二步:添加切换到安卓活动
现在转到 app - > res - >布局- > activity_main.xml 并添加 Switch ,现在我们的 activity_main.xml 文件将如下所示:
<?xml version = "1.0" encoding = "utf-8" ?>
<RelativeLayout
android:id = "@+id/constraintLayout"
xmlns:android = "http://schemas.android.com/apk/res/android"
xmlns:app = "http://schemas.android.com/apk/res-auto"
xmlns:tools = "http://schemas.android.com/tools"
android:layout_width = "match_parent"
android:layout_height = "match_parent"
tools:context = ".MainActivity">
<Switch
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"/>
</RelativeLayout>
在上面的代码中,我们在我们的安卓活动中添加了默认的切换开关。
交换机的属性示例:
让我们更多地了解 switch 的属性,以及如何在安卓应用中使用它们来定制 Switch。
1.属性标识:
它用于为交换机设置一个唯一 id ,通过它我们可以识别一个特定的交换机,这意味着不同的交换机有不同的 id。
<Switch
android:id = "@+id/mySwitchId"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"/>
2.选中的属性:
该属性用于设置开关的当前状态。该值可以是真或假,勾选属性的默认值为假。当我们设置checked="true"
时,开关默认为选中,当我们设置为假时,开关变为未选中。
<Switch
android:checked = "true"
android:id = "@+id/mySwitchId"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"/>
我们也可以使用setChecked(Boolean b)
功能在 Java 代码中更改开关的选中状态,其中b
可以是真也可以是假,如下图所示:
Switch sw = (Switch) findViewById(R.id.mySwitchId);
sw.setChecked(true);
sw.setChecked(false);
3.文本属性:
它用于设置开关的文本。我们可以直接设置文本,如下所示:
<Switch
android:text = "Dark Mode"
android:id = "@+id/mySwitchDarkMode"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"/>
或者我们也可以使用如下所示的setText(CharcaterSwequence cs)
函数在 Java 代码中动态更改文本:
Switch swdark = ( Switch ) findViewById( R.id.mySwitchDarkMode );
swdark.setText( "Dark Mode" );
4.重力属性:
它用于在开关中设置文本的重力。默认值为左侧。重力的数值有很多,如右、左、中心、中心 _ 水平、顶部、底部、中心 _ 垂直、夹 _ 水平、夹 _ 垂直、末端、填充、等要查看重力的影响,我们必须设置android:layout_width = "match_parent"
<Switch
android:gravity = "right"
android:text = "Gravity Right"
android:id = "@+id/mySwitchGravity"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"/>
我们也可以使用如下所示的setGravity(int gravity)
函数在运行时改变 Java 代码中的文本重力:
Switch swgravity = ( Switch ) findViewById( R.id.mySwitchGravity );
swgravity.setGravity( Gravity.RIGHT );
5.文本开和文本关属性:
文本开属性用于设置开关处于选中状态时我们想要显示的文本(表示处于打开状态)文本关属性用于设置开关处于未选中状态时我们想要显示的文本(表示处于关闭状态),如下图所示。为了显示文本关闭和文本打开文本,我们设置了showText = "true"
<Switch
android:textOff = "Disable"
android:textOn = "Enable"
android:text = "System Sound"
android:id = "@+id/mySwitchTextOnOff"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:showText = "true"/>
我们还可以使用如下所示的setTextOn(CharSeqence texton)
和setTextOff(CharSeqence textoff)
函数来更改 Java 代码中的文本开和文本关值:
Switch swOnOff = ( Switch ) findViewById( R.id.mySwitchTextOnOff );
swOnOff.setTextOn( "Enabled" );
swOnOff.setTextOff( "Disabled" );
输出为
输出为
6.文本颜色属性:
它用于设置开关的文本颜色。颜色值可以是任何一种形式的" #argb "、" #rgb "、" #rrggbb "或" # aarrggbb "。
<Switch
android:textColor = "#FF0000"
android:text = "Color text Switch"
android:id = "@+id/mySwitchTextColor"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"/>
我们也可以在 Java 代码中使用如下所示的void setTextColor(int color)
或void setTextColor(ColorStateList colors)
函数做同样的事情:
Switch swtxtColor = ( Switch ) findViewById( R.id.mySwitchTextColor );
swtxtColor.setTextColor(Color.RED);
7.文本大小属性:
该属性用于设置开关文本的大小。我们可以在 dp 、中、 mm 、 pt 、 px 、 sp 中用 XML 设置尺寸。在下面的示例中,我们将文本大小设置为 32 dp :
<Switch
android:textSize = "32dp"
android:text = " Text Size Switch"
android:id = "@+id/mySwitchTextSize"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"/>
我们可以使用void setTextSize(float size)
和void setTextSize(int unit, float size)
函数从 Java 代码中更改文本大小:
Switch swtxtSize = ( Switch ) findViewById( R.id.mySwitchTextSize );
swtxtSize.setTextSize( 32 );
8.文本样式属性:
它用于设置开关文本的文本样式。安卓系统提供的 3 种文本样式分别是粗体、普通和斜体。默认的文本样式是普通的,如果我们想要使用多个文本样式,那么我们可以在不同的样式之间使用**|**
(管道)操作符,例如粗体|斜体。
<Switch
android:textStyle = "bold"
android:text = " Text Style Switch"
android:id = "@+id/mySwitchTextStyle"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"/>
我们也可以使用如下所示的void setTypeface( Typeface tf)
和void setTypeface( Typeface typeface, int style )
函数来改变 Java 代码的文本样式:
Switch swtxtStyle = ( Switch ) findViewById( R.id.mySwitchTextStyle );
swtxtStyle.setTypeface( Typeface.DEFAULT_BOLD );
9.背景属性:
用于设置开关的背景。它可以是颜色或可绘制(图像)或任何自定义 xml 文件。在本教程中,我们将添加一个简单的红色背景:
<Switch
android:background = "#FF0000"
android:text = " Switch With Background"
android:id = "@+id/mySwitchBackground"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"/>
我们也可以使用void setBackgroundColor( int color)
函数从 Java 代码中设置背景:
Switch swBackground = ( Switch ) findViewById( R.id.mySwitchBackground );
swBackground.setBackgroundColor( Color.RED);
10.填充属性:
它用于设置开关的填充。我们可以使用padding
属性一次性设置上、下、左、右填充,也可以使用paddingLeft
、paddingRight
、paddingTop
和paddingBottom
属性为上、下、左、右添加不同的填充。
<Switch
android:paddingLeft = "12dp"
android:paddingBottom = "10dp"
android:paddingTop = "14dp"
android:paddingRight = "6dp"
android:padding = "16dp"
android:text = " Switch With Padding"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"/>
我们也可以使用如下所示的void setPadding( int left, int top, int right, int bottom )
函数从 Java 代码中添加填充:
Switch swPadding = ( Switch ) findViewById( R.id.mySwitchPadding );
swPadding.setPadding(12,14,6,10 );
交换机中的不同监听器:
现在让我们介绍一下事件或点击监听器功能,这些功能可用于捕捉用户点击切换开关并执行一些操作。
1.使用 setOnClickListener(OnClickListener l)侦听器:
当我们想要检查开关是否被点击并根据点击做出决定时,我们可以使用这个监听器。在public void onClick(View view)
功能中,会检查开关是否勾选使用boolean isChecked()
功能,并根据开关状态向用户显示吐司,如下图:
final Switch aSwitch = (Switch) findViewById(R.id.mySwitchListener);
aSwitch.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view) {
if (aSwitch.isChecked()) //checking if switch is checked
{
Toast.makeText(MainActivity.this, "Switch is Turned On using click listener ", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "Switch is Turned Off using click listener", Toast.LENGTH_SHORT).show();
}
}
});
以下是输出屏幕:
2.使用 setnchckedchangelistener(onchecedchangelistener l)监听器:
当开关状态改变时,该监听器被调用,这意味着当我们将开关从关闭状态切换到开启状态时,反之亦然。与 onClickListener 的主要区别在于,这仅在状态改变时调用,但是 onClickListener 在我们每次点击开关时都会被调用。
在 onCheckedChangeListener 中,我们有一个onCheckedChanged(CompoundButton compoundButton, boolean b)
,我们可以使用布尔值来检查开关的状态,并根据布尔值执行功能:
aSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b) //checking if the user turned on the switch
{
Toast.makeText(MainActivity.this, "Switch is Turned On using on checked changed", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "Switch is Turned Off using on checked changed", Toast.LENGTH_SHORT).show();
}
}
});
以下是输出屏幕:
根据我们的需要,还有许多其他的听众可以使用。这 2 个监听器是最基本的,任何项目都可以用这些监听器完成,没有任何问题。
使用视图和布局
安卓RecyclerView
原文:https://www.studytonight.com/android/android-recycler-view
在本文中,我们将把 Recycler View 添加到我们的安卓应用中。为此,我们使用回收商视图。回收机视图是 AndroidStudio 的一个视图,和 Listview 类似,但是控件和功能更多。那么,让我们创建一个项目。
步骤 1:创建新项目
-
打开你的 AndroidStudio 点击“”开始新的 AndroidStudio 项目”(学习如何设置 AndroidStudio、创建你的第一个安卓项目)。
-
从项目模板窗口中选择“空活动,点击下一步。
-
输入 App 名称、包名、保存位置、语言(Java/Kotlin,本教程我们使用 Java )和最小 SDK (我们使用的是 API 19: Android 4.4 (KitKat))。
-
填写完所有细节后,点击完成按钮,
-
现在,等待项目完成建设。
步骤 2:添加依赖项
转到梯度脚本- >构建.梯度(模块:应用)部分,导入下面的依赖项,点击顶部显示的“立即同步:
dependencies
{
//Adding Recycler view
implementation 'androidx.recyclerview:recyclerview:1.2.1'
}
第三步:用户界面部分
在对 activity_main.xml 文件进行任何更改之前,我们需要一个将在RecyclerView
中显示的图像和文本,您可以下载任何图像,并将该图像放入app->RES->drawing able,中,并给它一个合适的名称。
现在,转到 app - > res - >布局- > activity_main.xml 并添加recycle view,如下所示。
<?xml version = "1.0" encoding = "utf-8"?>
<RelativeLayout
xmlns:android = "http://schemas.android.com/apk/res/android"
xmlns:tools = "http://schemas.android.com/tools"
android:layout_width = "match_parent"
android:layout_height = "match_parent"
tools:context = ".MainActivity">
<!-- Recycler view -->
<androidx.recyclerview.widget.RecyclerView
android:id = "@+id/recycleView"
android:layout_width = "match_parent"
android:layout_height = "match_parent"/>
</RelativeLayout>
接下来,我们在其中创建一个新的布局资源文件(recycle view _ row . XML),我们添加一个简单的 ImageView 和 TextView 集合。recycle view _ row . XML的完整代码如下
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeightLarge"
android:id="@+id/relativeLayout">
<ImageView
android:padding="4dp"
android:layout_centerVertical="true"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:contentDescription="Icon" />
<TextView
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="@+id/textView"
android:layout_toEndOf="@id/imageView"
android:gravity="center_vertical"
android:textSize="24sp"/>
</RelativeLayout>
第 4 步:编码部分
首先,我们创建一个MyData.java类,并添加如下所示的代码。
package com.studytonight.project;
public class MyData {
private String desc;
private int imgId;
public MyData(String desc, int imgId) {
this.desc = desc;
this.imgId = imgId;
}
public String getDescription() {
return desc;
}
public int getImgId() {
return imgId;
}
}
然后,我们创建一个新的RecyclerViewAdapter.java类,将其扩展到回收视图。适配器<再循环适配器。viewpholder>并实现了它的一些方法,如下所示。
package com.studytonight.project;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.recyclerview.widget.RecyclerView;
public class RecyclerViewAdapter extends RecyclerView.Adapter < RecyclerViewAdapter.ViewHolder > {
private MyData[] mydata;
// RecyclerView recyclerView;
public RecyclerViewAdapter(MyData[] mydata) {
this.mydata = mydata;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View listItem = layoutInflater.inflate(R.layout.recyclerview_row, parent, false);
ViewHolder viewHolder = new ViewHolder(listItem);
return viewHolder;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
final MyData MyData = mydata[position];
holder.textView.setText(mydata[position].getDescription());
holder.imageView.setImageResource(mydata[position].getImgId());
holder.relativeLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(view.getContext(), "click on item: " + MyData.getDescription(), Toast.LENGTH_LONG).show();
}
});
}
@Override
public int getItemCount() {
return mydata.length;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public ImageView imageView;
public TextView textView;
public RelativeLayout relativeLayout;
public ViewHolder(View itemView) {
super(itemView);
this.imageView = (ImageView) itemView.findViewById(R.id.imageView);
this.textView = (TextView) itemView.findViewById(R.id.textView);
relativeLayout = (RelativeLayout) itemView.findViewById(R.id.relativeLayout);
}
}
}
最后,我们将数据添加到RecyclerView
中,并显示给用户。MainActivity.java的完整代码如下:
package com.studytonight.project;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyData[] myListData = new MyData[]{
new MyData("Upload", R.drawable.u1),
new MyData("Chart", R.drawable.u2),
new MyData("Wifi", R.drawable.u3),
new MyData("Clock", R.drawable.u4),
new MyData("Video", R.drawable.u5),
new MyData("Share", R.drawable.u6),
new MyData("Download", R.drawable.u7),
new MyData("Torch", R.drawable.u8),
new MyData("Delete", R.drawable.u9),
new MyData("Phone", R.drawable.u10),
new MyData("Bluetooth", R.drawable.u11),
new MyData("Processor", R.drawable.u12),
};
RecyclerView recyclerViewOKL = (RecyclerView) findViewById(R.id.recycleView);
RecyclerViewAdapter adapter = new RecyclerViewAdapter(myListData);
recyclerViewOKL.setHasFixedSize(true);
recyclerViewOKL.setLayoutManager(new LinearLayoutManager(MainActivity.this));
recyclerViewOKL.setAdapter(adapter);
}
}
输出:
在下面的快照中,您可以看到 Recycler View 在安卓应用中的外观。
首次打开应用时:
当我们向下滚动时
当我们点击项目时
适配器和AdapterView
原文:https://www.studytonight.com/android/adapter-and-adapter-view
适配器和AdapterView
非常受欢迎,以至于每次您看到任何带有项目列表或项目网格的应用,您都可以肯定地说它正在使用适配器和AdapterView
。
通常,当我们创建任何数据列表或网格时,我们认为我们可以使用循环来迭代数据,然后设置数据来创建列表或网格。
但是如果数据是一组 100 万个产品呢。那么使用循环不仅会消耗大量时间,使应用变慢,而且可能会耗尽所有运行时内存。
所有这些问题都可以通过使用适配器和AdapterView
来解决。
Adapter View,是一个View
对象,可以像我们使用任何其他界面小部件一样使用。这里唯一的问题是,它需要一个Adapter
来提供内容,因为它不能自己显示数据。
什么是适配器?
适配器就像数据源和用户界面之间的桥梁。它从各种数据源读取数据,将其转换为视图对象,并将其提供给链接的AdapterView
以创建用户界面组件。
数据源或数据集可以是数组对象、列表对象等。
您可以通过扩展BaseAdapter
类来创建自己的适配器类,该类是所有其他适配器类的父类。安卓 SDK 也提供了一些现成的适配器类,比如ArrayAdapter
、SimpleAdapter
等。
什么是AdapterView
?
AdapterView
可以用来以列表或网格等形式有效地显示由适配器提供给它的大数据集。
当我们高效地说时,我们指的是什么?
**AdapterView
能够在用户界面上显示数百万个项目,同时保持内存和 CPU 使用率非常低,并且没有任何明显的延迟。不同的适配器遵循不同的策略,但安卓 SDK 中提供的默认适配器遵循以下技巧:
- 它只渲染那些当前在屏幕上或即将出现在屏幕上的
View
对象。因此,无论数据集有多大,AdapterView
总是一次只加载 5、6 或 7 个项目,这取决于显示大小。从而节省内存。 - 它还可以在用户滚动时重用已经创建的布局来填充数据项,从而节省了 CPU 的使用。
假设您有一个数据集,如包含以下内容的字符串数组。
String days[] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
现在,适配器所做的是从这个数组中获取数据,并根据这些数据创建一个视图,然后,它将这个视图提供给一个AdapterView
。然后,AdapterView
以您想要的方式显示数据。
注意:适配器只负责从数据源获取数据,并将其转换为 View,然后将其传递给 AdapterView。因此,它用于管理数据。AdapterView 负责显示数据。
因此,您可以从数据库或ArrayList
或任何其他数据源中获取数据,然后以任何排列显示该数据。您可以垂直显示( ListView
)、或按行和列显示( GridView
)、或在下拉菜单中显示( Spinners
)等。
有不同类型的AdapterView
。让我们来看看其中的一些:
ListView
它显示一个可垂直滚动的视图集合,其中每个视图都位于列表中前一个视图的正下方。
显示数据表格(一种控件)
GridView 是一个视图组,它在一个二维的、可滚动的网格中显示项目。
纺纱机
Spinner
提供了从一组值中选择一个值的快速方法。触摸Spinner
会显示一个包含所有其他可用值的下拉菜单,用户可以从中选择一个新值。
每个AdapterView
都使用某种方法来使用适配器。我们将在各自的 AdapterView 教程中讨论这种方法。
安卓系统中的ListView
当您必须在垂直滚动列表中显示项目时,使用ListView
。最好的例子就是我们设备的联系人列表。使用ListView
,用户可以轻松浏览信息,同时上下滚动。你可以根据你的用户界面设计来设置每一个项目之间的分隔线以及它的高度和颜色。
在ListView
中,我们可以使用TextView
显示文本项目列表,或者使用ImageView
显示图片,或者任何其他视图或视图组合。
由于ListView
一般用于显示大量数据,因此无法为完整数据手动创建列表项,因此安卓为我们提供了特殊的Adapter
类,可用于将数据集的数据提供给ListView
。
以下是一些最常用的主要属性:
| 属性 | 描述 |
| android:divider
| 使用这个属性,我们可以在列表项之间指定一个分隔符。可绘制或任何颜色都可以指定为该属性的值。 |
| android:dividerHeight
| 用于指定分隔线的高度。 |
下面我们展示了如何使用布局 XML 将ListView
添加到您的安卓应用中。
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@android:color/black"
android:dividerHeight="1dp"/>
输出屏
使用带ListView
的适配器
让我们看看如何使用适配器从数组中读取数据,并以列表的形式显示它。
我们将在主布局 XML 文件 activity_main.xml 中定义一个 ListView。
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFEB3B"
tools:context="com.example.android.studytonightandroid.MainActivity">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@android:color/black"
android:dividerHeight="1dp"/>
</android.support.constraint.ConstraintLayout>
通过这样做,我们已经定义了一个要在主活动中创建的ListView
,但是它会显示什么数据呢?什么格式?我们将在哪里声明和定义它?
正如我们在上一个教程中所指定的,适配器用于将数据项转换成视图对象,视图对象可用于显示为用户界面组件。
所以我们需要一个数据集和一个视图,这个数据集将被适配器转换成这个视图。
这里我们有一个简单的数组,其中包含节日名称:
String[] festivals = {
"Diwali",
"Holi",
"Christmas",
"Eid",
"Baisakhi",
"Halloween"
};
由于我们的数据集有简单的文本值,所以我们可以定义一个简单的TextView
来保存这些值并填充ListView
。这听起来令人困惑吗?让它陷进去。
如果我们的数据集有图像和一些文本,那么我们也可以定义一个TextView
和一个ImageView
来显示列表中的数据。
所以现在我们将创建一个新的 XML 文件,在布局文件夹中命名为 list_item.xml ,并在其中添加一个TextView
,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:padding="4dp"
android:textColor="#000000"
/>
现在是大结局的时候了,下面我们有MainActivity.java
类,其中我们使用了ArrayAdapter
从数组中的数据创建TextView
,并通过将这些视图对象提供给ListView
来创建一个列表。
package listview.studytonightexample.com.listview;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
ListView listView;
TextView textView;
String[] festivals = {
"Diwali",
"Holi",
"Christmas",
"Eid",
"Baisakhi",
"Halloween"
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView)findViewById(R.id.listView);
textView = (TextView)findViewById(R.id.textView);
final ArrayAdapter <string>adapter = new ArrayAdapter<string>(this,
R.layout.list_item, android.R.id.textView, festivals);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
// TODO Auto-generated method stub
/* appending Happy with festival name */
String value = "Happy " + adapter.getItem(position);
/* Display the Toast */
Toast.makeText(getApplicationContext(), value, Toast.LENGTH_SHORT).show();
}
});
}
}</string></string>
输出屏
安卓系统中的GridView
GridView
就像ListView
一样工作,这一点我们在上一期教程中详细了解过。唯一的区别是GridView
用于显示视图对象的网格。
视图对象可以是TextView
、ImageView
或既有图像又有一些文本的视图组。这个视图最好的例子是在网格中显示图像的手机图库。我们可以将列的数量设置为特定的数量,并将图像自动匹配到列中。
gridView 每一个单项之间的垂直和水平间距可以通过verticalSpacing
和horizontalSpacing
设置。
<GridView
android:id="@+id/gridView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:verticalSpacing="2dp"
android:horizontalSpacing="2dp"
android:numColumns="2"/>
将适配器用于 GridView
在上一个教程中,我们解释了适配器如何将数据集转换为视图对象,然后在AdapterView
中填充这些对象以创建用户界面组件。现在我们的AdapterView
是GridView
。详细说明可以参考上一篇教程。
我们将在主布局 XML 文件 activity_main.xml 中定义一个 ListView。
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFEB3B"
tools:context="com.example.android.studytonightandroid.MainActivity">
<GridView
android:id="@+id/gridView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:numColumns="2"/>
</android.support.constraint.ConstraintLayout>
为此,让我们来看看一些令人惊叹的汽车品牌。
String[] carBrands = {
"Ferrari",
"McLaren",
"Jaguar",
"Skoda",
"Suzuki",
"Hyundai",
"Toyota",
"Renault",
"Mercedes",
"BMW",
"Ford",
"Honda",
"Chevrolet",
"Volkswagon",
};
由于我们的网格只有文本值,因此我们必须定义一个 TextView
。
所以现在我们将创建一个新的 XML 文件,在布局文件夹中命名为 grid_item.xml ,并在其中添加一个TextView
,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:padding="4dp"
android:textColor="#000000"
/>
而MainActivity.java文件将如下所示:
package listview.studytonightexample.com.listview;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
GridView gridView;
TextView textView;
String[] carBrands = {
"Ferrari",
"McLaren",
"Jaguar",
"Skoda",
"Suzuki",
"Hyundai",
"Toyota",
"Renault",
"Mercedes",
"BMW",
"Ford",
"Honda",
"Chevrolet",
"Volkswagon",
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridView = (GridView)findViewById(R.id.gridView);
textView = (TextView)findViewById(R.id.textView);
final ArrayAdapter <string>adapter = new ArrayAdapter<string>(this,
android.R.layout.grid_item, android.R.id.textView, carBrands);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
// TODO Auto-generated method stub
/* appending I Love with car brand names */
String value = "I Love " + adapter.getItem(position);
/* Display the Toast */
Toast.makeText(getApplicationContext(), value, Toast.LENGTH_SHORT).show();
}
});
}
}</string></string>
输出屏
安卓系统中的Spinner
在本教程中,我们将学习和探索安卓系统中的 Spinner。让我们从理解什么是Spinner
开始。
Spinner
是一种视图类型,以下拉菜单的形式保存项目,供用户选择。它创建了一个带有多个选项的菜单,用户可以在其中选择任何一个选项。下面是一个Spinner
的示例。
我们可以通过向布局 XML 文件添加以下代码来创建一个 Spinner:
<Spinner
android:id="@+id/days_spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
Spinner 和 ListView 有什么区别?
ListView
和Spinner
看起来非常相似。但是它们彼此不同。
Spinner
提供了从给定的一组值中选择一个值的快速方法,在默认状态下,Spinner
仅显示当前选定的值。当您触摸(点击)Spinner
时,它会显示一个包含所有其他可用值(选项)的下拉菜单,用户可以从中选择一个新值。
ListView 则是一个显示可滚动项目列表的视图组。使用适配器将列表项自动插入到列表中,该适配器从数据源(如数组或数据库表)提取内容,并将每个数据项转换为放置在列表中的视图。
因此,Spinner 和 ListView 在显示方式和用法上也有所不同。如果您想从一组选项中只选择一个值,那么您应该使用Spinner
。如果要显示数据列表,请使用ListView
。
Spinner
是如何工作的?
-
Define the data source
应该有一个用于在
Spinner
中显示数据的数据源。String days[] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
数据源可以是列表、数组、JSON 数据或来自数据库的数据。
-
Define the Adapter
将有一个适配器 (ArrayAdapter 等)从数据源获取数据,创建一个视图,然后将其传递给
AdapterView
,即Spinner
。因此,您需要告诉适配器如何通过为下拉列表指定布局来显示数据。ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, days);
有 3 个参数用于实例化 ArrayAdapter(我们在示例中使用了 ArrayAdapter):
- 上下文 c :指当前正在实例化 ArrayAdapter 的类对象。
- 布局:这是一个布局文件,定义了单个项目在
Spinner
中的显示方式。安卓 SDK 默认提供simple_spinner_item
、simple_spinner_dropdown_item
这样的布局,如果你没有什么特殊的设计要求,我们建议你只用这些。 - 数据源:是将数据转换为视图的数据源。
-
Define any actions for Spinner
要为选项选择添加事件处理程序,您可以实现OnemSelected Listener界面,以确定当用户从菜单中选择任何选项时会发生什么。为此,您需要实现上述接口并重写两个方法:
未选中()
该方法有 4 个参数:
- AdapterView av :您使用的是 Spinner 视图。
- 视图 v :它定义了被点击的
Spinner
内部的TextView
。 - int 位置:告知在
Spinner
中点击的项目的位置。索引或位置从 0 开始。 - 长 id :给出在
Spinner
中点击的项目的行 id。该参数主要用于安卓系统中处理数据库时。
onNothingSelected()
此方法只有一个参数:
AdapterView av :您使用的是 Spinner 视图。只要当前选定的项目从
Spinner
的可用项目列表中移除,就会调用此方法。如果适配器被修改,使得当前选定的项不再可用,则将调用此方法。可以使用此方法,以便您可以设置在前一个项目不再可用时将选择哪个项目。这将阻止Spinner
自动选择列表中的下一项。如果
mySpinner
是一个 Spinner 视图的实例,那么下面是我们如何实现上面的监听器:mySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { // An item was selected. You can retrieve the selected item using // parent.getItemAtPosition(pos) } @Override public void onNothingSelected(AdapterView<?> parent) { // If an option is removed then what to do // or anything else } });
我们希望您已经了解了什么是 Spinners 以及如何实现它们。在下一个教程中,我们将看到如何在我们的安卓应用中创建一个Spinner
。
在安卓系统中使用Spinner
原文:https://www.studytonight.com/android/spinner-example-in-android
你已经学习了什么是Spinner
以及它们是如何工作的。因此,让我们检查一个例子,并了解如何在我们的安卓应用中实现它。
在本教程中,我们将创建一个应用,它与两个依赖于 inder 的 Spinners 一起工作。应用的主布局将包含我们的一个TextView
和两个Spinner
作为其子组件视图。因此,我们需要定制布局(如下图所示),其中一个Spinner
位于TextView
下方,另一个Spinner
位于第一个Spinner
下方。
由于第二个Spinner
中的选项将取决于我们在第一个Spinner
中选择的内容,因此最初第二个Spinner
将被隐藏,并且只有当用户从第一个Spinner
中选择了一个选项时才会出现。
第二个Spinner
的属性isVisible
等于go,这意味着它存在于布局中,但不可见(或隐藏)。
因此,在下图中,它看起来好像不存在。但是你可以试着把 isVisible 的值改成VISIBLE
看看有没有。但之后暂时改回GONE
。
第一个Spinner
(classSpinner
)包含用户要选择的课程列表(在学校中),基于该选择,我们将值分配给第二个Spinner
(divSpinner
)。当用户也从第二个Spinner
中选择一个选项时,我们将创建一个吐司并在屏幕上显示所选的值。
让我们开始吧,这里有布局 XML 文件。如果需要,复制并粘贴下面的 XML,以便在您的本地计算机上开始这个示例。
main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.akshay.studytonightandroid.MainActivity">
<TextView
android:id="@+id/tvDemo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:gravity="center"
android:text="SPINNER DEMO"
android:layout_alignParentLeft="true" />
<Spinner
android:id="@+id/classSpinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/tvDemo"
android:layout_marginTop="25dp"
android:entries="@array/items_class"/>
<Spinner
android:id="@+id/divSpinner"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/classSpinner"
android:layout_toLeftOf="@id/classSpinner"
android:layout_marginTop="10dp"
/>
</RelativeLayout>
注意:如果您在这方面出现错误,那是因为您还没有创建下面的数据 XML 文件。一旦您创建了它,这个文件中的错误就会被解决。
如您所见,我们在 xml 文件中有一个 TextView 和两个 Spinner 视图,并指定了一些属性。
要将项目添加到Spinner
,有两种可能的方法为其提供一组选项。一种是声明一个数组并定义其中的项。但是对于这个例子,我们将尝试另一种方法,即使用一个 XML。
我们可以用 XML 定义一个字符串数组,就像下面在 strings.xml 文件中显示的那样。在安卓系统中,我们必须将数据 XML 文件像我们的 strings.xml 文件一样放在应用→ res → values → strings.xml 中。
strings.xml
<resources>
<string name="app_name">StudytonightAndroid</string>
<string-array name="items_class">
<**item**>Class 1</**item**>
<**item**>Class 2</**item**>
<**item**>Class 3</**item**>
<**item**>Class 4</**item**>
</string-array>
<string-array name="items_div_class_1">
<**item**>Div 1-A</**item**>
<**item**>Div 1-B</**item**>
<**item**>Div 1-C</**item**>
<**item**>Div 1-D</**item**>
</string-array>
<string-array name="items_div_class_2">
<**item**>Div 2-A</**item**>
<**item**>Div 2-B</**item**>
<**item**>Div 2-C</**item**>
<**item**>Div 2-D</**item**>
</string-array>
<string-array name="items_div_class_3">
<**item**>Div 3-A</**item**>
<**item**>Div 3-B</**item**>
<**item**>Div 3-C</**item**>
<**item**>Div 3-D</**item**>
</string-array>
<string-array name="items_div_class_4">
<**item**>Div 4-A</**item**>
<**item**>Div 4-B</**item**>
<**item**>Div 4-C</**item**>
<**item**>Div 4-D</**item**>
</string-array>
</resources>
到目前为止,我们已经完成了以下工作:
- 我们已经理解了我们在安卓应用中创建的设计,它将有 1 个
TextView
和 2 个Spinner
。 - 我们已经为用户界面定义了布局 XML。
- 我们还为 Spinners 定义了数据集。
在我们的数据集中,名为项目类的string-array
将被分配给classSpinner
以在下拉列表中显示类项目。
要将这些条目添加到Spinner
中,我们所要做的就是在主活动布局 XML 文件中添加一个属性android:entries="@array/items_class"
。这样做将把items_class
数组中的值分配给类Spinner
。
根据用户从第一个Spinner
中选择的选项,我们的第二个Spinner
将与基于第一个Spinner
选择的选项一起出现。我们将通过 Java 代码实现这一点,因为用户将在运行时从第一个下拉列表中进行选择,即动态选择。
为了处理 GUI 事件,我们需要在MainActivity.java文件中实现代码。我们将从创建两个Spinner
的实例开始,然后在两个Spinner
上分配setOnItemSelectedListener()
。
MainActivity.java
public class MainActivity extends AppCompatActivity
{
// these are the global variables
Spinner classSpinner, divSpinner;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
classSpinner = (Spinner) findViewById(R.id.classSpinner);
divSpinner = (Spinner) findViewById(R.id.divSpinner);
// Class Spinner implementing onItemSelectedListener
classSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
// do something upon option selection
}
@Override
public void onNothingSelected(AdapterView<?> parent)
{
// can leave this empty
}
});
// Div Spinner implementing onItemSelectedListener
divSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
// do something upon option selection
}
@Override
public void onNothingSelected(AdapterView<?> parent)
{
// can leave this empty
}
});
}
}
基于第一个Spinner
值更改第二个Spinner
的值
在classSpinner
的onItemSelected()
方法中,您必须从下拉列表中获取所选项目,并基于该值,您必须从字符串数组资源中为divSpinner
分配条目,即选项。所以在 classSpinner 的onItemSelected()
方法中添加以下代码。
classSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
// Get Selected Class name from the list
String selectedClass = parent.getItemAtPosition(position).toString();
switch (selectedClass)
{
case "Class 1":
// assigning div item list defined in XML to the div Spinner
divSpinner.setAdapter(new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_spinner_dropdown_item,
getResources().getStringArray(R.array.items_div_class_1)));
break;
case "Class 2":
divSpinner.setAdapter(new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_spinner_dropdown_item,
getResources().getStringArray(R.array.items_div_class_2)));
break;
case "Class 3":
divSpinner.setAdapter(new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_spinner_dropdown_item,
getResources().getStringArray(R.array.items_div_class_3)));
break;
case "Class 4":
divSpinner.setAdapter(new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_spinner_dropdown_item,
getResources().getStringArray(R.array.items_div_class_4)));
break;
}
//set divSpinner Visibility to Visible
divSpinner.setVisibility(View.VISIBLE);
}
@Override
public void onNothingSelected(AdapterView<?> parent)
{
// can leave this empty
}
});
我们可以从 ClassSpinner 中获取所选类名的值。为此,我们使用了parent.getItemAtPosition(position).toString()
方法。这里,parent
是 classSpinner 视图,position
是所选选项的位置。
因此在parent.getItemAtPosition(position).toString()
中,我们正在获取存储在参数position
中的位置处的类别Spinner
下拉列表的项目(选项)。
一旦我们在第一个下拉列表中选择了类的名称,我们就可以使用一个简单的switch
案例来用适当的值集初始化第二个下拉列表。
我们将用相应的字符串数组初始化ArrayAdapter
,并将适配器放置到第二个Spinner``divSpinner
上。
要从 XML 中的字符串资源访问字符串数组,我们必须使用方法getResources().getStringArray(ID_OF_ARRAY)
最后,我们将第二个Spinner
的可见性设置为 VISIBLE 。
创建一个吐司来显示选定的值
接下来,当用户从第二个Spinner
中选择一个选项时,我们将创建一个吐司并在屏幕上显示所选的值。
// getting selected value from second spinner
selectedDiv = parent.getItemAtPosition(position).toString();
// creating Toast
Toast.makeText(MainActivity.this, "\n Class: \t " + selectedClass + "\n Div: \t" + selectedDiv, Toast.LENGTH_LONG).show();
MainActivity.java 的完整代码
以下是MainActivity.java
的完整代码
package com.example.android.studytonight;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity
{
// these are the global variables
Spinner classSpinner, divSpinner;
// string variable to store selected values
String selectedClass, selectedDiv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
classSpinner = (Spinner) findViewById(R.id.classSpinner);
divSpinner = (Spinner) findViewById(R.id.divSpinner);
// Class Spinner implementing onItemSelectedListener
classSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
String selectedClass = parent.getItemAtPosition(position).toString();
switch (selectedClass)
{
case "Class 1":
// assigning div item list defined in XML to the div Spinner
divSpinner.setAdapter(new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_spinner_dropdown_item,
getResources().getStringArray(R.array.items_div_class_1)));
break;
case "Class 2":
divSpinner.setAdapter(new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_spinner_dropdown_item,
getResources().getStringArray(R.array.items_div_class_2)));
break;
case "Class 3":
divSpinner.setAdapter(new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_spinner_dropdown_item,
getResources().getStringArray(R.array.items_div_class_3)));
break;
case "Class 4":
divSpinner.setAdapter(new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_spinner_dropdown_item,
getResources().getStringArray(R.array.items_div_class_4)));
break;
}
//set divSpinner Visibility to Visible
divSpinner.setVisibility(View.VISIBLE);
}
@Override
public void onNothingSelected(AdapterView<?> parent)
{
// can leave this empty
}
});
// Div Spinner implementing onItemSelectedListener
divSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
selectedDiv = parent.getItemAtPosition(position).toString();
/*
Now that we have both values, lets create a Toast to
show the values on screen
*/
Toast.makeText(MainActivity.this, "\n Class: \t " + selectedClass +
"\n Div: \t" + selectedDiv, Toast.LENGTH_LONG).show();
}
@Override
public void onNothingSelected(AdapterView<?> parent)
{
// can leave this empty
}
});
}
}
当你运行你的安卓应用时,默认情况下你会得到第一条吐司消息,因为第一个项目已经分配给了Spinner
。别担心。只要去尝试改变类和部门下拉微调选择,你应该会看到如下图的结果。
当您选择类选项时,根据类选择,您的应用将在 DivSpinner 中加载其他项目,然后您可以从第二个 Spinner 中选择项目。当您从第二个Spinner
中选择一个项目时,您的应用将在设备屏幕上显示所选项目。
边距与填充属性
刚开始设计用户界面时,填充和边距属性之间总是有混淆。无论是网络开发还是安卓开发,边距和填充都是定位和设计用户界面元素的标准参数。
两者都在容器内部或外部提供了额外的空间/间隙。那到底有什么区别呢?让我们把它清理干净。简单来说,边距就是往外推,填充就是往里推。
现在,让我们理解当我们在安卓中使用这些属性来查看视图时会发生什么。
视图的边距和填充
让我们看看如何在安卓系统中使用视图的这些属性,以及它如何影响视图的位置和样式。
边距→安卓:布局 _ 边距
当我们说“向外推”时,视图(即矩形)会按 margin 属性中指定的尺寸从自身推出其周围的内容。这里,周围的内容可以是其他视图。下图会更清楚。
下面是我们如何证明这是我们的布局 XML:
android:layout_margin="20dp"
因此,其他视图将与该视图分开至少 20dp。
我们还可以为所有边设置不同的边距值,例如:
android:layout_marginRight="20dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
填充→安卓:填充
当我们说“向内推”时,视图(即矩形)通过填充属性中指定的维度将其内容从自身推向其中心。填充可被视为边距,但在视图内部。下图会更清楚。
下面是我们如何证明这是我们的布局 XML:
android:padding="20dp"
因此,它的内容(这里是文本)将被推入矩形内部 20dp。
我们还可以为所有边设置不同的填充值,例如:
android:paddingRight="20dp"
android:paddingLeft="20dp"
android:paddingTop="20dp"
android:paddingBottom="20dp"
带有布局的边距和填充
现在,让我们理解当我们为
边缘
当我们说“向外推”时,根布局即矩形按照边距属性中指定的尺寸从自身推出其周围的内容。在这里,周围的内容将是手机的屏幕。因此,布局(矩形)将自己从手机屏幕上推出。下图会更清楚。
将边距应用于布局的语法类似于视图的语法。
填料
当我们说向内推送时,根布局(即矩形)通过填充属性中指定的维度从自身推送其内容。在这里,它的内容将是它持有的不同观点,如TextView
、ImageView
等。下图会更清楚。
注意:在安卓系统中,应用于父级(根布局)的填充属性看起来与应用于子级(布局内部的视图)的边距属性相同。
从EditText
中获取值,并为TextView
设置值
原文:https://www.studytonight.com/android/get-edittext-set-textview
任何安卓应用都有两个部分——前端和后端。前端指的是组件的可视化,即您的应用在其他用户面前的外观。后端部分指的是应用运行背后的逻辑。****
****每当我们点击任何按钮或提交任何表单时,后端代码都会决定下一步要执行什么操作或如何处理从用户等处接收的数据。
在我们之前的教程中,我们已经看到了不同类型的布局对于作为前端部分的 GUI 设计是多么有用。在本教程中,我们将关注后端部分并为其编写代码。
在我们的示例中,我们将通过EditText
视图从用户处获取输入,并将其显示在TextView
中。此外,我们还将看到一个buttonClickListener
,用于定义在应用中点击按钮时要执行的操作。
下面是我们将要进行的设计。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFF8D"
tools:context="com.example.akshay.studytonightandroid.MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:text="NAME"
android:textSize="20sp"
android:layout_margin="20dp" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="PASSWORD"
android:layout_marginTop="38dp"
android:layout_below="@+id/textView"
android:layout_alignLeft="@+id/textView"
android:layout_alignStart="@+id/textView" />
<EditText
android:id="@+id/editName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:hint="Enter Name"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignLeft="@+id/editPassword"
android:layout_alignStart="@+id/editPassword" />
<EditText
android:id="@+id/editPassword"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Enter Password"
android:inputType="textPassword"
android:layout_alignBottom="@+id/textView2"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginRight="18dp"
android:layout_marginEnd="18dp" />
<Button
android:id="@+id/buttonSubmit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/textView2"
android:layout_marginTop="20dp"
android:text="SUBMIT" />
<Button
android:id="@+id/buttonReset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="RESET"
android:layout_alignBaseline="@+id/buttonSubmit"
android:layout_alignBottom="@+id/buttonSubmit"
android:layout_centerHorizontal="true" />
<TextView
android:id="@+id/tvResult"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginBottom="143dp"
android:textSize="30sp" />
</RelativeLayout>
在MainActivity.java文件中,我们将全局变量定义如下:
package com.example.akshay.studytonightandroid;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
// These are the global variables
EditText editName, editPassword;
TextView result;
Button buttonSubmit, buttonReset;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
在onCreate()
方法中使用setContentView()
方法设置主布局后,使用如下所示的findViewById()
方法将我们定义的全局变量附加到 GUI 视图中。
/*
Using the id of views specified in layout XML
we can initialize the view using findViewById
*/
editName = (EditText) findViewById(R.id.editName);
editPassword = (EditText) findViewById(R.id.editPassword);
result = (TextView) findViewById(R.id.tvResult);
buttonSubmit = (Button) findViewById(R.id.buttonSubmit);
buttonReset = (Button) findViewById(R.id.buttonReset);
正如该方法的名称所示,findViewById()
返回布局 XML 中定义的视图的一个实例。换句话说,这个方法用于获取 Java 中的视图实例,您已经在布局 XML 中制作并使用了这个实例。这是通过提到您在 XML 中定义的视图的id
来实现的。用 XML 创建的视图在 Java 中用来动态操作它。
注:
findViewById()
方法只返回View
,但不告诉返回哪个视图,即视图是否为 Button、 TextView 、 EditText 等。因此,您需要将此方法返回的视图类型转换为。
现在,要启用按钮点击事件,我们需要将点击监听器附加到按钮实例。这是通过编写以下代码来完成的:
// Attaching OnClick listener to the submit button
buttonSubmit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Get the Data and Use it
}
});
一旦你添加了这个代码,每当点击提交按钮,方法onClick
就会被调用,里面的代码就会被执行。
根据您的要求,我们希望获得用户在EditText
中输入的文本,并在单击提交按钮时显示在TextView
中。因此,让我们将以下代码放入onClick()
方法中:
// get text from EditText name view
String name = editName.getText().toString();
// get text from EditText password view
String password = editPassword.getText().toString();
我们使用了getText()
方法来获取在EditText
视图中输入的文本。但是getText()
方法返回一个Editable
实例,因此我们对其进行类型化以将其转换为String
供进一步使用。这可以通过使用toString()
方法来完成。
注: 我们将
editName
和editPassword
定义为全局变量,因此它们可以用于任何方法。
因此,现在我们有了用户输入的名称和密码值,我们可以轻松地在这个数据集上应用任何逻辑,如执行登录验证等。现在,我们将在TextView
中显示这些信息。为此,我们将在 TextView 实例中使用setText()
方法来显示其中的信息。这是使用以下代码完成的:
result.setText("Name:\t" + name + "\nPassword:\t" + password );
现在,每当点击提交按钮时,调用提交按钮的onClick()
方法,并使用EditText
实例上的getText()
方法将用户输入值存储在name
和password
变量中。然后,使用setText()
方法,输入值显示在TextView
中。
现在,当您按下重置按钮时,TextView
中的文本应该被重置,即清除。为此,我们还必须在重置按钮上实现点击监听器。下面是这样做的代码:
buttonReset.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// clearing out all the values
editName.setText("");
editPassword.setText("");
result.setText("");
editName.requestFocus();
}
});
您只需要为EditText
和TextView
设置文本等于""
(空)。此外,要获得名称EditText
字段上的输入光标,我们可以对编辑名称实例使用requestFocus()
方法。
MainActivity.java 的完整代码
package com.example.akshay.studytonightandroid;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
// These are the global variables
EditText editName, editPassword;
TextView result;
Button buttonSubmit, buttonReset;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editName = (EditText) findViewById(R.id.editName);
editPassword = (EditText) findViewById(R.id.editPassword);
result = (TextView) findViewById(R.id.tvResult);
buttonSubmit = (Button) findViewById(R.id.buttonSubmit);
buttonReset = (Button) findViewById(R.id.buttonReset);
/*
Submit Button
*/
buttonSubmit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String name = editName.getText().toString();
String password = editPassword.getText().toString();
result.setText("Name:\t" + name + "\nPassword:\t" + password );
}
});
/*
Reset Button
*/
buttonReset.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
editName.setText("");
editPassword.setText("");
result.setText("");
editName.requestFocus();
}
});
}
}
你可以在这里下载整个项目
如果需要,可以添加验证
如果用户将字段名称和密码留空并点击提交按钮,您也可以添加验证,如显示消息。
在这种情况下,我们所要做的就是检查name
或password
是否为空,如果发现为空,则使用 Toast
显示消息,说明这两个字段都是必填的。
buttonSubmit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String name = editName.getText().toString();
String password = editPassword.getText().toString();
if(name == '' || password == '') {
// If name or password is not entered
Toast.makeText(getApplicationContext(), "Both Name and Password are required", Toast.LENGTH_LONG).show();
}
else {
result.setText("Name:\t" + name + "\nPassword:\t" + password );
}
}
});
在安卓系统中使用RadioButton
和CheckBox
原文:https://www.studytonight.com/android/radiogroup-radiobutton-checkbox
到目前为止,您一定非常熟悉EditText
和TextView
以及各种布局。让我们继续,了解更多关于其他视图的信息,如RadioButton
和CheckBox
。
在本教程中,我们将设计一个表单,用户必须使用RadioButton
选择其中一个选项。用户将不得不使用CheckBox
选择更多的建议和选项。然后我们将在显示屏上显示用户使用吐司选择的所有选项。
让我们从收音机按钮和收音机组开始
让我们开始吧。创建一个新的安卓应用项目,并复制 XML 布局文件的以下内容。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.studytonightandroid.MainActivity" >
<TextView
android:id="@+id/tvRg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:gravity="center"
android:text="Rate This Lesson"
android:textAppearance="?android:attr/textAppearanceMedium" />
<RadioGroup
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/tvRg"
android:layout_centerHorizontal="true"
android:orientation="horizontal"
android:showDividers="beginning|middle|end"
android:layout_marginTop="10dp"
android:id="@+id/radioGroup" >
<RadioButton
android:id="@+id/rb1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="EXCELLENT"
android:checked="false" />
<RadioButton
android:id="@+id/rb2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="GOOD"
android:checked="true" />
<RadioButton
android:id="@+id/rb3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OKAY"
android:checked="false" />
<RadioButton
android:id="@+id/rb4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="POOR"
android:checked="false" />
</RadioGroup>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="SUBMIT"
android:id="@+id/btnSubmit"
android:layout_below="@+id/radioGroup"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"/>
</RelativeLayout>
您将看到以下输出:
布局完成后,我们现在将处理用户界面的后台逻辑(后端),它将获取用户选择并使用 toast 在屏幕上显示。
因此,我们需要用户将与之交互的视图,以便我们能够获得必要的信息。然后我们需要实现点击提交按钮上的监听器。
在onClickListener()
中,首先我们必须从收音机组中获取选定的RadioButton``id
。一旦我们有了所选RadioButton
的id
按钮,我们就可以很容易地获取所选RadioButton
的文本值并将其显示在屏幕上。让我们实现它。下面我们有MainActivity.java文件的所有代码。
package com.example.akshay.studytonightandroid;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
// These are the global variables
RadioGroup radioGroup;
RadioButton selectedRadioButton;
Button buttonSubmit;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// layout instances
buttonSubmit = (Button) findViewById(R.id.buttonSubmit);
radioGroup = (RadioGroup) findViewById(R.id.radioGroup);
/*
Submit Button
*/
buttonSubmit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// get the selected RadioButton of the group
selectedRadioButton = (RadioButton)findViewById(radioGroup.getCheckedRadioButtonId());
//get RadioButton text
String yourVote = selectedRadioButton.getText().toString();
// display it as Toast to the user
Toast.makeText(MainActivity.this, "Selected Radio Button is:" + yourVote , Toast.LENGTH_LONG).show();
}
});
}
}
为了得到选中的RadioButton
,我们使用了radioGroup.getCheckedRadioButtonId()
方法,返回选中RadioButton
的id
。
然后为了获得所选RadioButton
的文本,我们在该所选RadioButton
上使用了getText()
方法。我们从该方法接收的文本使用toString()
方法转换为String
类型。最后,我们使用一个 Toast 向用户显示了所选的选项值。
将以上代码添加到MainActivity.java文件中,然后运行你的安卓应用项目。结果将类似于下图所示。每当用户选择任何选项时,它都会以吐司的形式显示给用户。
是CheckBox
的时候了
现在,是时候玩一些CheckBox
了。通过在布局 XML 文件中的Button
视图后复制粘贴以下代码来扩展用户界面设计(将id
作为b 提交)。
<TextView
android:id="@+id/tvCb"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/radioGroup"
android:gravity="center"
android:text="Give Your Suggestions Here."
android:layout_marginTop="65dp"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<CheckBox
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=" I really enjoy this lesson."
android:id="@+id/cb1"
android:layout_below="@+id/tvCb"
android:layout_centerHorizontal="true"
android:checked="false"/>
<CheckBox
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="I will prefer this lesson over any other."
android:id="@+id/cb2"
android:layout_below="@+id/cb1"
android:layout_centerHorizontal="true"
android:checked="false"/>
<CheckBox
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="I would like to hear more from you."
android:id="@+id/cb3"
android:layout_below="@+id/cb2"
android:layout_centerHorizontal="true"
android:checked="false"/>
<CheckBox
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="I am satisfied with the content and full description."
android:id="@+id/cb4"
android:layout_below="@+id/cb3"
android:layout_centerHorizontal="true"
android:checked="false"/>
重要提示: 对于提交按钮,我们必须设置这个属性:
android:layout_below="@+id/cb4"
,使其出现在最后,因为我们现在已经在现有表单中添加了CheckBox
。
CheckBox
用于向用户显示多个选项,并且允许用户从这些选项中选择一个或多个。所有CheckBox
最初都将checked
属性设置为 false 。
要在用户点击提交按钮时从用户界面获取用户选择的CheckBox
值,我们将使用isChecked()
检查CheckBox
是否被选中。
因此,我们将不得不对我们的MainActivity.java类文件进行一些更改。首先,我们必须使用findViewById()
方法为CheckBox
创建实例。为此,我们还必须声明 CheckBox 类型的全局变量。
要声明全局变量,
CheckBox cb1, cb2, cb3, cb4;
然后,在onCreate()
方法内部,使用findViewById()
方法将来自 XML 的 CheckBox 视图存储到 Java 中。
cb1 = (CheckBox) findViewById(R.id.cb1);
cb2 = (CheckBox) findViewById(R.id.cb2);
cb3 = (CheckBox) findViewById(R.id.cb3);
cb4 = (CheckBox) findViewById(R.id.cb4);
一旦我们准备好了所有的实例,我们所要做的就是当用户点击提交按钮时,检查用户选择了哪些CheckBox
。正如我们已经提到的,这是通过使用 CheckBox 视图的isChecked()
方法来完成的。
isChecked()
如果CheckBox
被选中,方法返回真,否则返回假。使用getText()
和toString()
方法检索选定的CheckBox
值并将其添加到一个字符串(checkBoxChoices
)中。最后,一个吐司被用来显示所有选择的选项。
因此,用以下代码更新 SUBMIT 按钮的OnClick()
方法中的现有代码:
/*
Submit Button
*/
buttonSubmit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Get the selected RadioButton
selectedRadioButton = (RadioButton) findViewById(radioGroup.getCheckedRadioButtonId());
// get RadioButton text
String yourVote = selectedRadioButton.getText().toString();
String checkBoxChoices = "";
if (cb1.isChecked()) {
checkBoxChoices += cb1.getText().toString() + "\tYES";
}
else{
checkBoxChoices += cb1.getText().toString() + "\tNO";
}
if (cb2.isChecked()) {
checkBoxChoices += cb2.getText().toString() + "\tYES";
}
else{
checkBoxChoices += cb2.getText().toString() + "\tNO";
}
if (cb3.isChecked()) {
checkBoxChoices += cb3.getText().toString() + "\tYES";
}
else{
checkBoxChoices += cb3.getText().toString() + "\tNO";
}
if (cb4.isChecked()) {
checkBoxChoices += cb4.getText().toString() + "\tYES";
}
else{
checkBoxChoices += cb4.getText().toString() + "\tNO";
}
// display it as Toast to the user
Toast.makeText(MainActivity.this, "Selected Radio Button is:" + yourVote + "\n CheckBox Choices: \n "+ checkBoxChoices , Toast.LENGTH_LONG).show();
}
});
当您运行该应用时,您将看到在所有RadioButton
中,您只能选择一个RadioButton
,而在CheckBox
的情况下,您可以选择任意数量的RadioButton
。这就是RadioButton
和CheckBox
的工作方式。这就是安卓应用开发中RadioButton
和CheckBox
的实现。
Android 中的AutoCompleteTextView
原文:https://www.studytonight.com/android/autocomplete-textview
在本教程中,我们将了解可以在安卓应用开发中使用的AutoCompleteTextView
小部件。
但是它有什么用呢?你一定注意到谷歌搜索栏在你输入搜索查询时提供建议。
在AutoCompleteTextView
的帮助下,类似的功能可以在安卓应用中实现。
自动完成TextView
是一个可编辑的TextView
,用户可以在其中键入任何值,甚至可以从建议的项目列表中选择输入。当用户点击一个项目时,将从列表中选择建议的项目。此外,编辑框的内容将被所选的建议项目替换。以下是AutoCompleteTextView
的示例:
通过点击后退键或点击项目下拉列表外的任意位置,可以随时取消建议列表。建议列表使用数组编辑器生成,该编辑器保存当用户键入字符时出现在下拉列表中的项目数据集,并且仅在键入了由阈值定义的给定数量的字符后才出现。
自动完成 xtView 示例
在本教程中,我们将创建一个安卓应用,用户将获得一个EditText
视图,选择输入他们最喜欢的餐厅的名称。由于用户将输入名称,我们将为用户提供建议,用户可以从中选择任何项目。由于用户可以通过点击列表项来选择任何名称,一个带有餐厅名称的吐司将显示在屏幕上,该名称也将添加到TextView
中。
以下是项目的 XML 代码:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.studytonightandroid.MainActivity">
<TextView
android:id="@+id/tvRestaurant"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="Enter Your Country Below"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<AutoCompleteTextView
android:id="@+id/actv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/tvRestaurant"
android:layout_marginTop="10dp"
android:completionThreshold="1"/>
<TextView
android:id="@+id/tvDisplay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/actv"
android:layout_marginTop="10dp"
android:gravity="center"
android:text="selected country will appear here"
android:textSize="20sp"/>
</RelativeLayout>
在这个布局中,我们有一个TextView
在屏幕上显示标题“输入任何餐厅名称”。然后在它下面,我们有一个AutoCompleteTextView
,它将从用户那里获取餐厅名称,并提供建议。之后我们还有一个TextView
,它将显示从建议列表中选择的项目。
如您所见,在AutoCompleteTextView
中,我们设置了一个名为android:completionThreshold
的属性。此属性指示要输入的字符数,之后,建议列表将显示给用户。这意味着,如果您为其分配一个等于2
的值,那么,该视图将需要至少 2 个字符来向用户显示建议列表。
在MainActivity.java文件中,首先我们将创建AutoCompleteTextView
和TextView
的实例。然后,我们将使用 ArrayAdapter
在AutoCompleteTextView
中显示建议项目。为此,我们首先需要创建一个名为restaurants
的数组,并添加各种餐厅的名称以显示它们作为建议。
然后我们将实现AdapterView.OnItemClickListener
并在AutoCompleteTextView
上设置onItemClickListener()
,以从列表中获取用户选择的项目值。
以下是上述逻辑的代码:
MainActivity.java
package com.example.android.studytonight;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
// get instances of AutoCompleteTextView and TextView
AutoCompleteTextView autoCompleteTextView;
TextView tvDisplay;
String restaurants[] = {
"KFC",
"Dominos",
"Pizza Hut",
"Burger King",
"Subway",
"Dunkin' Donuts",
"Starbucks",
"Cafe Coffee Day"
};
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
autoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.actv);
tvDisplay = (TextView) findViewById(R.id.tvDisplay);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, restaurants);
autoCompleteTextView.setAdapter(adapter);
autoCompleteTextView.setOnItemClickListener(this);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
// we will show a Toast with selected value
}
}
请注意,在使用ArrayAdapter
时,我们提供了一个布局对象作为参数android.R.layout.simple_list_item_1
,而我们没有创建任何布局 xml 文件,因为这是指安卓操作系统提供的默认布局 XML。
您可以使用getItemAtPosition()
方法获得用户选择的值。然后,要在屏幕上显示所选项目,您需要使用Toast
类。最后,我们将使用第二个TextView
的setText()
方法为TextView
添加值。我们需要将所有这些代码放入onItemClick()
方法中,如下所示:
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
// fetch the user selected value
String item = parent.getItemAtPosition(position).toString();
// create Toast with user selected value
Toast.makeText(MainActivity.this, "Selected Item is: \t" + item, Toast.LENGTH_LONG).show();
// set user selected value to the TextView
tvDisplay.setText(item);
}
MainActivity.java 完全法典
这里是整个MainActivity.java的文件代码:
package com.example.android.studytonight;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener
{
// get instances of AutoCompleteTextView and TextView
AutoCompleteTextView autoCompleteTextView;
TextView tvDisplay;
String restaurants[] = {
"KFC",
"Dominos",
"Pizza Hut",
"Burger King",
"Subway",
"Dunkin' Donuts",
"Starbucks",
"Cafe Coffee Day"
};
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
autoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.actv);
tvDisplay = (TextView) findViewById(R.id.tvDisplay);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,restaurants);
autoCompleteTextView.setAdapter(adapter);
autoCompleteTextView.setOnItemClickListener(this);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
// fetch the user selected value
String item = parent.getItemAtPosition(position).toString();
// create Toast with user selected value
Toast.makeText(MainActivity.this, "Selected Item is: \t" + item, Toast.LENGTH_LONG).show();
// set user selected value to the TextView
tvDisplay.setText(item);
}
}
输出屏幕:
活动、意图和片段
安卓系统中的活动
在本教程中,我们将学习与安卓开发相关的最重要的概念之一,即活动。
什么是安卓系统中的活动?
人类的思想或意识对我们的感觉负责,当我们受到伤害(身体上或情感上)时,我们的想法会让我们感到痛苦,这通常会导致一些眼泪,看到或听到有趣的事情时会笑,等等。现实世界中发生在我们身体上的事情(受伤、视觉、听觉等)是由我们的头脑(意识或灵魂)来感应的,我们按照它来思考或操作。
所以在某种程度上,我们可以说我们的身体只是一个物理物体,而在每种情况下控制我们的是我们的思想(灵魂或意识)。
如果是安卓→ 视图、布局和视图组用于设计用户界面,这是我们 App 的物理外观。但是我们的应用的思想、灵魂或意识是什么呢?是的,是活动。
Activity 只不过是 Android 中的一个 java 类,它有一些预定义的函数,这些函数在不同的 App 状态下被触发,我们可以覆盖这些函数来执行我们想要的任何事情。
活动类为我们提供了空函数,让我们成为一切的控制者。
例如,如果我们有一个由我们的头脑指定的函数→ onSeeingSomethingFunny()
,虽然我们知道这里面发生了什么,但是如果我们可以覆盖并提供我们自己对这个函数的定义呢。
@Override
onSeeingSomethingFunny()
{
start crying;
}
在上下文中,有一件事与我们的例子不同,那就是一个人在出生时被创造一次,在死亡时被毁灭一次,在这之间的时间是由头脑/灵魂/意识控制的。但是一个活动负责无限次地创建和销毁一个应用。因此,除了控制应用,Activity 还控制应用生命周期的创建、销毁和其他状态。
安卓可以有多个活动,但只能有一个主活动。例如在 Java 编程(或者像 C 或者 C++ 这样的编程语言)中,程序的执行总是以main()
方法开始。同样,当用户按下 App 图标时,主活动被调用,执行从活动类的onCreate()
方法开始。
应用的不同状态(或主要应用活动)
从用户点击应用图标启动应用,到用户退出应用,应用处于某些已定义的状态,让我们看看它们是什么。
- 当用户点击应用图标时,主活动开始,并使用布局 XMLs 创建应用的用户界面。App 或 Activity 开始运行,称其处于 ACTIVE 状态。
- 当任何对话框出现在屏幕上时,就像您在某些应用上按下退出时,它会显示一个确认您是否要退出的框。在那个时候,我们不能与应用的用户界面交互,直到我们处理那个对话框/弹出窗口。在这种情况下,活动被称为处于暂停状态。
- 当我们在使用应用时按下主页按钮,我们的应用不会关闭。只会越来越小。App 的这种状态称为 STOPPED 状态。
- 当我们最终销毁应用时,即当我们完全关闭它时,它被称为处于销毁状态。
因此,安卓系统中一个活动(App)总共有四种状态,即Active
、Paused
、Stopped
和Destroyed
。
从用户的角度来看,在给定的时间点,活动要么是可见的,要么是部分可见的,要么是不可见的。那么,当一个活动具有以下可见性之一时会发生什么?我们将了解这一点,首先让我们详细了解这些状态。
活动状态
- 当“活动”处于活动状态时,表示它处于活动状态并正在运行。
- 它对用户是可见的,并且用户能够与之交互。
- 安卓运行时以最高优先级对待这种状态下的活动,从不试图杀死它。
暂停状态
- 处于这种状态的活动意味着用户仍然可以在背景中看到该活动,例如在透明窗口或对话框后面,即它是部分可见的。
- 用户在完成当前视图之前不能与活动交互。
- 安卓运行时通常不会在这种状态下终止活动,但在资源紧张的极端情况下可能会这样做。
停机状态
- 当一个新的活动在当前活动的基础上开始时,或者当用户点击 Home 键时,该活动将进入停止状态。
- 这种状态下的活动是看不见的,但并没有被破坏。
- 安卓运行时可能会在资源紧张的情况下扼杀这样的活动。
被摧毁的国家
- 当用户点击后退键或安卓运行时决定回收分配给活动的内存时,即处于暂停或停止状态,它将进入销毁状态。
- 活动不在内存中,用户看不到。
注意: 活动不能控制管理自己的状态。由于用户交互或系统生成的事件,它只是经历状态转换。
活动生命周期方法
每当我们打开谷歌地图应用,它都会通过全球定位系统获取我们的位置。如果全球定位系统跟踪器关闭,那么安卓系统将请求您的许可来打开它。那么全球定位系统跟踪器或安卓如何决定一个应用是否需要全球定位系统跟踪器才能运行呢?
是的,很明显,应用启动时会询问全球定位系统位置,这只有在全球定位系统跟踪器打开时才有可能。
这个应用是如何知道的,因为我们对它进行了编码,每当用户启动它时,它都必须要求用户打开全球定位系统跟踪器,这是必需的。
同样,我们也可以告诉应用在退出或被破坏之前执行一些事情。
这就是活动生命周期的作用。有六种关键的生命周期方法,每个活动都根据其状态进行。它们是:
onCreate()
onStart()
onResume()
onPause()
onStop()
onDestroy()
| 方法 | 它是做什么的? |
| onCreate()
| 每当活动开始运行时,第一个要执行的方法是onCreate()
。此方法在生存期内只执行一次。如果我们在活动中有任何实例变量,这些变量的初始化可以在这个方法中完成。在onCreate()
方法之后,执行onStart()
方法。 |
| onStart()
| 在执行onStart()
方法的过程中,活动尚未呈现在屏幕上,但即将对用户可见。在这个方法中,我们可以执行任何与 UI 组件相关的操作。 |
| onResume()
| 当活动最终呈现在屏幕上时,调用onResume()
方法。此时,活动处于活动状态,并与用户交互。 |
| onPause()
| 如果活动失去了焦点,并且对用户来说只是部分可见,它将进入暂停状态。在此转换期间,调用onPause()
方法。在onPause()
方法中,我们可以在活动进入后台之前提交数据库事务或执行轻量级处理。 |
| onStop()
| 从活动状态,如果我们按下主页键,活动将转到背景,设备的主屏幕将变得可见。在此事件期间,活动进入停止状态。执行onPause()
和onStop()
两种方法。 |
| onDestroy()
| 当一个活动被用户或安卓系统破坏时,调用onDestroy()
函数。 |
当活动从暂停状态回到焦点时,调用onResume()
。
当我们重新打开任何应用时(按下主页键后),活动现在从停止状态转换到活动状态。因此,调用onStart()
和onResume()
方法。
注意:
onCreate()
方法不被调用,因为它在活动生命周期中只执行一次。
要破坏屏幕上的活动,我们可以按后退键。这将使活动进入销毁状态。在此事件中,调用onPause()
、onStop()
和onDestroy()
方法。
注意: 每当我们改变屏幕的方向,即从纵向改变为横向,或者相反,生命周期方法从开始即从
onCreate()
方法开始。这是因为完整的间距和其他视觉外观得到改变和调整。
安卓系统中的意图
你有没有想过当我们点击某个按钮时,一个新的活动是如何打开的,假设设置按钮在任何应用中显示设置屏幕?当我们点击它的通知时,应用是如何打开的?我们如何在手机中获得低电量警报?所有这些都是可能的,因为安卓的意图。
意图是一个消息对象,您可以使用它向应用组件请求操作。意图基本上是做一件事的意图。这是安卓组件之间的一种通信方式,通过不同的组件请求组件的动作。
这就像是安卓监听的一条消息,然后通过识别和调用应用的适当组件(比如活动、服务、内容提供商等)做出相应的反应。).它可以在同一个应用中,也可以在其他应用中。
如果多个应用能够响应该消息,那么安卓系统会向用户提供一份这些应用的列表,用户可以从中进行选择。
安卓系统中意图的使用
意图有三种基本用途:
1.开始一项活动
一个活动代表一个应用中的一个屏幕。您可以通过向startActivity()
传递意图来启动活动的新实例。意图描述要开始的活动,并携带任何必要的数据。
2.启动服务
服务是在后台执行操作的组件,没有用户界面。您可以通过向startService()
传递一个意向来启动一个服务以执行一次操作(如下载文件)。意图描述了启动哪个服务并携带任何必要的数据。
3.进行广播
广播是任何应用都能接收到的消息。系统为系统事件提供各种广播,例如当系统启动或设备开始充电时。您可以通过向sendBroadcast()
或sendOrderedBroadcast()
传递一个意图来将广播传递给其他应用。
意向类型
在安卓系统中,有两种意图:
- 明确的意图
- 隐含意图
明确的意图
当你明确定义哪个安卓组件应该在某个用户动作上打开时,你就使用了明确的意图。你通常使用明确的意图在你自己的应用中启动一个新组件,因为你知道你想要启动哪个确切的活动或服务。例如,您可以启动一个新的活动来响应用户操作,或者启动一个服务来在后台下载文件。
创建明确的意图
为了创造一个明确的意图,
-
You need to make an
Intent
object. The constructor of the Explicit Intent's object needs two parameters as follows:上下文 c :这表示活动的对象,您从这里调用意图。
Java 文件名:这代表你要打开的 Activity 的 Java 文件名。
注意 : 需要提到扩展名为
.class
的 java 文件名Intent i = new Intent(this, MyJavaFile.class);
-
调用
startActivity()
方法,将意图的对象作为参数传递。这个方法导航到意图对象中提到的 java 文件。startActivity(i);
-
If you need to pass some information or data to the new Activity you are calling, you can do this by calling
putExtra()
method before thestartActivity()
method. This method accepts key-value pair as its parameter.i.putExtra("key1", "I am value1"); i.putExtra("key2", "I am value2"); startActivity(i);
注意 : 要接收新活动中的数据并相应地使用它,您需要调用
getIntent()
方法,然后调用您想要通过显式意图打开的活动的 java 类中的getStringExtra()
方法。getStringExtra()
方法以键为参数。String a = getIntent().getStringExtra("key1");
这样做,将存储在键 1 的值存储到字符串变量
a
中。
隐含意图
当你只需要说出你想执行什么动作而不用担心哪个组件会执行它时,那么你可以使用隐式意图。
隐式意图并不指定执行特定操作的特定组件,而是声明要执行的一般操作,这允许任何组件,甚至来自另一个应用的组件来处理它。
例如,如果您想在地图上显示用户的特定位置,您可以使用隐式意图通过该意图传递坐标,然后任何其他能够在地图上显示坐标的应用都将接受该意图。
创建隐含意图
为了产生隐含的意图,
-
你需要制作一个
Intent
物体。隐式意图对象的构造器需要一个你想要执行的类型的动作。动作是指定要执行的一般动作的字符串。动作很大程度上决定了意图的其余部分是如何构造的,尤其是作为数据和附加信息包含在意图对象中的信息。例如,
ACTION_VIEW :当你有一些活动可以展示给用户的信息,比如在图库应用中查看的照片,或者在地图应用中查看的地址时,使用这个动作。
ACTION_SEND :当你有一些用户可以通过另一个应用分享的数据时,比如邮箱应用或者一些社交网络应用,就会用到这个动作。
注意 : 你可以指定你自己的动作,让你自己的应用内的意图使用(或者让其他应用使用来调用你的应用内的组件),但是你通常指定由意图类或者其他框架类定义的动作常量。
Intent i = new Intent(Intent.ACTION_VIEW);
-
您需要为要执行的操作提供一些数据。数据通常表示为 URI(统一资源标识符),它向其他应用提供数据,以便能够处理 URI 数据的任何其他应用可以执行所需的操作。例如,如果你想通过你的应用打开一个网站,你可以使用 setData() 方法传递 Uri 数据,如下所示:
i.setData(Uri.parse("http://www.google.co.in"));
-
最后以意向对象为参数调用
startActivity()
方法。startActivity(i);
安卓系统中的片段
原文:https://www.studytonight.com/android/fragments-in-android
安卓中的片段是一个组件,可以在活动中使用,定义一个独立的模块化用户界面组件,并附加到活动中。它独立运行,但由于它与活动相关联,当一个活动被破坏时,片段也会被破坏。
如果你懂生物,知道宿主和寄生虫的概念,那么在安卓系统中,Activity
是宿主,而一个片段是寄生虫。
片段有自己的生命周期事件,不同于活动的生命周期事件。
一个活动可以有任意数量的片段,尽管建议在一个活动中不要使用太多的片段。
此外,一个片段是一个可重用的组件,因此,如果需要,单个片段可以包含在多个活动中。
一般来说,在安卓应用中,片段被用来创建多窗格用户界面。
一个片段对于 UI(用户界面)有它自己的布局,但是我们甚至可以定义一个没有任何布局的片段,来实现一个没有用户界面的行为,更像是一个后台服务。
因此,片段是安卓操作系统中一个非常有趣的组件,它可以在一个安卓应用中以多种方式使用。
为什么我们需要安卓中的片段?
如果我们已经有了活动,一个片段就像是一个子活动,那么在安卓中再多一个组件又有什么用呢?
嗯,在片段引入之前(片段是在 Android 的蜂巢版即 API 版本 11 中添加的),我们在给定的时间点只能在一个屏幕上有一个活动,没有办法划分屏幕,单独控制不同的部分。
随着移动设备屏幕尺寸的增加,在屏幕上同时显示更多的内容更有意义,因此片段非常有用,在安卓开发者社区中非常受欢迎。
安卓应用中片段的使用完全取决于应用所使用的设备的屏幕大小。如果屏幕尺寸大,那么我们可以很容易地在屏幕上显示 2 个或者更多的片段,但是如果显示尺寸较小,建议在单独的活动中使用片段。
因此,还建议保持片段的设计模块化和独立,以便它可以根据屏幕大小或任何其他因素在不同的屏幕/活动上使用。
片段在安卓系统中的主要用途
下面是片段在安卓系统中的 3 种主要用法,片段就是针对这 3 种用法介绍的:
- 模块化:如果一个活动有太多的功能组件,最好将其分成独立的片段,从而使代码更有组织性和更容易维护。
- 可重用性:如果我们在一个片段中定义了一个特定的特性,那么这个特性或多或少会变成一个可重用的组件,可以很容易地被引入到任何活动中。
- 适应性:如果我们把一个应用屏幕的 UI 组件拆分成片段,那么根据屏幕大小等改变它们的方向和位置就变得更容易了。
片段生命周期
片段生命周期从它附加到一个活动开始。下面我们以流程图的形式展示了片段的完整生命周期。
片段的生命周期方法
This is called when the fragment becomes active or interactive.
| 方法名 | 描述 |
| 活动 | 当片段附加到活动时,它被调用一次。 |
| onCreate(捆绑) | 创建片段时,系统调用此方法。这是一个重要的方法,您应该在这个方法中实现片段的基本组件。 |
| onCreateView() | 当必须初始化片段的用户界面时,调用这个方法。当第一次创建片段时调用它,然后当片段从后栈返回布局时调用它。这个方法通常会返回一个View
组件,但是如果片段没有 UI,那么可以返回一个null
。 |
| onActivityCreated() | 创建宿主活动时会调用此方法。此时,我们甚至可以使用findViewById()
方法访问片段的视图。 |
| onStart() | 当片段在设备屏幕上变得可见时,调用此方法。 |
| onResume() | |
| onpause() | 当一个片段不再是交互式的,并且用户即将离开该片段时,就会调用这个函数。此时,如果需要,建议保存现有用户会话的任何数据。 |
| onStop() | 当片段不再可见时,调用此方法。 |
| onDestroyView() | 当片段要被销毁时,就调用这个函数。在这里,您可以在片段被销毁之前清理资源。 |
| onDestroy() | 这是对片段状态的最后清理。 |
| 底部() | 就在片段从宿主活动分离之前调用它。 |
在我们的下一个教程中,我们将学习如何在 android 中实现片段。
在安卓系统中处理片段
原文:https://www.studytonight.com/android/working-with-android-fragments
既然我们已经理解了什么是片段,现在是时候举一个实际的例子了。为了创建一个片段,我们必须定义一个片段类,它扩展了类Fragment
并覆盖了创建片段所必需的方法。
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.ViewGroup;
public class ExampleFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_view, container, false);
}
}
在上面的代码中,fragment_view
布局是片段的布局,通常在一个单独的名为 fragment_view.xml 的 XML 文件中定义
要向任何活动添加片段,您可以遵循以下两种方法中的任何一种:
-
Specify the fragment directly in the main layout XML file. Basic fragment code in XML looks like:
<fragment android:name="com.studytonight.android.fragments.ExampleFragment" android:id="@+id/fragments" android:layout_width="match_parent" android:layout_height="match_parent" />
其中属性
android:name
将保存片段类的完全限定名。 -
或者,您可以使用
FrameLayout
在运行时将片段添加到您的活动中。我们将详细讨论这种方法,但首先,让我们学习如何在我们的 android 应用中实现一个基本片段。
片段的基本实现
在这个例子中,我们将看到如何向一个活动添加一个片段,通过直接在我们的应用的主布局 XML 文件中添加片段。在这个例子中,我们将创建 2 个片段,并将它们添加到我们的主活动中。
下面是我们的 activity_main.xml 文件或主布局 xml 文件的代码:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<fragment
android:id="@+id/fragmentOne"
android:name="com.studytonight.fragmentexample.FragmentOne"
android:layout_height="0dp"
android:layout_width="match_parent"
android:layout_weight="1" />
<fragment
android:id="@+id/fragmentTwo"
android:name="com.studytonight.fragmentexample.FragmentTwo"
android:layout_height="0dp"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_below="@id/fragmentOne" />
</RelativeLayout>
第一个片段的布局将在 fragment_one.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="match_parent"
android:orientation="vertical"
android:background="#2c2e43" >
<TextView
android:id="@+id/textViewOne"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:gravity="center_horizontal"
android:text="First Fragment" />
</LinearLayout>
而对应的片段类FragmentOne
将是:
package com.studytonight.fragmentexample;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class FragmentOne extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
// TODO Auto-generated method stub
return inflater.inflate(R.layout.fragment_one, container, false);
}
}
同样,第二个片段的布局 XML 文件和类将是:
fragment_two.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="match_parent"
android:orientation="vertical"
android:background="#ff9100" >
<TextView
android:id="@+id/textViewTwo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:gravity="center_horizontal"
android:text="Second Fragment" />
</LinearLayout>
FragmentTwo.java
package com.studytonight.fragmentexample;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class FragmentTwo extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
// TODO Auto-generated method stub
return inflater.inflate(R.layout.fragment_two, container, false);
}
}
最后,主 actvity 类MainActivity.java的代码如下:
package com.studytonight.fragmentexample;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
一切就绪后,运行 android 应用查看输出。
输出屏
运行时更新片段
我们也可以在运行时添加、移除或更新活动中的片段组件。为了在运行时添加一个片段,我们必须使用FrameLayout
in out 主布局 XML 文件来定义我们想要添加片段的位置。
要在运行时添加/替换/删除片段,FragmentManager
和FragmentTransaction
可以优雅地执行添加、替换和删除片段的操作。
下面是我们如何将FrameLayout
添加到布局 XML 文件中:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<FrameLayout
android:id="@+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
这就是我们如何使用片段管理器和事务类:
// get fragment manager
FragmentManager fm = getFragmentManager();
// add a new fragment
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.your_placehodler, new FragmentOne());
// commit the change
ft.commit();
// replace a fragment
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.your_placehodler, new FragmentTwo());
ft.commit();
// remove a fragment
Fragment fragment = fm.findFragmentById(R.id.fragmentTwo);
FragmentTransaction ft = fm.beginTransaction();
ft.remove(fragment);
ft.commit();
这是可以使用的,当点击一些按钮时,我们必须显示不同的信息,在这种情况下,我们可以在点击按钮时更新片段。
你一定在想,为什么我们需要一个管理器和事务类来更新或添加一个片段?嗯,由于片段是异步加载的,对活动的更改是在运行时进行的,因此为了处理这些因素,使用了FragmentTransaction
类,它执行事务中的所有操作,这意味着,如果出现任何问题,它将把用户界面恢复到最后的稳定状态。
使用安卓系统
在安卓系统中使用自定义字体
原文:https://www.studytonight.com/android/custom-font-in-android
Android 在 android studio 中提供了各种字体样式,帮助开发者让自己的应用或游戏更有吸引力,但是如果你想给你的应用增加一些独特的字体,一种 Android Studio 默认没有的自定义字体,那你会怎么做呢?
要做到这一点,在 android studio 中,我们主要有 3 种方法,我们将使用如下所示的所有 3 种方法逐一添加自定义字体。所以在跳转到用于添加自定义字体的方法之前,首先我们必须下载任何自定义字体文件(我们将在我们的应用中使用),这通常是一个。ttf 文件。对于本教程,我们将使用FFF-图斯克 ( 立即下载)字体文件,或者您可以下载任何。你想要的 ttf 文件。
注意: 在进行下面 3 种方法或技巧之前,首先我们要创建一个活动为空的安卓项目,包含所有的基本文件和资源。
添加自定义字体-第一种方法
您必须遵循一些基本步骤来将自定义字体添加到您的 android 项目中:
-
首先,我们将创建一个新的安卓资源目录。为此,右键单击 app - > res ,选择 New - >安卓资源目录,创建字体的资源类型,然后单击确定。
-
现在解压FFF-图斯克 zip 文件,在FFF-图斯克文件夹中,你会找到fff _ 图斯克. ttf 文件。复制并粘贴 app - > res - >字体文件夹中的文件(您可以在项目中粘贴任意数量的字体文件)
-
Open the activity_main.xml file and remove the default android generated code and create a RelativeLayout and inside the relative layout add a simple TextView and create an id for the text view, which we will use in step 4.
<TextView android:layout_marginLeft = "16dp" android:layout_marginRight = "16dp" android:textColor = "#FF5722" android:layout_centerInParent = "true" android:foregroundGravity = "center_horizontal" android:gravity = "center_horizontal" android:text = "Hello World" android:textSize = "32dp" android:id = "@+id/customFont" android:layout_width = "match_parent" android:layout_height = "wrap_content"/>
activity_main.xml 文件的完整代码如下:
<?xml version = "1.0" encoding = "utf-8" ?> <RelativeLayout xmlns:android = "http://schemas.android.com/apk/res/android" xmlns:app = "http://schemas.android.com/apk/res-auto" xmlns:tools = "http://schemas.android.com/tools" android:layout_width = "match_parent" android:layout_height = "match_parent" tools:context = ".MainActivity"> <TextView android:layout_marginLeft = "16dp" android:layout_marginRight = "16dp" android:textColor = "#FF5722" android:layout_centerInParent = "true" android:foregroundGravity = "center_horizontal" android:gravity = "center_horizontal" android:text = "Hello World" android:textSize = "32dp" android:id = "@+id/customFont" android:layout_width = "match_parent" android:layout_height = "wrap_content"/> </RelativeLayout>
-
现在打开MainActivity.java文件,导入如下图所示的库:
//import the basic library import android.graphics.Typeface; import android.os.Bundle ; import android.widget.TextView; import androidx.core.content.res.ResourcesCompat;
在
onCreate()
方法中,创建TextView
的实例,并创建一个Typeface
对象,并将其设置为TextView
,如下所示://creating and initializing the TextView object TextView customFontTextView = ( TextView ) findViewById( R.id.customFont); //creating typeface and getting the font from the font directory Typeface typeface = ResourcesCompat.getFont( MainActivity.this, R.font.fff_tusj ); //setting typeface to textview customFontTextView.setTypeface( typeface );
MainActivity.java文件的完整代码如下:
package com.studytonight.project ; //import the basic library import android.graphics.Typeface; import android.os.Bundle ; import android.widget.TextView; import androidx.core.content.res.ResourcesCompat; import androidx.appcompat.app.AppCompatActivity ; public class MainActivity extends AppCompatActivity { @Override protected void onCreate( Bundle savedInstanceState ) { super.onCreate( savedInstanceState ); setContentView( R.layout.activity_main ); //creating and initializing the TextView object TextView customFontTextView = ( TextView ) findViewById( R.id.customFont); //creating typeface and getting the font from the font directory Typeface typeface = ResourcesCompat.getFont( MainActivity.this, R.font.fff_tusj ); //setting typeface to textview customFontTextView.setTypeface( typeface ); } }
注: 所有 3 种技术的输出都是一样的,就像我们在做同样的事情,只是方式不同。
通过添加自定义字体类别:
要通过为自定义字体创建类来添加自定义字体,请执行以下步骤:
-
首先我们创建一个新的文件夹为此,右键单击应用并选择新建- >文件夹- >资产文件夹并创建一个资产文件夹。
-
现在复制过去 app - >资产文件夹中我们在方法 1 中提取的 fff_tusj.ttf (您可以在资产文件夹中的项目中粘贴任意多的文本文件)
-
在本教程中,我们将通过右键单击app->Java->com . study south . project->New->Java 类为自定义字体创建一个新的 Java 类,并根据您的需要命名该类(我们正在为本教程创建 MyCustomFont 类)
-
Now extend the MyCustomFont to AppCompatTextView and create 3 constructors inside the MyCustomFont class as shown below:
//constructor with 1 parameter public MyCustomFont( @NonNull Context context ) { super( context ); } //constructor with 1 parameter public MyCustomFont( @NonNull Context context, @Nullable AttributeSet attrs ) { super( context, attrs); } //constructor with 1 parameter public MyCustomFont( @NonNull Context context, @Nullable AttributeSet attrs , int defStyleAttr ) { super( context, attrs , defStyleAttr ); }
-
现在在我的自定义字体里面我们创建一个方法私有虚空
setTheTypeface(Context context)
,在这个方法里面我们创建并设置字体,如下图所示:private void setTheTypeface( Context context ) { Typeface typeface = Typeface.createFromAsset(context.getAssets() , "fff_tusj.ttf" ); this.setTypeface( typeface ); }
现在调用
setTheTypeface()
方法里面的所有的构造器如下图所示public MyCustomFont( @NonNull Context context ) { super( context ); //calling setTheTypeface Function setTheTypeface( context ); } public MyCustomFont( @NonNull Context context, @Nullable AttributeSet attrs ) { super( context, attrs); //call the setTheTypeface Function setTheTypeface( context ); } public MyCustomFont( @NonNull Context context, @Nullable AttributeSet attrs , int defStyleAttr ) { super( context, attrs , defStyleAttr ); //calling the setTheTypeface Function setTheTypeface( context ); }
现在 MyCustomFont 类的工作已经结束,MyCustomFont.java的完整代码如下所示
package com.studytonight.project; import android.content.Context; import android.graphics.Typeface; import android.util.AttributeSet; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.widget.AppCompatTextView; class MyCustomFont extends AppCompatTextView { //constructor with 1 parameter public MyCustomFont( @NonNull Context context ) { super( context ); //calling setTheTypeface Function setTheTypeface( context ); } //constructor with 2 parameter public MyCustomFont( @NonNull Context context, @Nullable AttributeSet attrs ) { super( context, attrs); //call the setTheTypeface Function setTheTypeface( context ); } //constructor with 3 parameter public MyCustomFont( @NonNull Context context, @Nullable AttributeSet attrs , int defStyleAttr ) { super( context, attrs , defStyleAttr ); //calling the setTheTypeface Function setTheTypeface( context ); } private void setTheTypeface( Context context ) { Typeface typeface = Typeface.createFromAsset(context.getAssets() , "fff_tusj.ttf" ); this.setTypeface( typeface ); } }
-
现在转到 activity_main.xml 文件,删除默认布局,添加一个相对布局,在相对布局中添加com . study south . project . mycustomfont,如下所示:
<com.studytonight.project.MyCustomFont android:layout_marginLeft = "16dp" android:layout_marginRight = "16dp" android:textColor = "#FF5722" android:layout_centerInParent = "true" android:foregroundGravity = "center_horizontal" android:gravity = "center_horizontal" android:text = "Hello World" android:textSize = "32dp" android:id = "@+id/customFont" android:layout_width = "match_parent" android:layout_height = "wrap_content"/>
现在方法 2 完成, activity_main.xml 文件的完整代码如下所示
<?xml version = "1.0" encoding = "utf-8" ?> <RelativeLayout xmlns:android = "http://schemas.android.com/apk/res/android" xmlns:app = "http://schemas.android.com/apk/res-auto" xmlns:tools = "http://schemas.android.com/tools" android:layout_width = "match_parent" android:layout_height = "match_parent" tools:context = ".MainActivity"> <com.studytonight.project.MyCustomFont android:layout_marginLeft = "16dp" android:layout_marginRight = "16dp" android:textColor = "#FF5722" android:layout_centerInParent = "true" android:foregroundGravity = "center_horizontal" android:gravity = "center_horizontal" android:text = "Hello World" android:textSize = "32dp" android:id = "@+id/customFont" android:layout_width = "match_parent" android:layout_height = "wrap_content"/> </RelativeLayout>
使用 fontFamily 属性-最简单的方法:
这是在我们的安卓应用中添加自定义字体的最简单方法,
-
在这个技巧中,我们将遵循方法 1 的前 2 步,这意味着我们首先添加字体。ttf 文件里面的字体文件夹。
-
Then open the activity_main.xml file and remove the default code and add the relative layout and inside it we add the simple TextView and add the fontFamily property to it as shown below:
android:fontFamily="@font/fff_tusj"
现在我们的
TextView
看起来像:<TextView android:fontFamily = "@font/fff_tusj" android:layout_marginLeft = "16dp" android:layout_marginRight = "16dp" android:textColor = "#FF5722" android:layout_centerInParent = "true" android:foregroundGravity = "center_horizontal" android:gravity = "center_horizontal" android:text = "Hello World" android:textSize = "32dp" android:layout_width = "match_parent" android:layout_height = "wrap_content"/>
我们完成了,是的,就是这样, activity_main.xml 文件的完整代码如下所示:
<?xml version = "1.0" encoding = "utf-8" ?> <RelativeLayout xmlns:android = "http://schemas.android.com/apk/res/android" xmlns:app = "http://schemas.android.com/apk/res-auto" xmlns:tools = "http://schemas.android.com/tools" android:layout_width = "match_parent" android:layout_height = "match_parent" tools:context = ".MainActivity"> <TextView android:fontFamily = "@font/fff_tusj" android:layout_marginLeft = "16dp" android:layout_marginRight = "16dp" android:textColor = "#FF5722" android:layout_centerInParent = "true" android:foregroundGravity = "center_horizontal" android:gravity = "center_horizontal" android:text = "Hello World" android:textSize = "32dp" android:layout_width = "match_parent" android:layout_height = "wrap_content"/> </RelativeLayout>
自定义字体的输出:
对于以上三种方法,应用的输出都是相同的:
有了这个,现在你可以在你的安卓应用中使用任何你喜欢的新字体。
项目时间
科学测验安卓应用
原文:https://www.studytonight.com/android/second-android-application-1
现在我们已经熟悉了活动、布局、视图等,是时候动手了,创建我们的第二个应用。这个应用将有一个科学测验,用户将有选择回答“真”或“假”。根据用户输入的内容,我们将向用户显示,他们是否选择了正确的选项,只需显示一条消息,说明正确或不正确。
科学测验应用开发
- 打开AndroidStudio,进入文件→新建→新项目。在“新建项目”窗口中,输入应用名称作为
ScienceQuiz
,输入公司域作为com.studytonight.quiz
,然后单击“下一步”。
- 在下一步中,您将被要求选择目标设备,在该设备上将支持您的应用。这个应用还是用
Phone and Tablet
吧。在显示最低 SDK的下拉列表中,选择API 16: Android 4.1 (Jelly Bean)
,这意味着我们的应用将在安卓 4.1 版本到 7(最新版本)的所有手机和平板电脑上运行。点击下一步按钮。
- 现在是时候将第一个活动添加到我们的应用中了。从可用选项中选择
Empty Activity
。然后点击下一步。
- 输入活动名称为
ScienceActivity
,AndroidStudio 会自动填充布局文件名。在活动名称中添加后缀“活动”是一种标准做法,我们将遵循它。而对于布局 XML 文件,则是所有的字都是小而逆序,用下划线_
隔开。单击“完成”创建项目。
- AndroidStudio 需要一些时间,来构建一切,所以要有点耐心。一旦 AndroidStudio 完成你的项目构建,你会看到一个新的项目被添加到左边的项目工具窗口中,文件
activity_science.xml
将被打开,在预览工具窗口中你会看到你的应用的预览。如果预览工具窗口没有打开,进入视图→工具窗口→预览,预览窗口会显示在右侧。
科学测验安卓应用——第 2 部分
原文:https://www.studytonight.com/android/second-android-application-2
正如我们所知,一个活动的默认布局由一个RelativeLayout
和一个带有文本 Hello World 的TextView
组成!,因此我们将不得不改变 ti,因为我们正在构建一个科学测验应用。对于我们的应用,我们将设置如下图所示的屏幕,为此,我们需要:
LinearLayout
一纵- 一
TextView
- 一横
LinearLayout
T2】 - 以及,两个
Buttons
从文件activity_science.xml
中移除现有的 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="match_parent"
android:gravity="center"
android:orientation="vertical" >
<*TextView*
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="24dp"
android:text="@string/question_text" />
<*LinearLayout*
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<*Button*
android:id="@+id/true_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/true_button" />
<*Button*
android:id="@+id/false_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/false_button" />
</*LinearLayout*>
</*LinearLayout*>
你会注意到 3 个用红色标记的字符串,现在不要担心它们,我们稍后会回来。
在更改布局 xml 文件时,您会注意到预览也发生了变化。每个 XML 元素,即LinearLayout
、TextView
和Button
代表一个小部件,它们的 XML 属性定义了如何配置小部件,就像在TextView
中显示什么文本一样,由android:text
属性配置。文本显示在Button
小部件上也是如此。
小部件和属性的分层布局
让我们试着理解一下布局。从上面的 XML 中我们可以看到,LinearLayout
是根元素,它的高度和宽度等于属性android:layout_width="match_parent"
和android:layout_height="match_parent"
定义的设备屏幕。它还将子元素的方向定义为垂直。
根LinearLayout
的两个子部件是一个TextView
和另一个LinearLayout
。
孩子LinearLayout
还有两个孩子,Button
水平放置在LinearLayout
内部,因为它被定义为孩子LinearLayout
中的属性android:orientation
。
我们还为两个Button
小部件指定了android:id
属性。完成后,我们可以参考和使用活动类中的按钮,我们将在下一个教程中看到如何做到这一点。
创建字符串资源
每个安卓项目都已经添加了一个strings.xml
文件。在项目工具窗口中,在您的项目中,如果您选择了安卓风格结构,请找到应用/res/values ,如果您的项目工具窗口在项目视图中,请找到应用/src/main/res/values 。如果您不知道如何在安卓包结构和项目之间切换,请遵循下图。
在strings.xml
文件中单独定义字符串值是一种标准做法。可以指定任何字符串值的格式如下:
<string name="STRING_NAME">STRING_VALUE</string>
一旦在strings.xml
文件中声明了一个字符串,就可以使用@string/STRING_NAME
直接在布局 xml 文件中使用它。现在,我们必须在我们的strings.xml
文件中为问题 _ 文本、真 _ 按钮和假 _ 按钮创建三个字符串引用,如下所述:
<string name="question_text">
*Graphite is used in making Pencils.*
</string>
<string name="true_button">*True*</string>
<string name="false_button">*False*</string>
当您在strings.xml
中创建这 3 个字符串时,您将看到您的layout_science.xml
文件中的所有错误都将被解决。
如果我们愿意,我们也可以有自己独立的任意名称的字符串 xml 文件,但是它应该位于 res/values/ 目录中。
科学测验安卓应用——大结局
原文:https://www.studytonight.com/android/second-android-application-3
现在我们的布局已经完全设置好了,是时候定义真和假按钮的动作了。由于这是一个简单的应用,因此只有一个问题,当用户点击“真”时,我们会显示一条消息,说Correct!
因为石墨是用来做铅笔的,这是真的。如果用户按下“假”按钮,我们将显示消息Incorrect!
我们的ScienceActivity
类默认情况下是这样的:
package quiz.studytonight.com.sciencequiz;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class ScienceActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_science);
}
}
将按钮部件连接到科学活动类
我们将在我们的ScienceActivity
类中定义两个类型为Button
的私有变量,然后将它们与布局 xml 文件中定义的小部件挂钩。首先让我们定义两个私有变量:
public class ScienceActivity extends AppCompatActivity {
private Button mTrueButton;
private Button mFalseButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_science);
}
}
当你将这两个新变量引入你的类时,AndroidStudio 会给出错误,说不能解析符号【按钮】,因为类Button
必须导入我们的类才能使用。点击文本Button
并按选项+返回如果你使用的是 Macbook,按 Alt +回车如果你是 Windows 用户,命令 Android Studio 自动为你导入类。记住这个快捷方式以备将来使用。
获取小部件引用并设置侦听器
变量创建只是一个开始,我们现在必须将 Button 小部件引用分配给这些变量,然后设置监听器,来监听这个事件上的 click 事件。
为了引用布局 xml 中定义的任何小部件,我们使用findViewById
方法,其语法为:
public View *findViewById*(int id)
该方法以小部件的资源 id(定义为属性android:id
)为参数,返回一个View
对象。
在ScienceActivity.java
类中,使用Button
小部件的资源 id 来获取视图对象,并将它们分配给您的成员变量。您必须将返回的View
对象转换为Button
对象。每当您引用活动类中布局 xml 中定义的任何小部件时,总是需要将返回的视图对象转换为相应的小部件。
public class ScienceActivity extends AppCompatActivity {
private Button mTrueButton;
private Button mFalseButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_science);
mTrueButton = (Button) findViewById(R.id.true_button);
mFalseButton = (Button) findViewById(R.id.false_button);
}
}
安卓应用是事件驱动的,因此一旦一个活动加载了一个布局,它将保持这种状态,直到被任何事件指示改变。这些事件可以是任何事情,人类接触,操作系统启动,定时器事件等。名为侦听器的对象被附加到一个小部件上,使该小部件可以侦听任何事件,侦听器为该事件实现一个侦听器接口。安卓为各种事件提供监听器接口。在我们的例子中,因为我们必须监听“点击”事件,所以我们将让我们的监听器实现View.OnClickListener
接口。
mTrueButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Does nothing yet, but soon!
}
});
添加 aboe 代码,就在您使用findViewById
方法将小部件引用分配给我们的mTrueButton
成员变量的那一行的下面。然后同样地把一个听众也连接到mFalseButton
上。上面的侦听器实现为 Java 匿名内部类。
点击时显示消息
现在我们已经将监听器连接到我们的按钮,我们将知道用户何时点击“真”或“假”按钮。我们将在侦听器接口实现的相应onClick()
方法中编写显示消息的代码。
安卓提供了一种非常简单的显示消息的方式,不需要任何输入或动作,它被称为Toast
。因此,我们将基于按钮按压创建显示Correct!
或Incorrect!
的Toast
。以下是用于创建Toast
的方法:
<
public static Toast makeText(Context context, int resId, int duration)
在此,Context
将会以我们的活动为例(Activity
是Context
的子片段)。第二个参数是字符串消息的资源标识,将显示在Toast
中。因此,我们将不得不在我们的strings.xml
文件中增加两个条目,一个用于Correct!
,第二个用于Incorrect!
。将下面几行添加到strings.xml
文件中。
<string name="correct_toast">*Correct!*</string>
<string name="incorrect_toast">*Incorrect!*</string>
现在添加代码,在mTrueButton
和mFalseButton
的onClick()
方法中创建Toast
。我们将向您展示如何为一个按钮做,为另一个按钮自己做。
mTrueButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(ScienceActivity.this,
R.string.correct_toast,Toast.LENGTH_SHORT).show();
}
});
方法show()
用于显示创建的Toast
。要导入Toast
类,只需按下选项+返回为 Mac 和 Alt +输入为 Windows 自动导入所需的类。
注意:如果我们只是用this
来引用makeText
方法中的ScienceActivity
,那就行不通了,因为这里的this
会引用View.OnClickListener
对象,因为这一切都是在匿名内部类内部完成的。
是时候运行我们的应用了
您可以使用模拟器来运行应用,但我们建议您使用真实的设备来运行应用。只需将安卓智能手机连接到电脑上,AndroidStudio 就会自动检测到它,然后点击运行按钮(绿色播放按钮)。
啊!你的第二个安卓应用正在运行,尽情享受吧!
秒表安卓应用项目——第 1 部分
原文:https://www.studytonight.com/android/stopwatch-android-app-project-part-1
在本教程中,我们将一步一步制作一个简单的秒表安卓应用,并在教程中学习一些关于安卓应用开发的基本知识。本教程由 3 部分组成,如下所示:
第 1 部分:秒表安卓 App 项目设置
第二部分: 秒表安卓 App UI
第 3 部分: 秒表安卓应用-对功能进行编码
最终的应用如下所示:
秒表应用项目简介:
秒表是一个用来记录或测量时间的简单应用。主要有以下 4 个主要功能:
-
开始:从开始或从暂停状态开始计时。
-
停止:停止秒表时间,将时间归零。
-
暂停:暂停秒表时间
-
圈速:记录秒表计时的圈数(例如在比赛过程中我们可以使用圈速功能记录比赛中不同参与者的时长)
创建项目
-
打开你的 AndroidStudio 点击“开始一个新的 AndroidStudio 项目”(学习如何设置 AndroidStudio创建你的第一个安卓项目)
-
从项目模板窗口中选择空活动,点击下一步
-
输入 App 名称、包名、保存位置、语言(Java/T11】Kotlin 语言 ,本教程我们使用 Java )和最小 SDK (我们使用的是 API 19: Android 4.4 (KitKat))
-
填写以上详细信息后,点击完成按钮
-
现在等待项目完成建设。
添加所需文件
-
为了使我们的应用的用户界面更具吸引力,我们将在我们的应用中添加 CardView 为此,我们必须在我们的应用中实现****card view 库,为此,请遵循以下步骤。
转到梯度脚本- >构建.梯度(模块:应用)部分并导入下面的依赖项,然后单击顶部显示的“立即同步:
dependencies { //Adding the card view library implementation 'androidx.cardview:cardview:1.0.0' }
我们正在添加 cardview,以使我们的应用的用户界面更具吸引力,并给它一个专业的外观,我们还将在整个教程中了解更多关于 card view 及其属性的信息。
-
现在,我们将添加秒表应用中所需的基本颜色,为此,我们遵循以下步骤转到应用- > res - >值- > colors.xml ,然后在 colors.xml 文件中添加以下颜色:
<?xml version = "1.0" encoding = "utf-8"?> <resources> <color name = "colorPrimary">#1989C8</color> <color name = "colorPrimaryDark">#1989C8</color> <color name = "colorAccent">#FF0D3D</color> <color name = "textColor">#0B1A37</color> <color name = "white">#ffffff</color> </resources>
-
接下来,我们将添加一些应用所需的图标和图像,只需下载以下图像并将其粘贴到 app - > res - >可绘制文件夹中
有了这个,我们都准备开始编写我们的秒表安卓应用的实际代码。在下一部分中,我们将为我们的秒表安卓应用创建完整的用户界面,然后开始工作。
秒表安卓应用项目——第 2 部分
原文:https://www.studytonight.com/android/stopwatch-android-app-project-part-2
在这一部分,我们将制作秒表安卓应用的用户界面。在这个项目的第一部分,我们为秒表安卓应用创建了基本项目结构。正如我们所知,一个活动的默认布局由一个带有文本 Hello World 的约束布局和一个 TextView
组成!,因此我们将不得不改变它,因为我们正在构建一个停止观察应用。对于我们的应用,我们将设置如下图所示的屏幕,为此,我们需要以下视图和布局:
从文件 activity_main.xml
中移除现有的 XML 代码,并在布局文件中编写以下代码。
<?xml version = "1.0" encoding = "utf-8" ?>
<RelativeLayout
xmlns:android = "http://schemas.android.com/apk/res/android"
xmlns:app = "http://schemas.android.com/apk/res-auto"
xmlns:tools = "http://schemas.android.com/tools"
android:layout_width = "match_parent"
android:layout_height = "match_parent"
tools:context = ".MainActivity">
<!-- Main Scroll View -->
<ScrollView
android:layout_width = "match_parent"
android:layout_height = "wrap_content">
<LinearLayout
android:layout_marginBottom = "0dp"
android:layout_marginTop = "8dp"
android:layout_marginRight = "4dp"
android:layout_marginLeft = "4dp"
android:orientation = "vertical"
android:layout_width = "match_parent"
android:layout_height = "wrap_content">
<!-- Outter Card View -->
<androidx.cardview.widget.CardView
android:id = "@+id/card_clock"
android:elevation = "24dp"
app:cardElevation = "24dp"
app:cardCornerRadius = "24dp"
android:layout_marginTop = "20dp"
android:layout_marginRight = "20dp"
android:layout_marginLeft = "20dp"
android:layout_width = "match_parent"
android:layout_height = "600dp">
<RelativeLayout
android:layout_width = "match_parent"
android:layout_height = "match_parent">
<!-- Stopwatch icon image view -->
<ImageView
android:layout_marginLeft = "16dp"
android:layout_marginTop = "14dp"
android:src = "@drawable/swicon"
android:layout_width = "48dp"
android:layout_height = "48dp"/>
<!-- stop watch text view parent -->
<androidx.cardview.widget.CardView
android:layout_marginTop = "8dp"
android:layout_alignParentTop = "true"
android:layout_centerInParent = "true"
android:foregroundGravity = "center"
app:cardCornerRadius = "20dp"
app:cardElevation = "8dp"
app:cardBackgroundColor = "@color/colorPrimary"
android:layout_width = "200dp"
android:layout_height = "64dp">
<!-- stop watch text -->
<TextView
android:textAllCaps = "true"
android:textAlignment = "center"
android:textStyle = "bold"
android:textColor = "@color/whiteColor"
android:layout_marginBottom = "8dp"
android:id = "@+id/title"
android:layout_alignParentTop = "true"
android:layout_marginTop = "8dp"
android:gravity = "center"
android:layout_gravity = "center_horizontal"
android:textSize = "32dp"
android:fontFamily = "sans-serif-condensed-medium"
android:text = "Stop Watch "
android:layout_width = "match_parent"
android:layout_height = "match_parent"/>
</androidx.cardview.widget.CardView>
<!-- stop watch time parent card view -->
<androidx.cardview.widget.CardView
app:cardCornerRadius = "180dp"
android:elevation = "40dp"
app:cardElevation = "40dp"
android:layout_centerInParent = "true"
android:layout_width = "240dp"
android:layout_height = "240dp">
<!-- stopwatch time without ms text view -->
<TextView
android:textAlignment = "center"
android:textStyle = "bold"
android:layout_centerInParent = "true"
android:layout_marginLeft = "8dp"
android:layout_marginRight = "8dp"
android:gravity = "center"
android:text = "0:00:00"
android:layout_gravity = "center"
android:textColor = "@color/textColor"
android:id = "@+id/time_view"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:textSize = "56sp" />
<!-- stopwatch time with ms text view -->
<TextView
android:textAlignment = "center"
android:textStyle = "bold"
android:layout_marginTop = "60dp"
android:id = "@+id/time_view_ms"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:layout_gravity = "center"
android:layout_marginLeft = "8dp"
android:layout_marginRight = "8dp"
android:gravity = "center"
android:text = "00"
android:textColor = "@color/textColor"
android:textSize = "24sp" />
</androidx.cardview.widget.CardView>
<!-- Linear layout containing the start ,stop ,pause ,lap image view -->
<LinearLayout
android:layout_marginBottom = "8dp"
android:layout_centerInParent = "true"
android:layout_alignParentBottom = "true"
android:orientation = "horizontal"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content">
<!-- time lapse image view -->
<ImageView
android:focusable = "true"
android:visibility = "gone"
android:clickable = "true"
android:layout_margin = "8dp"
android:src = "@drawable/lap_icon"
android:id = "@+id/timeLapseBtn"
android:layout_width = "80dp"
android:layout_height = "80dp" />
<!-- time pause image view -->
<ImageView
android:focusable = "true"
android:clickable = "true"
android:visibility = "gone"
android:layout_margin = "8dp"
android:src = "@drawable/pause_icon"
android:id = "@+id/pauseBtn"
android:layout_width = "80dp"
android:layout_height = "80dp" />
<!-- time stop image view -->
<ImageView
android:focusable = "true"
android:clickable = "true"
android:visibility = "gone"
android:layout_margin = "8dp"
android:src = "@drawable/stop_icon"
android:id = "@+id/stopBtn"
android:layout_width = "80dp"
android:layout_height = "80dp" />
<!-- time play image view -->
<ImageView
android:focusable = "true"
android:clickable = "true"
android:layout_margin = "8dp"
android:src = "@drawable/play_icon"
android:id = "@+id/playBtn"
android:layout_width = "80dp"
android:layout_height = "80dp" />
</LinearLayout>
</RelativeLayout>
</androidx.cardview.widget.CardView>
<!-- lap time card view parent -->
<androidx.cardview.widget.CardView
android:paddingTop = "8dp"
android:layout_marginBottom = "20dp"
android:elevation = "24dp"
app:cardElevation = "24dp"
app:cardCornerRadius = "8dp"
android:layout_marginTop = "16dp"
android:layout_marginRight = "20dp"
android:layout_marginLeft = "20dp"
android:layout_width = "match_parent"
android:layout_height = "wrap_content">
<!-- lap time title -->
<TextView
android:layout_marginTop = "4dp"
android:textStyle = "bold"
android:textSize = "24dp"
android:layout_marginLeft = "12dp"
android:text = "Time Laps"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"/>
<!-- scroll view conatining the lap text view -->
<ScrollView
android:layout_marginTop = "32dp"
android:layout_width = "match_parent"
android:layout_height = "wrap_content">
<LinearLayout
android:orientation = "vertical"
android:layout_width = "match_parent"
android:layout_height = "wrap_content">
<!-- lap text view -->
<TextView
android:padding = "16dp"
android:id = "@+id/timeLapse"
android:isScrollContainer = "true"
android:layout_below = "@id/title"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"/>
</LinearLayout>
</ScrollView>
</androidx.cardview.widget.CardView>
</LinearLayout>
</ScrollView>
</RelativeLayout>
现在上面的 activity_main.xml 看起来像
现在我们来讨论一下上面的 UI。它由 4 个部分组成,包含在垂直滚动视图中:
1.标题部分-秒表应用:
这部分包含一个ImageView
和一个TextView
。
<!-- Stopwatch icon image view -->
<ImageView
android:layout_marginLeft = "16dp"
android:layout_marginTop = "14dp"
android:src = "@drawable/swicon"
android:layout_width = "48dp"
android:layout_height = "48dp"/>
<!-- stop watch text view parent -->
<androidx.cardview.widget.CardView
android:layout_marginTop = "8dp"
android:layout_alignParentTop = "true"
android:layout_centerInParent = "true"
android:foregroundGravity = "center"
app:cardCornerRadius = "20dp"
app:cardElevation = "8dp"
app:cardBackgroundColor = "@color/colorPrimary"
android:layout_width = "200dp"
android:layout_height = "64dp">
<!-- stop watch text -->
<TextView
android:textAllCaps = "true"
android:textAlignment = "center"
android:textStyle = "bold"
android:textColor = "@color/whiteColor"
android:layout_marginBottom = "8dp"
android:id = "@+id/title"
android:layout_alignParentTop = "true"
android:layout_marginTop = "8dp"
android:gravity = "center"
android:layout_gravity = "center_horizontal"
android:textSize = "32dp"
android:fontFamily = "sans-serif-condensed-medium"
android:text = "Stop Watch "
android:layout_width = "match_parent"
android:layout_height = "match_parent"/>
</androidx.cardview.widget.CardView>
上面的代码将创建以下用户界面:
2.时间部分-秒表应用:
这部分用户界面包含一个显示时间的TextView
,单位为 小时:分钟:秒 ,另一个TextView
显示毫秒。我们创建TextView
的ids
来在TextView
中显示时间,稍后我们将在MainActivity.java中使用它来显示时间。
<!-- stop watch time parent card view -->
<androidx.cardview.widget.CardView
app:cardCornerRadius = "180dp"
android:elevation = "40dp"
app:cardElevation = "40dp"
android:layout_centerInParent = "true"
android:layout_width = "240dp"
android:layout_height = "240dp">
<!-- stopwatch time without ms text view -->
<TextView
android:textAlignment = "center"
android:textStyle = "bold"
android:layout_centerInParent = "true"
android:layout_marginLeft = "8dp"
android:layout_marginRight = "8dp"
android:gravity = "center"
android:text = "0:00:00"
android:layout_gravity = "center"
android:textColor = "@color/textColor"
android:id = "@+id/time_view"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:textSize = "56sp" />
<!-- stopwatch time with ms text view -->
<TextView
android:textAlignment = "center"
android:textStyle = "bold"
android:layout_marginTop = "60dp"
android:id = "@+id/time_view_ms"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:layout_gravity = "center"
android:layout_marginLeft = "8dp"
android:layout_marginRight = "8dp"
android:gravity = "center"
android:text = "00"
android:textColor = "@color/textColor"
android:textSize = "24sp" />
</androidx.cardview.widget.CardView>
上面的代码将创建以下用户界面:
3.互动部分-秒表应用:
这部分界面包含了开始、暂停、停止和重叠控制的所有ImageView
。在本例中,我们仅显示开始 I ImageView
,并隐藏所有其他ImageView
(重叠、暂停、停止)。我们还为开始、停止、暂停、第一圈创建了不同的id,稍后我们将在MainActivity.java中使用这些 id 来控制秒表。
<!-- Linear layout containing the start ,stop ,pause ,lap image view -->
<LinearLayout
android:layout_marginBottom = "8dp"
android:layout_centerInParent = "true"
android:layout_alignParentBottom = "true"
android:orientation = "horizontal"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content">
<!-- time lapse image view -->
<ImageView
android:focusable = "true"
android:clickable = "true"
android:visibility = "gone"
android:layout_margin = "8dp"
android:src = "@drawable/lap_icon"
android:id = "@+id/timeLapseBtn"
android:layout_width = "80dp"
android:layout_height = "80dp" />
<!-- time pause image view -->
<ImageView
android:focusable = "true"
android:clickable = "true"
android:visibility = "gone"
android:layout_margin = "8dp"
android:src = "@drawable/pause_icon"
android:id = "@+id/pauseBtn"
android:layout_width = "80dp"
android:layout_height = "80dp" />
<!-- time stop image view -->
<ImageView
android:focusable = "true"
android:clickable = "true"
android:visibility = "gone"
android:layout_margin = "8dp"
android:src = "@drawable/stop_icon"
android:id = "@+id/stopBtn"
android:layout_width = "80dp"
android:layout_height = "80dp" />
<!-- time play image view -->
<ImageView
android:focusable = "true"
android:clickable = "true"
android:layout_margin = "8dp"
android:src = "@drawable/play_icon"
android:id = "@+id/playBtn"
android:layout_width = "80dp"
android:layout_height = "80dp" />
</LinearLayout>
上面的代码将创建以下用户界面:
4.膝盖部分-秒表应用:
它包含用于显示流逝时间的用户界面。我们创建一个id
延时,稍后我们将在MainActivity.java中使用它来显示延时:
<!-- lap time card view parent -->
<androidx.cardview.widget.CardView
android:paddingTop = "8dp"
android:layout_marginBottom = "20dp"
android:elevation = "24dp"
app:cardElevation = "24dp"
app:cardCornerRadius = "8dp"
android:layout_marginTop = "16dp"
android:layout_marginRight = "20dp"
android:layout_marginLeft = "20dp"
android:layout_width = "match_parent"
android:layout_height = "wrap_content">
<!-- lap time title -->
<TextView
android:layout_marginTop = "4dp"
android:textStyle = "bold"
android:textSize = "24dp"
android:layout_marginLeft = "12dp"
android:text = "Time Laps"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"/>
<!-- scroll view conatining the lap text view -->
<ScrollView
android:layout_marginTop = "32dp"
android:layout_width = "match_parent"
android:layout_height = "wrap_content">
<LinearLayout
android:orientation = "vertical"
android:layout_width = "match_parent"
android:layout_height = "wrap_content">
<!-- lap text view -->
<TextView
android:padding = "16dp"
android:id = "@+id/timeLapse"
android:isScrollContainer = "true"
android:layout_below = "@id/title"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"/>
</LinearLayout>
</ScrollView>
</androidx.cardview.widget.CardView>
上面的代码将创建以下用户界面:
现在我们的用户界面已经完成,在本项目教程的下一部分,我们将在 MainActivity 类中编写逻辑,将所有功能添加到我们的秒表安卓应用中。
秒表安卓应用项目——第 3 部分
原文:https://www.studytonight.com/android/stopwatch-android-app-project-part-3
这是我们在 AndroidStudio 制作秒表安卓应用系列的最后一部分,也是这个项目中最重要的一部分。
如果您还没有完成前两部分,请在继续之前完成:
在这一部分,我们将为秒表的所有功能编写登录,以使应用根据我们的需要工作。因此,在进入编码部分之前,我们必须了解一些基本情况,如下所示:
-
1 秒= 1000 毫秒
-
1 分钟= 60 秒
-
1 小时=60 分钟
秒表安卓应用——为逻辑编码
现在打开MainActivity.java文件,导入一些基础类,如下图:
//importing required classes
import android.os.Handler;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.Locale;
接下来我们在 MainActivity 类中创建AndroidImageView和AndroidTextview的对象如下所示:
//creating object of ImageView and Text View
ImageView playBtn, pauseBtn, stopBtn, timeLapseBtn;
TextView timeView;
TextView timeViewms;
TextView timeLapse;
接下来我们在MainActivity.java类中加入整数变量和布尔变量,如下所示:
// integers to store hours, minutes, seconds, ms
int hours, minutes, secs, ms;
// integer to store seconds
private int seconds = 0;
// boolean to check if the stopwatch is running or not
private boolean running;
// simple count variable to count number of laps
int lapCount=0;
现在在onCreate
方法里面我们初始化 ImageView 和 TextView 并添加OnClickListener
并显示一条简单的安卓吐司消息给用户根据输入如下所示:
// initializing the Image view objects
playBtn=(ImageView)findViewById(R.id.playBtn) ;
pauseBtn=(ImageView)findViewById(R.id.pauseBtn) ;
stopBtn=(ImageView)findViewById(R.id.stopBtn) ;
timeLapseBtn=(ImageView)findViewById(R.id.timeLapseBtn) ;
// initializing the text view objects
timeView = (TextView)findViewById(R.id.time_view) ;
timeViewms=(TextView)findViewById(R.id.time_view_ms) ;
timeLapse = (TextView)findViewById(R.id.timeLapse) ;
// play button click listener
playBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//showing simple toast message to user
Toast.makeText(MainActivity.this, "Started", Toast.LENGTH_SHORT).show();
// hide the play and stop button
playBtn.setVisibility(View.GONE) ;
stopBtn.setVisibility(View.GONE) ;
// show the pause and time lapse button
pauseBtn.setVisibility(View.VISIBLE) ;
timeLapseBtn.setVisibility(View.VISIBLE) ;
// set running true
running = true ;
}
}) ;
// pause button click listener
pauseBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//showing simple toast message to user
Toast.makeText(MainActivity.this, "Paused", Toast.LENGTH_SHORT).show();
// show the play and stop button
playBtn.setVisibility(View.VISIBLE) ;
stopBtn.setVisibility(View.VISIBLE) ;
// hide the pause and time lapse button
timeLapseBtn.setVisibility(View.GONE) ;
pauseBtn.setVisibility(View.GONE) ;
running = false ;
}
}) ;
// stop button click listener
stopBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//showing simple toast message to user
Toast.makeText(MainActivity.this, "Stoped", Toast.LENGTH_SHORT).show();
// set running to false
running = false ;
seconds = 0 ;
lapCount=0 ;
// setting the text view to zero
timeView.setText("00:00:00") ;
timeViewms.setText("00") ;
timeLapse.setText("") ;
// show the play
playBtn.setVisibility(View.VISIBLE) ;
// hide the pause , stop and time lapse button
pauseBtn.setVisibility(View.GONE) ;
stopBtn.setVisibility(View.GONE) ;
timeLapseBtn.setVisibility(View.GONE) ;
}
}) ;
// lap button click listener
timeLapseBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// calling timeLapse function
timeLapseFun() ;
}
}) ;
// calling runtimer
runTimer() ;
现在在里面创建一个方法private void runTimer
,当我们点击如下所示的开始按钮时调用该方法:
private void runTimer() {
// creating handler
final Handler handlertime = new Handler();
// creating handler
final Handler handlerMs = new Handler();
handlertime.post(new Runnable() {@Override
public void run() {
hours = seconds / 3600;
minutes = (seconds % 3600) / 60;
secs = seconds % 60;
// if running increment the seconds
if (running) {
String time = String.format(Locale.getDefault(), "%02d:%02d:%02d", hours, minutes, secs);
timeView.setText(time);
seconds++;
}
handlertime.postDelayed(this, 1000);
}
});
handlerMs.post(new Runnable() {@Override
public void run() {
if (ms >= 99) {
ms = 0;
}
// if running increment the ms
if (running) {
String msString = String.format(Locale.getDefault(), "%02d", ms);
timeViewms.setText(msString);
ms++;
}
handlerMs.postDelayed(this, 1);
}
});
}
我们在MainActivity.java内部又创建了一个方法来处理圈速,如下所示:
void timeLapseFun() {
// increase lap count when function is called
lapCount++;
String laptext = String.format(Locale.getDefault(), "%02d:%02d:%02d", hours, minutes, secs);
String msString = String.format(Locale.getDefault(), "%02d", ms);
// adding ms to lap text
laptext = laptext + ":" + msString;
if (lapCount >= 10) {
laptext = " Lap " + lapCount + " -------------> " + laptext + " \n " + timeLapse.getText();
} else {
laptext = " Lap " + lapCount + " ---------------> " + laptext + " \n " + timeLapse.getText();
}
//showing simple toast message to user
Toast.makeText(MainActivity.this, "Lap " + lapCount, Toast.LENGTH_SHORT).show();
// showing the lap text
timeLapse.setText(laptext);
}
MainActivity.java的完整代码如下:
package com.studytonight.project;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
// importing required classes
import android.os.Handler;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
// integers to store hours , minutes , seconds , ms
int hours,
minutes,
secs,
ms;
// integer to store seconds
private int seconds = 0;
// boolean to check if stopwatch is running or not
private boolean running;
// simple count variable to count number of laps
int lapCount = 0;
// creating object of ImageView and Text View
ImageView playBtn,
pauseBtn,
stopBtn,
timeLapseBtn;
TextView timeView;
TextView timeViewms;
TextView timeLapse;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// initializing the Image view objects
playBtn = (ImageView) findViewById(R.id.playBtn);
pauseBtn = (ImageView) findViewById(R.id.pauseBtn);
stopBtn = (ImageView) findViewById(R.id.stopBtn);
timeLapseBtn = (ImageView) findViewById(R.id.timeLapseBtn);
// initializing the text view objects
timeView = (TextView) findViewById(R.id.time_view);
timeViewms = (TextView) findViewById(R.id.time_view_ms);
timeLapse = (TextView) findViewById(R.id.timeLapse);
// play button click listener
playBtn.setOnClickListener(new View.OnClickListener() {@Override
public void onClick(View view) {
//showing simple toast message to user
Toast.makeText(MainActivity.this, "Started", Toast.LENGTH_SHORT).show();
// hide the play and stop button
playBtn.setVisibility(View.GONE);
stopBtn.setVisibility(View.GONE);
// show the pause and time lapse button
pauseBtn.setVisibility(View.VISIBLE);
timeLapseBtn.setVisibility(View.VISIBLE);
// set running true
running = true;
}
});
// pause button click listener
pauseBtn.setOnClickListener(new View.OnClickListener() {@Override
public void onClick(View view) {
//showing simple toast message to user
Toast.makeText(MainActivity.this, "Paused", Toast.LENGTH_SHORT).show();
// show the play and stop button
playBtn.setVisibility(View.VISIBLE);
stopBtn.setVisibility(View.VISIBLE);
// hide the pause and time lapse button
timeLapseBtn.setVisibility(View.GONE);
pauseBtn.setVisibility(View.GONE);
running = false;
}
});
// stop button click listener
stopBtn.setOnClickListener(new View.OnClickListener() {@Override
public void onClick(View view) {
//showing simple toast message to user
Toast.makeText(MainActivity.this, "Stoped", Toast.LENGTH_SHORT).show();
// set running to false
running = false;
seconds = 0;
lapCount = 0;
// setting the text view to zero
timeView.setText("00:00:00");
timeViewms.setText("00");
timeLapse.setText("");
// show the play
playBtn.setVisibility(View.VISIBLE);
// hide the pause , stop and time lapse button
pauseBtn.setVisibility(View.GONE);
stopBtn.setVisibility(View.GONE);
timeLapseBtn.setVisibility(View.GONE);
}
});
// lap button click listener
timeLapseBtn.setOnClickListener(new View.OnClickListener() {@Override
public void onClick(View view) {
// calling timeLapse function
timeLapseFun();
}
});
// calling runtimer
runTimer();
}
private void runTimer() {
// creating handler
final Handler handlertime = new Handler();
// creating handler
final Handler handlerMs = new Handler();
handlertime.post(new Runnable() {@Override
public void run() {
hours = seconds / 3600;
minutes = (seconds % 3600) / 60;
secs = seconds % 60;
// if running increment the seconds
if (running) {
String time = String.format(Locale.getDefault(), "%02d:%02d:%02d", hours, minutes, secs);
timeView.setText(time);
seconds++;
}
handlertime.postDelayed(this, 1000);
}
});
handlerMs.post(new Runnable() {@Override
public void run() {
if (ms >= 99) {
ms = 0;
}
// if running increment the ms
if (running) {
String msString = String.format(Locale.getDefault(), "%02d", ms);
timeViewms.setText(msString);
ms++;
}
handlerMs.postDelayed(this, 1);
}
});
}
void timeLapseFun() {
// increase lap count when function is called
lapCount++;
String laptext = String.format(Locale.getDefault(), "%02d:%02d:%02d", hours, minutes, secs);
String msString = String.format(Locale.getDefault(), "%02d", ms);
// adding ms to lap text
laptext = laptext + ":" + msString;
if (lapCount >= 10) {
laptext = " Lap " + lapCount + " -------------> " + laptext + " \n " + timeLapse.getText();
} else {
laptext = " Lap " + lapCount + " ---------------> " + laptext + " \n " + timeLapse.getText();
}
//showing simple toast message to user
Toast.makeText(MainActivity.this, "Lap " + lapCount, Toast.LENGTH_SHORT).show();
// showing the lap text
timeLapse.setText(laptext);
}
}
输出:
在下面的快照中,您可以看到秒表在安卓应用中的外观。
首次打开应用时:
当我们点击开始:
当我们点击暂停时:
当我们点击圈图标时(我们已经记录了 12 圈)
当我们点击停止图标时:
结论:
有了这个,我们成功地完成了秒表项目。如果这个项目帮助了你,那就在 Instagram - @study .今夜找到我们,和我们分享你的项目快照。祝贺你完成了这个项目。
Kotlin
Kotlin 基础知识
Kotlin 简介
原文:https://www.studytonight.com/kotlin/introduction-to-kotlin
欢迎来到 Kotlin 教程系列。Kotlin 是一种针对 Java 平台的相对较新的编程语言。我们几乎可以在 Java 的任何地方使用 Kotlin。Kotlin 可用于开发服务器端应用、安卓应用、数据科学领域等。Kotlin 代码也可以转换成 JavaScript 代码。有一些 Java 的背景知识是好的,但是如果你没有 Java 的任何先验知识,那就不成问题了。
Kotlin 具有代码简洁、空安全、实用等特点。它也完全可以与 Java 互操作。因此,它也支持所有现有的 Java 库和框架。
Kotlin 历史
Kotlin 语言是由 JetBrains(开发著名的 Java IDE IntelliJ IDEA 的同一家公司)在 2010 年创建的。自 2012 年以来,它一直是开源的。
Kotlin 得名于俄罗斯一个名叫Kotlin 岛的岛屿。kotlin 的第一个版本于 2016 年发布,最新版本(2020 年)是 Kotlin v1.3。
Kotlin 版本简史:
-
Kotlin v1.0,Kotlin 的第一个版本于 2016 年 2 月发布。它正式成为 Kotlin 的第一个稳定版本。
-
Kotlin v1.1 于 2017 年 3 月发布。这个版本中增加的主要特性是引入了与 JavaScript 的互操作性和对 coroutines 的支持(虽然不稳定)。现在开发人员可以将 Kotlin 代码编译成 JS,并在浏览器中运行。
-
Kotlin 的下一个版本 Kotlin v1.2 于 2017 年 11 月发布。它允许开发人员在不同平台之间共享相同的代码。我们可以一次性编写您的应用的业务逻辑,并在我们的应用的所有层中重用它——后端、浏览器前端和安卓移动应用。
-
Kotlin v1.3 于 2018 年 10 月发布。在这个版本中,协同程序变得稳定。现在读和写阻塞代码更容易了。
-
Kotlin v1.4 正在开发中,将于 2020 年发布。
2017 年,由于越来越受欢迎,谷歌宣布对 Kotlin 提供一流的支持。2019 年,谷歌将 Kotlin 编程语言作为安卓应用开发的首选语言。
Kotlin 的特点
Kotlin 提供了比 Java 更多的特性。Kotlin 优于其他语言的主要特点是:
1.简洁的代码
代码的大小在开发人员的生活中起着重要的作用。假设你加入了一家公司,在那里你被分配了一项任务,用新的功能替换旧的功能或者可能修复它。你需要做的第一件事是检查代码库。如前所述,如果代码库的大小很大,那么您将花费比编写代码更多的时间来理解代码。代码越简单简洁,你理解它的速度就越快。
Kotlin 确保每一行代码都带有某种意义。在 Java 中需要的所有样板代码,比如获取器、设置器、给字段分配构造器参数等等,在 Kotlin 中都是不需要的。
2.空保险箱
Kotlin 确保我们的程序在运行时不会抛出 NullPointerException 。Kotlin 的类型系统跟踪可以为空的值。如果对该值执行任何操作,这可能导致空指针异常,Kotlin 禁止该操作,并给出错误以避免该错误。我们将在单独的章节中讨论更多关于 null 安全性的内容。
3.彼此协作的
这是 Kotlin 最令人钦佩的特征之一。Kotlin 与 Java 完全互操作。这意味着你可以在你的 Kotlin 代码库中使用 Java 库,调用 Java 方法,扩展 Java 类,实现 Java 接口等等。您可以用 Java 编写项目的一个类,用 Kotlin 编写另一个类。他们都将能够使用彼此的功能。
4.JavaScript 透明
您可以将您的 Kotlin 代码转换成 JavaScript 代码。因此,我们可以用 Kotlin 编写代码,将它转换成 JavaScript,并在浏览器上运行。但是它有一个缺点。当我们将 Kotlin 代码转换为 JS 时,项目中的所有代码以及使用的标准库都会转换为 JS 代码。但是它将排除任何使用的 Java 框架或库。因此,如果您使用 Java 库,这可能会导致问题。
Kotlin 还有其他特性,如扩展函数、命名参数和默认参数、数据类等。我们将在后面的章节中介绍它们。
摘要
在本教程中,我们快速了解了什么是 Kotlin 语言,讨论了它的历史并探索了它的特性。如果讨论的任何功能都没有意义,那就不要担心。我们稍后将详细探讨它们。
接下来,我们将看到如何为 Kotlin 设置 IDE,并在 Kotlin 中编写我们的第一个 hello-world 程序。
另读:-Java vs Kotlin:Kotlin 和 Java 有什么区别?
Kotlin 环境设置
原文:https://www.studytonight.com/kotlin/kotlin-environment-setup
在本教程中,我们将讨论如何在本地机器上设置 Kotlin 环境。您可以设置命令行工具来运行 Kotlin 程序,也可以安装 IntelliJ IDEA IDE(IDE)。
对于任何编程语言,最好使用 IDE,因为它比简单的文本编辑器提供了更多的功能。对于 Kotlin 来说,最流行的 IDE 是 IntelliJ IDEA。IntelliJ IDEA 是由开发 Kotlin 的同一家公司 JetBrains 建立的。
安装 IntelliJ IDEA
要设置 IntelliJ IDEA,请执行以下步骤:
- 首先进入 IntelliJ IDEA 的官方页面。你会看到这样的东西:
-
现在,选择您的操作系统并下载社区版本,如上图所示。
-
运行下载的可执行文件。您将看到此屏幕:
Click on Next.
-
再次点击下一步。如果你想安装在其他地方,选择目的地,然后点击下一步。
-
现在,将出现此窗口:
According to your system, select 32-bit launcher or 64-bit launcher . Select all other options and click on next.
-
点击安装,IDE 将成功安装。
您已经在系统中成功安装了 IntelliJ IDEA。如果你在 start 中搜索它,你就能看到它。
安装命令行编译器
如果您运行的是低配置系统(< = 1GB RAM),或者仍然想使用文本编辑器和命令行工具来运行 Kotlin 代码,这里有一个如何安装和运行命令行工具的指南。要运行 Kotlin 程序,您需要系统中的 Kotlin 编译器和 Java 开发工具包(JDK)。
首先,我们将下载并设置 Kotlin 编译器:
-
第一步是下载 Kotlin 编译器。打开这个 github 链接。你会看到这样的东西:
向下滚动并从资产部分下载“kotlin-编译器-xx”,如下所示:
-
解压缩下载的文件。
-
在提取的文件夹中,导航到 kotlinc 文件夹中的 bin 文件夹并复制路径。大概会是这样的:“C:\ Users \ Deepak \ Downloads \ kot Lin-编译器-1.3.72\kotlinc\bin”。我们必须将这个路径设置为环境变量。
-
在开始菜单中,键入“编辑系统环境变量”并将其打开。
-
该窗口将被打开:
-
单击环境变量。
-
在“系统变量”中找到变量“路径”,双击它。将出现一个新窗口。现在,点击“新建”按钮。在这里粘贴 bin 文件夹的路径,点击 ok 按钮。
现在我们下载并安装 Java 开发工具包(JDK):
-
打开这个链接下载 Java 开发工具包。你会看到一个类似这样的窗口:< =/p >
-
点击“JDK 下载”(用红色箭头标记)。将会打开一个新窗口。
-
根据您的操作系统向下滚动并下载合适的安装程序。对于 windows,请选择此选项:
-
解压缩下载的文件。
-
在提取的文件夹中,导航至箱文件夹并复制路径。大概会是这样的:“C:\ Users \ Deepak \ Downloads \ JDK-14 . 0 . 1 _ windows-x64 _ bin \ JDK-14 . 0 . 1 \ bin”。该路径也需要设置为环境变量。
-
按照相同的步骤将此路径设置为环境变量。
现在我们已经成功地设置了 Kotlin 编译器。要检查是否一切正常,请打开命令提示符,并键入以下命令:
kotlinc -help
如果你观察到这样的东西:
然后一切都按预期运行。
摘要
您已经成功安装了编写 Kotlin 程序的环境。我们将在下一个教程中开发我们的第一个项目和第一个程序。
第一个使用 IntelliJ IDEA 的 Kotlin 程序
原文:https://www.studytonight.com/kotlin/first-program-in-kotlin-using-intellij-idea
在上一个教程中,我们看到了如何在我们的系统中安装 IntelliJ idea。在本教程中,我们将看到如何在 IntelliJ IDEA IDE 中创建新项目,并在 Kotlin 中运行我们的第一个程序,该程序将在控制台上打印“ Hello World ”。
在 IntelliJ IDEA 中创建新项目
在 IntelliJ 中设置项目是运行任何 Kotlin 文件所必需的。按照以下步骤创建新项目:
-
转到开始,搜索 IntelliJ IDEA,然后打开它。如果您是第一次运行它,您可能会看到一些第一次设置,如导入设置,并选择一个黑暗或正常的主题。据此选择。
-
接下来,你会看到这个窗口:
-
点击“新建项目”。
-
从左侧面板选择 Kotlin,选择“ JVM| IDEA ”选项。点击下一步。
T3】 -
输入项目的名称。您可以编辑项目位置并提供自定义位置。
-
在左侧可以看到这样的项目结构:
-
右键点击 src 文件夹,选择新建>Kotlin 文件/类,点击回车。你会看到:
-
输入文件名“ HelloWorld ,点击回车。
您已经成功创建了一个新的 Kotlin 项目,并在其中创建了一个 Kotlin 文件。现在我们将在其中创建我们的第一个 Kotlin 程序。
Kotlin 的第一个节目
编写以下程序的是 HelloWorld.kt 文件:
fun main() {
println("Hello World")
}
说明:
-
第 1 行:每个 Kotlin 程序都以
main()
函数开始。使用 Kotlin 中的fun
关键字创建函数。我们将在后面的章节中阅读更多关于函数的内容。 -
第 2 行:
println()
功能用于在控制台上打印字符串。
要运行该程序,点击main()
功能旁边的绿色箭头,如下所示:
程序将被编译,输出将打印在控制台上:
摘要
在本文中,我们创建了一个 Kotlin 项目,并在 Kotlin 运行了我们的第一个程序。在下一个教程中,我们将看到如何通过命令行运行相同的程序。
如何使用编译器运行 Kotlin 程序
原文:https://www.studytonight.com/kotlin/how-to-run-kotlin-program-using-compiler
在本教程中,我们将看到如何使用编译器运行 Kotlin 程序。确保您已经在前面设置了 Kotlin 编译器。
Kotlin 的第一个节目
打开任何文本编辑器(记事本、崇高等)。)并创建一个 HelloWorld.kt 文件。确保该文件的扩展名为“”。kt ”。编写以下程序的是 HelloWorld.kt 文件:
fun main() {
println("Hello World")
}
说明:
-
第 1 行:每个 Kotlin 程序都以
main()
函数开始。在 Kotlin 中使用fun
关键字创建函数。我们将在后面的章节中阅读更多关于函数的内容。 -
第 2 行:
println()
功能用于在控制台上打印字符串。
通过命令行运行程序:
打开命令提示符,转到保存 Kotlin 程序的目录。编写以下命令,将 Kotlin 程序转换成 jar 文件:
kotlinc HelloWorld.kt -include-runtime -d HelloWorld.jar
说明:
-
Kotlinc :就是我们下载来运行 Kotlin 程序的命令行工具。
-
“hello world . kt”:是你的 Kotlin 程序文件的名字。
-
-include-runtime :默认情况下,Kotlin 编译成 Java。它将需要 Java 库在运行时运行。因此,为了包含 Kotlin 在运行时所需的库,我们编写了这个。
-
-d HelloWorld.jar :用这个名字,会创建一个 jar 文件。
要运行生成的 jar 文件,请编写以下命令:
java -jar HelloWorld.jar
你会看到“你好世界”印在控制台上。
摘要
在本教程中,我们看到了如何通过命令行运行程序。基本设置已经完成,我们将从下一个教程开始详细学习 Kotlin 的概念。
Kotlin 关键字和标识符
原文:https://www.studytonight.com/kotlin/kotlin-keywords-and-identifiers
每种编程语言都有特定的预定义词,它们带有某种特殊的含义。它们被称为关键字。关键字不能用作标识符。
标识符是变量、类、函数、接口等的名称。
例如,name
在这里是一个标识符:
val name: String = "emp_name"
然而,在 Kotlin 中,我们可以根据它们的类型使用一些关键字作为标识符。
关键字类型
Kotlin 中有两种类型的关键字:
-
硬关键字
-
软关键字
硬关键字
硬关键字不能用作标识符。如果将它们用作标识符,将会引发错误。
例如,在 HelloWorld 程序中,我们使用fun
关键字创建了一个函数。如果我们尝试创建一个名为fun
的变量,我们会得到一个错误。
*```kt
val fun = 5 // Error
Kotlin 的硬关键字是:
<caption>**Hard keywords**</caption>
| 为 | 断开 | 级 | 继续 |
| 做 | 否则 | 假 | 为 |
| 好玩 | 如果 | 中的 | 界面 |
| 存在 | 空 | 目标 | 包裹 |
| 返回 | 极好的 | 这个 | 投 |
| 真 | 试试 | 类型别名 | 类型 |
| val | 在处 | 当 | 而 |
### 软关键字
软关键字在特定的上下文中被视为关键字,只要它们适用。在其他情况下,它们可以用作标识符。例如,当我们设置类或成员的可见性时,private 被认为是关键字。在另一个上下文中,它可以用作标识符。
```kt
val private = 5 // No Error
Kotlin 中的软关键字是:
| 经过 | 哪个 | 构造器 | 代表 |
| 动态的 | 领域 | 文件 | 最后 |
| 得到 | 进口 | 初始化 | 参数 |
| 财产 | 接收器 | 设置 | 他们设定好了吗 |
| 在哪里 | 实际的 | 摘要 | 注释 |
| 同伴 | 常量 | 交叉内联 | 数据 |
| 列举型别 | 预期 | 外部 | 最后的 |
| 中缀 | 在一条直线上的 | 内部的 | 内部的 |
| 拉丁人 | 我们在网上 | 打开 | 操作员 |
| 在外 | 推翻 | 私人的 | 保护 |
| 公众的 | 使具体化 | 密封的 | 暂停 |
| 尾递归 | vararg 档 | | |
摘要
在本教程中,我们研究了关键字和标识符。我们将使用和研究本教程系列中的大多数关键字。
接下来,我们将研究 Kotlin 中的变量。
Kotlin 变量和常量
原文:https://www.studytonight.com/kotlin/kotlin-variables-and-constants
在本教程中,我们将讨论 Kotlin 中的变量。变量基本上是用来保存一些数据的内存位置。每个变量都被赋予一个唯一的名称,即它的标识符。
在 Kotlin 中,我们可以使用两个关键字声明一个变量:
-
英国压力单位
-
定义变量
Kotlin val
关键字
val
关键字用于声明一个“只读”变量,即一个不可变的变量。简单来说,无法将值重新分配给标有val
关键字的变量。
例如:
val name = "Hello"
name = "World!!" //Error: Val cannot be reassigned
当在一个变量的生命周期内,它只需要像创建一个类的对象一样被赋值一次时,建议使用val
。它还确保开发人员不会意外地将值重新分配给不应更改的变量。
Kotlin var
关键字
var
关键字用于声明可变的变量,即其值可以改变并重新分配给它的变量。
var name = "Hello"
println(name)
name = "World!!"
println(name)
你好
世界!!
Kotlin 常量
Kotlin 常量用于定义具有常量值的变量。const
关键字用于定义常量变量。const
关键字只能与val
关键字一起使用,不能与var
关键字一起使用。
const val empName = "employee_1"
println(empName)
员工 _1
如果我们试图用var
关键字声明一个常量,我们会得到错误:“修饰符‘const’不适用于‘vars’”
const
和val
的区别
val
和const
这两个关键字似乎在做同样的工作,即声明常量变量。但是它们之间有细微的差别。const
关键字用于声明编译时常量,而val
关键字可以声明运行时常量。让我们用一个例子来理解它:
假设我们声明了一个变量empName
,我们想给它赋值,这个值将由函数sayHello()
返回。如果我们使用val
关键字,我们将不会得到任何错误:
val empName = sayHello() // No error
fun sayHello():String{
return "Hello"
}
但是,如果我们用const
关键字声明这个变量,我们会得到一个错误,因为这个值将在运行时分配给empName
:
const val empName = sayHello() // we will get error
fun sayHello():String{
return "Hello"
}
因此,const
关键字用于声明变量,这些变量的值只有在编译时才知道。
摘要
在本教程中,我们讨论了 Kotlin 中的变量类型。我们也看到了const
关键字的使用以及val
和const
关键字的区别。在下一个教程中,我们将讨论 Kotlin 中的数据类型。
Kotlin 数据类型
Kotlin 是一种静态类型的语言。在静态类型语言中,变量的数据类型在编译时是已知的。这意味着,如果程序员想要定义一个字符串,它的数据类型必须是编译器在编译时知道的。静态类型语言的其他例子有:Java、Kotlin、C、C++。
在动态类型语言的编程语言中,变量的数据类型是在运行时确定的。动态类型语言的一些例子有 Python 、 JavaScript 、 PHP 。
因此,在 Kotlin 中,变量的数据类型必须在编译时为编译器所知,因为它是静态类型语言。但是如果您尝试运行以下代码,它将毫无错误地执行:
val marks = 5
println(marks)
Here we haven't mentioned any data type for
marks
variable, but it is executed successfully. It is because, Kotlin uses something called as Type Inference too, which means if the compiler can figure out what is the data type of the variable using type inference, then programmer need not to explicitly mention its type, the compiler will manage it itself.
我们可以通过这样声明变量来检查为声明的变量自动推断了哪些数据类型:
val subjects = 5
println("Data type of subjects: " + subjects::class.simpleName)
val marks = 47.5
println("Data type of marks: " + marks::class.simpleName)
val name = "Deepak"
println("Data type of name: " + name::class.simpleName)
受试者数据类型:Int
标记数据类型:Double
名称数据类型:String
Kotlin 中的数据类型
现在我们将讨论 Kotlin 中的基本数据类型。以下是支持的基本数据类型:
-
民数记
-
特性
-
布尔运算
-
数组
-
用线串
用数据类型定义变量的语法:
这里我们有定义指定数据类型的变量的基本语法:
val variable_name: datatype = value
因此,我们在 Kotlin 中主要使用val
关键字来声明变量,我们可以在变量名后面使用冒号来指定数据类型。我们将在下面讨论各种数据类型时看到示例。
1.Kotlin 数字
Kotlin 提供了一些内置的数据类型来表示数字。Kotlin 数可以是整数值或浮点数值。
对于整数,数据类型为:
-
字节
-
短的
-
(同 Internationalorganizations)国际组织
-
长的
下表给出了它们各自所占的范围和空间:
类型 | 大小(字节) | 最小值 | 最大值 |
---|---|---|---|
字节 | one | -128 | One hundred and twenty-seven |
短的 | Two | -32768 | Thirty-two thousand seven hundred and sixty-seven |
(同 Internationalorganizations)国际组织 | four | -2,147,483,648 | Two billion one hundred and forty-seven million four hundred and eighty-three thousand six hundred and forty-seven |
长的 | eight | -9,223,372,036,854,775,808 | 9,223,372,036,854,775,808 |
您可以根据要存储的数据所需的范围和内存来使用它们。下面是我们如何声明每一个:
val byte: Byte = 1
val short: Short = 1
val int: Int = 1
val long: Long = 1
-
如果不超过
Int
的最大值,所有积分变量都推断为Int
。 -
若要明确指定
Long
,请在该值中添加后缀 L 。
例如:
val normalNumber = 1
val explicitlyMarkedLong = 1L
val longByRange = 100000000000
println("Data type of normalNumber is: " + normalNumber::class.simpleName)
println("Data type of explicitlyMarkedLong is: " + explicitlyMarkedLong::class.simpleName)
println("Data type of longByRange is: " + longByRange::class.simpleName)
对于浮点数,提供的数据类型有:
-
浮动
-
两倍
它们的有效十进制位数不同:
类型 | 大小(字节) | 十进制数字 |
---|---|---|
浮动 | four | 6-7 |
两倍 | eight | 15-16 |
例如:
val marks: Float = 1.0f
val percentage: Double = 1.0
对于分数数据类型,编译器默认推断双数据类型。要明确指定浮动,请在值中添加后缀 f 或 F 作为后缀。
2.Kotlin 字符
Kotlin 中的字符使用 Char 关键字声明。字符应该放在单引号中,如‘a’。一个字符的大小是 4 位。
让我们举个例子:
val letter: Char = 'p'
与 Java 不同,数字在 Kotlin 中不能被视为字符:
val letter: Char = 65 // Error
3.Kotlin 布尔型
一个布尔变量用来表示两个值,或者真或者假。它们的用法与任何其他语言相同:
val isQualified: Boolean = true
val isPromoted: Boolean = false
4.Kotlin 数组
Kotlin 数组是相同数据类型的值的集合。如果我们想存储 7 个主题的标记,那么我们可以声明一个大小为 7 的数组,并保存其中的所有数字,而不是创建 7 个变量。
在 Kotlin 中,我们可以使用Array
类来声明一个数组。例如:
val marks: Array<Int> = arrayOf(10,9,2,7,8,6,10)
我们将在后面的章节中详细讨论数组。
5. 琴弦 Kotlin
一个字符串可以使用 Kotlin 中的字符串类来表示。字符串基本上是字符、单词或句子的集合,可以包含字符、数字、特殊字符,但所有内容都应该用双引号括起来。比如“嗨我是一根弦”就是一根弦。字符串总是在双引号内声明。
让我们举个例子:
val message: String = "Corona Go, Go Corona!!"
在编写任何程序时,字符串都非常有用。我们将在单独的教程中详细介绍 String 类。
摘要
在本教程中,我们学习了 Kotlin 中的静态类型和类型推断。我们还研究了 Kotlin 中存在的各种数据类型。我们将在单独的教程中详细讨论数组和字符串。
Kotlin 运算符
在本教程中,我们将讨论 Kotlin 运算符。运算符是用于对一个或多个操作数执行操作的特殊字符。
例如:
var num1: Int = 10
var num2: Int = 20
var sum: Int = num1 + num2
println(sum)
在上面的代码示例中,num1
和num2
是操作数,而+
是运算符。
Kotlin 有各种类型的运营商。它们分为以下几类:
-
算术运算符
-
比较运算符
-
赋值运算符
-
等式运算符
-
一元运算符
-
逻辑运算符
-
杂项操作员
现在,我们将详细讨论每一个。
1.算术运算符
Kotlin 中的算术运算符用于执行基本的数学运算,如加法、减法、乘法、除法和模数。
在下表中,我们列出了所有算术运算符,并给出了每个运算符的基本示例。
操作员 | 描述 | 表示 |
---|---|---|
+ |
两个变量相加 | a + b |
- |
两个变量的减法 | 美国罗克韦尔 |
* |
两个变量的乘法 | a * b |
/ |
两个变量的除法 | a / b |
% |
两个变量的模。当 a 除以 b 时,它将返回余数。 | a % b |
让我们举一个代码示例:
var num1: Int = 25
var num2: Int = 6
println("Sum: " + (num1 + num2))
println("Difference: " + (num1 - num2))
println("Multiplication: " + (num1 * num2))
println("Division: " + (num1 / num2))
println("Modulus: " + (num1 % num2))
和:31
差:19
乘:150
除:4
模:1
2.比较运算符
Kotlin 中的比较运算符用于比较变量。比较运算符根据比较结果返回真或假。
以下是 Kotlin 支持的比较运算符:
操作员 | 描述 | 表示 |
---|---|---|
< |
检查一个变量是否小于另一个变量。如果左边的操作数小于右边的操作数,则返回真,否则返回假。 | a < b |
> |
检查一个变量是否大于另一个变量。如果左边的操作数大于右边的操作数,则返回真,否则返回假。 | a > b |
<= |
检查一个变量是否小于或等于另一个变量。如果左边的操作数小于或等于右边的操作数,则返回真,否则返回假。 | a <= b |
>= |
检查一个变量是否大于或等于另一个变量。如果左边的操作数大于或等于右边的操作数,则返回真,否则返回假。 | a >= b |
让我们举一个代码示例:
var num1: Int = 25
var num2: Int = 6
println("Less than: " + (num1 < num2))
println("Greater than: " + (num1 > num2))
println("Less than or equal to: " + (num1 <= num2))
println("Greater than or equal to: " + (num1 >= num2))
小于:假
大于:真
小于或等于:假
大于或等于:真
3.赋值运算符
这些运算符用于给变量赋值。我们有一个简单赋值运算符和五个增广赋值运算符。
操作员 | 描述 | 表示 |
---|---|---|
= |
给变量赋值 | a = 10 |
+= |
向变量添加并赋值 | a+=b |
-= |
对变量进行减法运算并赋值 | a-=b |
*= |
将一个值相乘并赋给一个变量 | a*=b |
/= |
给变量赋值 | a/=b |
%= |
模数并为变量赋值 | a%=b |
让我们通过代码示例来理解赋值运算符:
var num1: Int = 25
var addAndAssign: Int = 0
addAndAssign += num1
println(addAndAssign)
var subAndAssign: Int = 40
subAndAssign -= num1
println(subAndAssign)
var multiplyAndAssign: Int = 1
multiplyAndAssign *= num1
println(multiplyAndAssign)
var divideAndAssign: Int = 50
divideAndAssign /= num1
println(divideAndAssign)
var modulusAndAssign: Int = 30
modulusAndAssign %= num1
println(modulusAndAssign)
25
15
25
2
5
4.等式运算符
这些运算符用于检查两个变量是否相等。我们有四个等式运算符。
操作员 | 描述 | 表示 |
---|---|---|
== |
检查两个对象是否相等,并返回 true | a == b |
!= |
检查两个对象是否不相等,并返回 true | a!= b |
=== |
检查两个变量是否引用同一个对象 | a === b |
!== |
检查两个变量是否引用了同一个对象 | a!== b |
运算符===
和!==
被称为参考等式运算符。它们检查变量是否引用同一个对象。
让我们举个例子,
val num1: Int = 25
var num2: Int = 25
println(num1 == num2)
println(num1 != num2)
num2 = num1
println(num1 === num2)
println(num1 !== num2)
真
假
真
假
5.一元运算符
一元运算符仅适用于一个操作数。下表包含所有一元运算符:
操作员 | 描述 | 表示 |
---|---|---|
+ |
一元加号,返回正值 | +a |
- |
一元负值,返回负值 | -b |
++ |
递增运算符,将值增加 1 | a++,a++ |
-- |
递减运算符,将值减少 1 | b -,- b |
让我们举一个代码示例:
var num1: Int = 25
var num2: Int = 10
println("+num1 :"+ +num1)
println("-num2 :"+ -num2)
println("++num1 :"+ ++num1)
println("--num2 :"+ --num1)
+num 1:25
—num 2:-10
++ num 1:26
--num 2:25
6.逻辑运算符
这些运算符用于执行逻辑与、逻辑或和逻辑非运算。
操作员 | 描述 | 表示 |
---|---|---|
&& |
与运算符,如果两个输入都为真,则返回真 | a && b |
|| |
或运算符,如果其中任何一个为真,则返回真 | a || b |
! |
非运算符,返回变量的否定 | !a |
让我们举一个代码示例:
var num1: Int = 25
var num2: Int = -10
var andResult = num1 > 0 && num2 > 0
var orResult = num1 > 0 || num2 > 0
var notResult = !true
println("Check if both are positive: " + andResult)
println("Check if either one is positive: "+ orResult)
println("Not operator on true: "+ notResult)
检查两者是否都为正:假
检查其中一个是否为正:真
非运算符 on true: false
7.杂项操作员
Kotlin 还支持一些更杂的操作符。我们将在此讨论其他一些运算符:
1.可空运算符(?
)
默认情况下,Kotlin 不允许字段为空。为了使一个字段可以为空,我们需要分配?
运算符。
var message: String = null // Error
var nullableMessage: String? = null // No error
2.!!
操作员
空指针断言操作符(!!
)将将任何值转换为非空类型,如果值为空,则抛出异常。
val message: String? = null
println(message!!.length)
这段代码在编译时不会抛出任何错误,但会在运行时抛出错误。不建议使用此运算符。
3.安全呼叫操作员(?.
)
这个运算符是 Kotlin 中最重要的运算符之一。它将我们从空指针异常中拯救出来。顾名思义,它通过检查对象是否为空来帮助我们安全地调用对象的任何变量或方法。
val message: String? = null
println(message?.length) // It will return null
println(message!!.length) // It will through null pointer exception
在第一种情况下,它将检查message
是否为空。如果是,则不调用方法,而是返回null
。
4.埃尔维斯运算符
如果引用为空,则使用 Kotlin 中的 Elvis 运算符来赋值。
例如:
var message: String? = null
println(message?:"Message is null")
message = "Hello World"
println(message?:"Message is null")
消息为空
你好世界
在第一种情况下,当message
为空时,使用猫王运算符后的条件,并打印“T7”消息为空。在第二种情况下,当message
不为空时,message
本身被打印。
摘要
在本教程中,我们讨论了 Kotlin 中的 variuos 运算符。最后,我们还讨论了一些操作符,这些操作符在空指针或空指针异常的情况下会对我们有所帮助。在下一个教程中,我们将讨论如何在 kotlin 中获取输入和显示输出。
Kotlin 输入和输出
原文:https://www.studytonight.com/kotlin/kotlin-input-and-output
在本教程中,我们将讨论如何将输出打印到控制台或屏幕,并在 Kotlin 中接受用户的输入。用户输入和输出是任何程序的重要部分。它们将有助于用户交互。
在 Kotlin 显示输出
对于输出到控制台窗口的打印,我们可以使用print()
和println()
功能。当print()
功能继续将输出添加到同一行时,println()
将打印输出并将光标移动到下一行。让我们用一个例子来看看:
println("Hello ")
println("World!!")
print("Bye")
print("World!!")
你好
世界!!
再见!!
在本例中,使用println()
功能打印前两个输出。所以,他们出现在不同的线路上。但是接下来的两个语句是使用print()
功能打印的。他们会出现在同一条线上。
Kotlin 中的输出变量
我们可以使用print()
和println()
功能直接打印变量。
var number= 25
var character = 'a'
println(number)
println(character)
25
a
我们也可以用字符串连接变量并打印它们。我们可以使用+
或$
运算符。但是使用$
比+
更受欢迎。
var number= 25
var character = 'a'
println("Number is: " + number)
println("Character is: " + character)
println("Number is: $number")
println("Character is: $character")
数字为:25
字符为:a
数字为:25
字符为:a
在 Kotlin 获取用户输入
为了获取用户的输入,我们使用readline()
功能。默认情况下,它会将输入作为字符串。如果我们需要任何其他类型的输入,如数字、布尔值等。,则需要将其转换为特定的类型,这意味着显式地指定输入并将输入从字符串转换为其他数据类型,如 Integer 等。
println("Enter string: ")
var inputString = readLine()
println("Input in string format is: $inputString")
println("Enter number: ")
var inputNumber = Integer.valueOf(readLine())
println("Input in number format is: $inputNumber")
输入字符串:
你好世界
输入字符串格式为:你好世界
输入数字:
10
输入数字格式为:10
在每种情况下,我们都需要为不同的数据类型转换输入。我们也可以创建Scanner
类的对象,并使用它来获取输入。
var scanner = Scanner(System.`in`)
println("Enter number: ")
var inputNumber = scanner.nextInt()
println("Input in number format is: $inputNumber")
同样,我们将对不同类型的变量使用nextBoolean()
、nextFloat()
、nextLong()
和nextDouble()
。
摘要
在本教程中,我们讨论了如何在控制台中获取输入和打印输出。在下一个教程中,我们将讨论 Kotlin 中的注释。
Kotlin 注释
在本教程中,我们将在 Kotlin 中介绍注释。注释是代码的重要部分。有时候程序员很难理解其他程序员写的一段代码。为了使我们的代码更加易读和易懂,我们应该添加注释并适当地记录下来。
编译器完全忽略注释。因此,它们在编译代码时不会导致任何错误。
Kotlin 中有两种类型的注释:
-
单行注释
-
多行注释
现在我们将看到如何在 Kotlin 中使用它们。
Kotlin 的单行注释
顾名思义,单行注释用于在单行中编写注释。它们是使用//
(双斜线)创建的。单行注释应该只跨越一行,而不是多行,否则我们会得到一个错误。
这里有一个例子:
// This is a comment
println("Enter string: ") // Enter a string here
var inputString = readLine()
println("Input in string format is: $inputString") // Input is printed here
在上面的代码中,有三个注释(在第 1、2 和 4 行)。
多行注释 Kotlin
多行注释跨越多行。以/*
开始,以*/
结束。
/*
This is a multi-line comment
This is second line
Last line of comment
*/
println("Enter string: ")
var inputString = readLine()
println("Input in string format is: $inputString")
多行注释可以用来解释函数的功能和参数。或者我们可以在需要记录程序中如此关键的算法步骤的地方使用多行注释,或者在需要详细注释的地方使用多行注释。
摘要
在本教程中,我们讨论了 Kotlin 中的注释。注释是有用的工具,我们应该明智地使用它,使我们的代码更易读,并记录代码在程序中的作用。
Kotlin 控制流程
Kotlin if else
表达式
原文:https://www.studytonight.com/kotlin/kotlin-if-else-expression
在本教程中,我们将学习如何使用 if-else 表达式控制 Kotlin 中的执行流。几乎所有现代编程语言都可以使用 if-else 语句来控制执行流程。
在大多数语言中,if-else
块用于基于表达式选择条件。如果if
表达式返回真,将执行if
块。否则,将执行else
块。例如,如果我们想使用分数知道一个学生是否通过了考试,我们可以编写以下代码:
fun main() {
val marks = 70
val result:String
if(marks > 33){
result = "Hurrah! You passed"
}
else{
result ="Sorry! You failed"
}
println(result)
}
万岁!你通过了
在这里,因为学生的分大于 33,所以通过了考试。
但在 Kotlin,如果-else 不是陈述,而是表达。这意味着 if-else 块可以返回一个语法略有变化的值。
让我们看看下面的代码:
fun main() {
val marks = 70
val result:String
result = if(marks > 33) {
"Hurrah! You passed"
}
else{
"Sorry! You failed"
}
println(result)
}
这里,根据条件,该值将从 if-else 块返回,并将被分配给result
变量。
注意: 在使用 if-else 作为表达式时,必须有一个带有if
block 的else
block。
Kotlin 中有各种类型的 if-else 表达式:
-
简单的 if-else 表达式
-
if-else 梯子
-
嵌套 if 表达式
简单的 if-else 表达式
以下是如果不使用else
块时if
语句如何工作的图示:
让我们通过一个代码示例来看看简单的if
表达式的作用:
fun main() {
val light = "red"
if(light == "red"){
print("Stop")
}
}
停止
如果我们在代码中指定了if
和else
,那么:
我们已经在上面看到了一个简单 if-else 表达式的例子。我们可以进一步简化这个表达式:
fun main() {
val marks = 70
val result:String
result = if(marks > 33) "Hurrah! You passed" else "Sorry! You failed"
println(result)
}
万岁!你通过了
如果在if
和else
块中有单行代码,我们可以去掉大括号。
如果不是这样的梯子
如果我们有多个条件需要检查,那么我们可以使用if else
阶梯。让我们用一个例子来理解这一点。
假设我们想根据一个学生的分数给他/她打分;我们可以使用if else
阶梯:
fun main() {
val marks = 70
val grade: String
grade = if(marks >= 91)
"A+"
else if(marks >= 81)
"A"
else if(marks >= 71)
"B+"
else if(marks >= 61)
"B"
else if(marks >= 51)
"C+"
else if(marks >= 41)
"C"
else if(marks >= 33)
"D"
else
"F"
println("Your grade is: $grade")
}
你的成绩是:B
为了使上面的代码示例更具交互性,您可以从用户处获取输入,然后将等级显示为输出。
嵌套 if-else 表达式
当我们在另一个if
表达式中有一个if
表达式时,它被称为嵌套的if
表达式。让我们借助一个例子来理解这一点。
我们将编写一个程序来找出三个数字的最大值。
算法示例:
-
输入三个数字: num1 、 num2 和 num3。
-
如果 num1 大于 num2:
-
如果 num1 大于 num3,则 num1 为最大值
-
否则 num3 最大
-
-
否则如果 num2 大于 num3 ,则 num2 最大
-
否则 num3 最大
这可以实现为:
import java.util.*
fun main() {
val scanner = Scanner(System.`in`)
// Taking three numbers as input
println("Enter first number: ")
val num1 = scanner.nextInt()
println("Enter second number: ")
val num2 = scanner.nextInt()
println("Enter third number: ")
val num3 = scanner.nextInt()
val max = if(num1 > num2){
if(num1 > num3)
num1
else
num3
}
else if(num2 > num3)
num2
else num3
println("Maximum number is: $max")
}
输入第一个号码:
10
输入第二个号码:
20
输入第三个号码:
11
最大号码为:20
上面程序的第一部分是从用户那里输入 3 个数字,然后我们比较这些数字,找出 3 个数字中的最大数字。为此,我们在另一个if
条件中使用一个if else
条件,这是嵌套的if
表达式。
嵌套没有限制。一个if
条件内可以有任意多个if
条件,也可以做一个嵌套链。
摘要
在本教程中,我们讨论了 Kotlin 中的if
和else
表达式。在下一个教程中,我们将讨论 Kotlin 中的when
表达。
Kotlin when
表达式
原文:https://www.studytonight.com/kotlin/kotlin-when-expression
在本教程中,我们将讨论 Kotlin when
表达式。当我们使用根据变量的不同值来选择特定的语句时,会用到 Kotlin when
表达式。它类似于其他编程语言中的开关盒。
使用when
表达式打印字母表类型的简单程序是:
fun main() {
val alphabet:Char = 'a'
when(alphabet){
'a' -> println("Character is vowel")
'e' -> println("Character is vowel")
'i' -> println("Character is vowel")
'o' -> println("Character is vowel")
'u' -> println("Character is vowel")
else -> println("Character is consonant")
}
}
字符为元音
在上例中:
-
变量
alphabet
在when
表达式内部传递。 -
我们通过在输入变量前面添加
->
符号来定义不同的情况来匹配输入变量。 -
如果没有匹配,则执行
else
块。
类似于if-else
表达式,when
表达式也返回值。因此,我们可以返回值并将其赋给变量。让我们用一个例子来理解这一点。
我们将编写一个程序,根据当天的数字来查找当天:
fun main() {
val number:Int = 5
val day:String = when(number){
1 -> "Monday"
2 -> "Tuesday"
3 -> "Wednesday"
4 -> "Thursday"
5 -> "Friday"
6 -> "Saturday"
7 -> "Sunday"
else -> "Invalid number"
}
println("Day is: $day")
}
日为:星期五
在上面的代码中,我们指定了匹配变量number
值的条件。所以如果变量数的值是 1,那么“星期一”将被加到day
变量中,对于 2,“星期二”将被加到day
变量中,以此类推。如果该值等于或大于 8,则执行else
表达式。
现在我们已经对 Kotlin when
表达式有了一个基本的介绍,让我们看看更多使用它的方法。
when
表达式中的代码块
一段代码也可以放在 Kotlin when
的表达式条件里面:
fun main() {
val number:Int = 5
when(number){
1 -> {
println("Hello")
println("Monday")
}
2 -> {
println("Hello")
println("Tuesday")
}
3 -> {
println("Hello")
println("Wednesday")
}
4 -> {
println("Hello")
println("Thursday")
}
5 -> {
println("Hello")
println("Friday")
}
6 -> {
println("Hello")
println("Saturday")
}
7 -> {
println("Hello")
println("Sunday")
}
else -> {
println("Invalid input!!")
}
}
}
你好
周五
就像上面的代码示例一样,我们可以在这些when
表达式条件中拥有任何我们想要的逻辑。
组合多个when
条件
我们可以在一个when
表达式中用逗号组合多个条件。
fun main() {
val rating: Int = 5
val review: String = when(rating){
10 -> "Excellent"
8,9 -> "Above Average"
6,7 -> "Average"
4,5 -> "Below Average"
1,2,3 -> "Poor"
else -> "Invalid input"
}
println("Review is: $review")
}
评价为:低于平均水平
在上面的代码示例中,我们将多个条件组合在一起。
摘要
在本教程中,我们介绍了 Kotlin 中的when
表达式。这在编写 Kotlin 代码时非常有用,在那里你必须创建一个类似功能的菜单。在下一个教程中,我们将介绍 Kotlin 中不同类型的循环。
Kotlin while
循环
在本教程中,我们将从 Kotlin 中的循环开始。我们将介绍 Kotlin 中不同类型的循环,这些循环用于一次又一次地执行一段代码,直到满足某个条件。
Kotlin 环路
Kotlin 中的循环用于一次又一次地执行一段特定的代码。我们可以通过指定某个条件来打破循环。如果达到给定的条件,执行将结束循环。让我们用一个例子来理解循环。
假设你想写一个程序来打印所有从 1 到 100 的偶数。手动完成这个任务真的很难,即使我们设法做到了,如果范围增加到 1000,那就不可能了。对于这样的用例,我们可以使用一个循环,它将一次又一次地执行,直到我们达到目标(即 100 或 1000 个数字)。
kotlin 中有三种主要的循环类型:
-
While 循环
-
边做边循环
-
For 循环
在本教程中,我们将讨论while
循环。我们将在接下来的教程中介绍剩余的循环。
kot Lin〔t0〕回圈
while
循环将执行一段代码,直到指定条件返回真或任何正值。当条件返回假时,循环的执行将结束。
while
循环的语法是:
while(condition){
// Piece of code to be executed
}
while
回路的工作:
-
第一次进入循环前,会检查条件是真还是假。
-
如果条件为真,则进入循环。否则,它将结束循环执行。
-
将执行循环块中的语句。
-
此后,再次检查条件并遵循相同的程序,直到条件变为假。
如果条件从未失效,它将进入无限循环。我们在使用循环时应该注意这一点。
Kotlin while
循环示例
让我们举一个例子,我们将使用while
循环打印一个 2 的数学表。
fun main() {
var iterator = 1
// when iterator becomes 10, end the loop
while(iterator <= 10){
println("2 * $iterator = " + 2*iterator )
// increment value of iterator by 1
iterator++
}
}
2 * 1 = 2
2 * 2 = 4
2 * 3 = 6
2 * 4 = 8
2 * 5 = 10
2 * 6 = 12
2 * 7 = 14
2 * 8 = 16
2 * 9 = 18
2 * 10 = 20
这里,执行循环的条件是:迭代器应小于或等于 10 。当迭代器到达 11 时,条件返回假,执行退出循环。
注: 要了解++和-运算符,请了解 Kotlin 一元运算符。
再举一个例子:
再举一个例子求一个数的阶乘:
fun main() {
var number = 10 // Number whose factorial needs to be find
var numberToIterate = number // Creating a variable to use this as an iterator
var factorial = 1
// Iterating while loop until it reaches 0
while (numberToIterate > 0){
factorial *= numberToIterate
numberToIterate--
}
println("Factorial of $number is $factorial")
}
10 的阶乘为 3628800
摘要
在本教程中,我们介绍了 Kotlin 中的循环、为什么需要循环以及循环的类型。我们还详细介绍了while
循环。我们将在接下来的教程中学习for
循环和do-while
循环。
Kotlin do-while
循环
在本教程中,我们将介绍 Kotlin 中的do-while
循环。do-while 循环就像 Kotlin while
循环一样,只有一个区别,那就是无论您在do-while
循环中提供什么条件,l oop 都将执行一次,因为条件是在循环代码执行后检查的。
kot Lin〔t0〕回圈:
以下是do-while
循环的基本语法:
do {
// Block of code to be executed
}while (condition)
do-while
回路的工作如下:
-
第一次在不检查条件的情况下执行
do
块中写入的语句。 -
执行
do
块后,检查while
中指定的条件。 -
如果条件为真,再次执行
do
块。否则,循环的执行结束。
Kotlin do-while
循环示例
让我们举个例子打印所有从 1 到 10 的偶数:
fun main() {
var number = 1
do {
if(number % 2 == 0)
println(number)
number++
}while (number <= 10)
}
2
4
6
8
10
试着运行上面的代码来打印从 1 到 100 的偶数,你所要做的就是修改do-while
循环的条件。
就像我们在介绍中提到的那样,do-while
循环将至少执行一次,即使条件总是为假。让我们用一个例子来看看:
fun main() {
do {
println("Hello World!!")
}while (false)
}
你好世界!!
在上面的代码示例中,我们可以看到,即使条件始终为 false ,输出也会打印一次。
while
和do-while
循环之间的差异
while
循环和do-while
循环略有不同:
-
while
回路为入口控制回路,do-while
回路为出口控制回路。 -
至少,
do-while
循环将至少执行一次,但如果条件为假,while
循环可能一次也不执行。
摘要
在本教程中,我们通过代码示例介绍了 Kotlin do-while
循环,我们还看到了它与 Kotlin while
循环的不同之处。在下一个教程中,我们将介绍 Kotlin for
循环。
Kotlin for
循环
在本教程中,我们将讨论 Kotlin 中的for
循环。Kotlin 不像 C、C++、Java 等,没有传统的for
循环。,它将执行,直到条件返回假。Kotlin 中的for
循环类似于 Java 中的 forEach
循环。
for
循环用于迭代任何可以迭代的 Kotlin 对象。我们可以迭代一个数组、集合、字符串、范围,或者任何可以借助for
循环迭代的东西。
kot Lin〔t0〕回圈
以下是for
循环的语法:
for (item in collection){
// Body of for loop
}
这里的item
是变量,每个循环执行的值将存储在其中,而collection
是我们正在迭代的 Kotlin 对象。
Kotlin 中的for
循环并不用于一次又一次地执行操作,而是用于迭代任何 Kotlin 对象,如数组、列表或任何集合对象,以使用它们的元素执行一些操作。
Kotlin for
循环示例
让我们看一个例子,在这个例子中,我们将在 Kotlin 中迭代一个标记的数组:
fun main() {
val marks: Array<Int> = arrayOf(9,8,3,10,7,9)
for (subjectScore in marks){
println(subjectScore)
}
}
9
8
3
10
7
9
这里,for
循环将继续执行,直到数组中存在的所有元素都被覆盖。如果循环体中只有一行,可以去掉大括号。
我们也可以使用可迭代项的索引对其进行迭代:
fun main() {
val marks: Array<Int> = arrayOf(9,8,3,10,7,9)
for (index in marks.indices)
println("Score in subject $index is: " + marks[index])
}
科目 0 的分数为:9
科目 1 的分数为:8
科目 2 的分数为:3
科目 3 的分数为:10
科目 4 的分数为:7
科目 5 的分数为:9
迭代 Kotlin 字符串:
在下面的示例中,我们将遍历字符串的字符:
fun main() {
val name = "Ninja"
for (alphabet in name){
println(alphabet)
}
}
N
i
n
j
a
摘要
在本教程中,我们介绍了 Kotlin 中的for
循环。在下一个教程中,我们将讨论 Kotlin 中的range
以及如何在 Kotlin 循环中使用range
。
Kotlin 范围
在本教程中,我们将讨论 Kotlin 中的range
。在数学意义上,一个范围是一系列数字、字符等。在限定的边界内。边界点为起点 & 终点,两者都包含在范围内。range
也可以有一个step
(步骤用于跳转数字或字符,同时定义从开始到结束边界的范围)。
我们可以借助 Kotlin 中的rangeTo()
功能或者使用..
运算符来创建一个范围。
Kotlin:创建一个范围
如上所述,我们可以使用..
运算符和rangeTo()
函数,让我们一个接一个地讨论它们。
使用..
运算符的 Kotlin 范围:
让我们使用..
操作符创建一个从 1 到 9 的。
val range = 1..9
在上面的代码示例中,我们使用..
运算符创建了一个范围。如果您想创建一个包含所有数字的数字范围,那么使用..
操作符既简单又容易。
唯一的缺点是,我们不能用我们跳过/跳转数字的模式创建一个范围,例如,如果您想创建一个 1、3、5、7 等数字的范围。跳一号,或者 1、4、7、10 等。跳跃两个数字。
使用rangeTo()
运算符的 Kotlin 范围:
我们也可以使用rangeTo()
功能来创建范围。这是一个基本的例子:
val range = 1.rangeTo(9)
在上面的代码示例中,我们正在创建一个从 1 到 9 的范围,其中包括 1 和 9 。
检查数字是否在给定范围内
创建范围变量后,如果您想检查给定的数字是否在该范围内,那么我们可以使用带有if
条件的in
运算符轻松完成。
下面是一个简单的代码示例:
fun main() {
val range = 1..9
if (1 in range)
println("1 is in $range")
if(10 in range)
println("10 is in $range")
}
1 合 1..9
我们也可以在各种不同的场景中使用range
:
var lowerCase = 'a'..'z' // Range for lowercase alphabet
var upperCase = 'A'..'Z' // Range for uppercase alphabet
var digit = 0..9 // Range for digits
这样我们就可以根据我们的要求轻松地定义不同类型的范围。
Kotlin 步幅
要定义一个范围内两个连续值之间的距离,我们可以使用step()
函数。例如,要用 2 的step
打印 1 到 10 的数字,我们可以将范围写成:
val range = 1..10 step 2
让我们使用for
循环打印该范围:
fun main() {
val range = 1..10 step 2
for (number in range)
println(number)
}
1
3
5
7
9
同样,我们可以为step
函数提供任何数字作为参数,并基于此创建我们的范围变量。
Kotlin downTo()
功能
如果我们想按相反的顺序打印数字,即从 10 到 1,我们不能使用 rangeTo()
功能或..
运算符。如果我们试着像下面的代码一样使用它们,它不会打印任何东西,因为默认步骤是 1 ,并且它只会向前进行。
fun main() {
val range = 10..1
for (number in range)
println(number) // print nothing
}
因此,为了以相反的顺序创建一个范围,我们将使用downTo()
函数:
fun main() {
val range = 10 downTo 1
for (number in range)
println(number)
}
10
9
8
7
6
5
4
3
2
1
我们也可以用step
配合downTo()
功能:
fun main() {
val range = 10 downTo 1 step 3
for (number in range)
println(number)
}
10
7
4
1
摘要
在本教程中,我们讨论了rangeTo()
、step
和downTo()
函数。还有许多其他功能可用,如first()
、last()
、until()
,可与range
一起使用。接下来我们将讨论continue
、break
和repeat
语句。
Kotlin continue
,break
和repeat
语句
原文:https://www.studytonight.com/kotlin/kotlin-continue-break-and-repeat-statement
在本教程中,我们将讨论 Kotlin 中的continue
、break
和repeat
语句。这些语句在 Kotlin 循环中用于管理循环的执行流程,例如,如果您想跳过一个迭代,或脱离循环或重复一个迭代,那么可以使用这些语句。
在本教程中,我们将通过示例介绍所有这三个方面。
Kotlin continue
声明
continue
语句用于跳过循环的当前迭代,从下一个迭代开始。它主要与if
表达式一起使用,根据条件决定是否跳过循环的当前迭代。
让我们用一个例子来理解continue
的说法。我们将打印从 1 到 10 的所有数字,除了 3 的倍数:
fun main() {
for (number in 1..10){
if (number % 3 == 0)
continue
println("Number is $number")
}
}
号为 1
号为 2
号为 4
号为 5
号为 7
号为 8
号为 10
该计划的流程:
-
对于 1 到 10 之间的每个
number
值,将执行循环。 -
在
if
表达式内部,会检查number
是否能被 3 整除:-
如果是,由于
continue
语句,循环的其余部分将不会被执行,因此不会打印数字。它将转到下一个值并执行循环。 -
如果否,则执行循环并执行
println
语句。
-
在嵌套循环的情况下,最里面的循环将遵循continue
语句。
Kotlin break
声明
break
语句用于停止循环的执行,执行退出或跳出循环。它还与if
表达式一起使用,根据特定条件中断循环。
让我们编写一个程序来接收用户的输入。它将继续接受输入,直到用户输入“停止”:
fun main() {
while (true){
println("Enter the input: ")
val input: String? = readLine()
if(input == "stop")
break
println("Input entered is: $input")
}
println("Outside the loop!!")
}
输入输入:
你好
输入输入为:你好
输入为:
世界
输入输入为:世界
输入为:
停止
外循环!!
该计划的流程:
-
因为 while 循环中的条件总是真的,所以它永远不会停止自己。
-
如果输入为“停止”,则获取并检查输入:
- 如果是,循环结束,打印循环外的最后一条语句“”。
** 如果否,循环将继续执行并打印输入的内容。*
*在嵌套循环的情况下,break
语句将断开最里面的循环。因此,您将需要多个break
语句来分解或嵌套循环,这取决于循环的数量。
Kotlin repeat
声明
repeat
语句类似于 Kotlin 中的循环。它被用来重复一个任务多次,就像循环一样。
repeat
语句的语法是:
repeat(Number_of_time){
// Statements to be executed
}
让我们使用repeat
语句打印一个语句 3 次:
fun main() {
repeat(3){
i ->
println("This statement will be printed 3 times!!")
println("Index is: $i")
}
}
本声明将打印 3 次!!
指数为:0
本声明将打印 3 次!!
指数为:1
本声明将打印 3 次!!
指数为:2
如上面的代码所示,如果我们想使用它,我们可以得到repeat()
语句的索引。在上面的代码中,我们使用它来打印索引。
摘要
在本教程中,我们讨论了continue
、break
和repeat
语句。在下一个教程中,我们将开始详细讨论 Kotlin String。
Kotlin 数据类型
Kotlin 字符串
在本教程中,我们将向您介绍 Kotlin 字符串,包括 Kotlin 字符串类、其属性和函数以及代码示例。
字符串是组合在一起的字符数组。字符串通常使用双引号 ""
创建。我们也可以使用三重引号 """
创建多行字符串。这根弦也被称为生弦。
字符串的一个基本例子是“今晚学习”,或“学习 123”等。都是字符串。在内部,它被视为字符数组,您将会理解,因为我们将介绍一些代码示例。
和 Java 类似,字符串本质上是不可变的。不可变并不意味着我们不能改变字符串变量的值。这意味着每当我们改变一个字符串的值,而不是改变该字符串的实例时,编译器会创建该字符串的新实例。
让我们用一个例子来理解它:
fun main() {
var string: String = "Hello"
string = "Bye"
println(string)
}
在第 2 行中,我们创建了一个变量string
,并为其分配了"Hello"
值。编译器将在字符串池中创建新字符串。现在,当我们将"Bye"
分配给string
时,编译器将再次创建一个新字符串,将其存储在字符串池中,并将其实例分配给string
变量。并且先前创建的字符串“Hello
”将仍然存在于字符串池中。
字符串类的属性和方法
String 类包含许多属性和方法,用于管理 Kotlin 字符串并对其执行操作。一些重要的属性和功能是:
Kotlin 字符串属性:
-
length
:表示字符串的长度。 -
lastIndex
:表示字符串中最后一个字符的索引。
Kotlin 字符串方法:
-
get(index)
:返回字符串中指定索引处的字符或者抛出IndexOutOfBoundsException
。 -
first()
:返回字符串中的第一个字符,如果字符串为空则抛出NoSuchElementException
。 -
last()
:返回字符串中最后一个字符,如果字符串为空则抛出NoSuchElementException
。 -
plus(string)
:返回一个新的字符串,这个新的字符串是通过将连接到调用这个方法的字符串上而得到的,这个字符串作为参数给出。它不会改变实际的字符串,因为字符串是不可变的。 -
subSequence(startIndex, endIndex)
:返回startIndex
(包含)和endIndex
(不包含)之间的子序列。 -
contains(subString, ignoreCase)
:如果该字符串中包含给定的子字符串,则返回true
。ignoreCase
参数为真/假,指定是否忽略大小写。 -
capitalize()
:返回该字符串的副本,其第一个字母大写。 -
decapitalize()
:返回该字符串的副本,其第一个字母以开头。 -
reversed()
:以相反的顺序返回一个带有字符的字符串。 -
toLowerCase()
:返回这个字符串的一个副本转换成小写。 -
toUpperCase()
:返回转换为大写的字符串的副本。
让我们在一个例子中使用这些方法和属性:
fun main() {
var message = "Hello World!!"
// Properties
println("Length of string: ${message.length}")
println("Last index number: ${message.lastIndex}")
// Functions
println("Character at index 0: ${message[0]}")
println("Character at index 1: ${message.get(1)}")
println("First character in string: ${message.first()}")
println("Last character in string: ${message.last()}")
println("Add Bye to message for printing: ${message.plus(" Bye")}")
println("Subsequence from message: ${message.subSequence(0,5)}")
println("Message contains 'll'?: ${message.contains("ll")}")
println("Capitalize message: ${message.capitalize()}")
println("decapitalize message: ${message.decapitalize()}")
println("Reversed message: ${message.reversed()}")
println("Message in lower case: ${message.toLowerCase()}")
println("Message in upper case: ${message.toUpperCase()}")
}
字符串长度:13
最后一个索引号:12
索引 0 处字符:H
索引 1 处字符:e
字符串中第一个字符:H
字符串中最后一个字符:!
给消息添加 Bye 进行打印:你好世界!!再见
消息子序列:你好
消息包含‘ll’?:true
大写留言:你好世界!!
去大写信息:你好世界!!
反转消息:!!dlroW olleH
小写留言:你好世界!!
大写信息:你好世界!!
不要被语法${ .. }
搞糊涂了,它是用来在 Kotlin 的 println 输出中追加一个变量值的。
字符串模板
我们可以添加一段代码并将其连接到字符串(在将其转换为字符串之后)。这段代码被称为字符串模板。我们在使用println()
函数打印值时也使用了字符串模板。字符串模板以$
(美元)符号开始。
让我们看一个例子,其中我们将添加一个字符串模板:
fun main() {
var message = "Hello World!!"
var multiLineMessage = """Adding message in
multiline
comment:
$message
"""
println(multiLineMessage)
}
多行
添加消息评论:
你好世界!!
正如您在上面的代码中看到的,我们已经使用$
符号在println
方法中打印的消息中添加了一个字符串。当我们打印带有字符串值变量的输出时,这非常有用。
摘要
在本教程中,我们讨论了 Kotlin 字符串、它的属性和方法。当我们编写实际程序时,字符串非常有用,当您使用 Kotlin 开发您的安卓应用时,所有这些方法都会派上用场。在下一个教程中,我们将讨论 Kotlin 数组。
Kotlin 数组
在本教程中,我们将讨论 Kotlin 数组。数组是数据类型的集合。在大多数语言中,数组元素应该是相同的数据类型,但是在 Kotlin 中,我们可以有包含不同数据类型的数据的数组。意思是,我们可以存储整数、字符串、字符等。在同一个数组中。
数组的属性有:
-
数组是基于 0 索引的,即第一个元素的索引为 0。
-
阵的大小是固定的。申报后不能增减。
-
数组是可变的,因为数组元素在声明后可以改变。
在 Kotlin 中,可以使用Array<T>
类和一些 Kotlin 函数来创建数组。我们将首先看到如何使用函数创建数组,然后我们将看到如何使用Array
类创建。
使用函数创建数组
创建数组最简单的方法是使用arrayOf()
函数。调用arrayOf()
函数时,我们可以将数组元素作为参数传递。
让我们创建一个整数数组:
val marks = arrayOf(10,9,3,4,5)
在上面的代码中,我们创建了一个整数数组。由于数组的大小是固定的,我们以后不能在此添加元素。该数组的大小将是固定的,即 5 。
在上面的例子中,没有提到数组的类型。因此,不同类型的元素可以添加到这个数组中:
val differentTypeArray = arrayOf(10,4,5,"Array string", 'c', 10.5f)
正如您在上面的代码示例中看到的,不同类型的元素被添加到这个数组中。
如果我们想固定数组中元素的类型,可以在创建数组时提到类型,如下所示:
val marks = arrayOf<Int>(10,4,5,8,9)
现在在上面定义的数组中,只能存储整数值。
为了限制数组只存储特定类型的数据,我们也可以在 Kotlin 中使用特定类型的函数。它们是:
-
intArrayOf()
-对于整数数组 -
charArrayOf()
-对于字符数组 -
byteArrayOf()
-对于字节数组 -
shortArrayOf()
-对于短值数组 -
longArrayOf()
-对于长值数组 -
doubleArrayOf()
-对于双值数组 -
floatArrayOf()
-对于浮点值数组 -
booleanArrayof()
-对于布尔值数组
让我们举一个使用上述所有函数的简单代码示例:
var intArray = intArrayOf(1,2,3,4,5)
var charArray = charArrayOf('a','b','c')
var byteArray = byteArrayOf(1,2,5,6,7)
var shortArray = shortArrayOf(2,3,5,6)
var longArray = longArrayOf(1,2,3)
var doubleArray = doubleArrayOf(10.0, 1.1, 3.14)
var floatArray = floatArrayOf(10.0f, 3.14f)
var booleanArray = booleanArrayOf(true, false, true)
所以如果你想限制一个数组存储相同类型的数据,你可以通过使用上面的,特定类型的arrayOf
函数或者使用简单的arrayOf
函数以及像<Int>
、<Char>
等类型信息来实现。
使用数组类创建数组
可以使用Array
类的构造器创建 Kotlin 数组。构造器需要两个参数:第一个是数组的size
,第二个是init
函数。init
功能用于初始化数组:
var numbers = Array(3, init = {
i -> i * 3
})
这里,使用公式索引* 3 创建大小为 3 的数组并由元素初始化。创建的数组将包含 0,3,6 。
访问和修改数组
使用get()
和set()
功能可以访问和修改数组的元素。
get()
函数只取一个参数:元素的索引。
而set()
函数取两个参数:第一个作为元素的index
,第二个作为该index
的新值。
让我们举一个代码例子,
fun main() {
val marks = arrayOf<Int>(10,4,5,8,9)
println(marks.get(0))
println(marks.get(1))
// update the value of the first element of the array
marks.set(0,100)
println(marks.get(0))
}
10
4
100
除了使用get()
和set()
,我们还可以使用[]
来访问方括号内提供索引值的数组元素。以上使用[]
的代码可以写成:
fun main() {
val marks = arrayOf<Int>(10,4,5,8,9)
println(marks[0])
println(marks[1])
// setting new value for first element of array
marks[0] = 100
println(marks[0])
}
10
4
100
获取数组的大小
Kotlin 数组的大小可以通过其size
属性找到:
fun main() {
val marks = arrayOf<Int>(10,4,5,8,9)
println(marks.size)
}
5
遍历数组
可以使用for
循环遍历数组。下面是一个简单的代码示例,
fun main() {
val marks = arrayOf<Int>(10,4,5,8,9)
for (i in marks)
println(i)
}
10
4
5
8
9
也可以使用 Kotlin 中的forEach()
来访问数组元素:
fun main() {
val marks = arrayOf<Int>(10,4,5,8,9)
marks.forEach { i ->
println(i)
}
}
10
4
5
8
9
摘要
在本教程中,我们讨论了使用方法和数组类构造器创建数组。我们还讨论了如何访问和修改数组元素、查找数组大小以及遍历数组。在下一个教程中,我们将讨论 Kotlin 函数。
Kotlin 函数
Kotlin 用户定义函数
原文:https://www.studytonight.com/kotlin/kotlin-userdefined-functions
在本教程中,我们将讨论 Kotlin 函数,包括 Kotlin 库函数和用户定义函数。函数用于将巨大的单片代码分解成可重用的更小的代码块。理想情况下,我们应该为单个任务创建一个函数。函数也增加了代码的可重用性因为一旦被编写,函数可以在需要的时候被多次调用。
功能可以有两种类型:
-
标准库函数
-
用户定义的函数
标准库函数由 Kotlin 标准库提供,可以直接使用。我们已经使用了许多标准库函数,如:print()
、println()
、main()
、arrayOf()
等。您可以在这里探索更多关于 Kotlin 标准库的信息。现在,我们将看到如何创建用户定义的函数。
Kotlin 用户定义函数
顾名思义,用户定义的功能是由用户创建的。Kotlin 中的函数是使用fun
关键字创建的。函数的语法是:
fun <name_of_function>(<argument_name>: <argument_data_type>):<return_type>{
// body of the function
}
在语法中:
-
<函数名> :是给函数起的名字。
-
<自变量 _ 名称> :代表自变量名称。
-
<参数 _ 数据 _ 类型> :表示参数的数据类型。
-
< return_type > :表示函数返回值的数据类型。
对于绝对初学者来说,参数代表调用函数时提供给函数的数据值,函数使用这些数据值,返回类型是函数作为结果返回的值的数据类型。
让我们创建一个简单的函数,将一个整数作为输入,并返回它的平方:
fun getSquare(number: Int): Int {
return number * number
}
在上面的代码中,我们提供了输入参数作为Int
的数据类型和返回值也作为Int
的数据类型。
让我们从main()
函数调用这个函数:
fun main() {
println("The square of 9 is : ${getSquare(9)}")
}
fun getSquare(number: Int): Int {
return number * number
}
9 的平方是:81
关于功能的几个要点是:
-
一旦我们定义了一个函数,我们可以随意调用它多次。
-
如果在调用函数时,我们提供了错误的数据类型参数,那么我们将得到一个编译时异常。
-
我们还可以定义不返回任何内容的函数,这将在本教程的下一节中介绍。
不返回任何内容的 Kotlin 函数
我们可以定义在 Kotlin 中返回任何东西的函数。有三种不同的方法。
无返回类型的 Kotlin 函数:
如果函数没有返回任何东西,那么就不需要提到返回类型:
fun sayHello(){
println("Hello World!!")
}
在上面的函数中,如果我们愿意,我们可以添加参数(参数),但是函数可能不会返回任何东西。例如,我们可以更新上面定义的 getSquare()函数,只打印结果而不是返回结果。
fun getSquare(number: Int) {
println("Square is: ${number * number}")
}
带有Unit
返回类型的 Kotlin 函数:
如果我们想指定返回类型,我们可以添加Unit
作为不返回任何有意义的函数的返回类型。类似于 Java 中的虚空。如果没有提到任何返回类型,也没有从函数中返回任何值,那么默认情况下,返回类型被认为是Unit
。
让我们举一个代码示例:
fun sayHello(): Unit{
println("Hello World!!")
}
带有Nothing
返回类型的 Kotlin 函数:
在 Kotlin 中,Nothing 是一种特殊类型,它也可以用作用户定义函数的返回类型,用于不返回任何内容的函数。或者,我们可以说,以Nothing
为返回类型的函数,从不返回任何东西,甚至不是默认的Unit
类型。
例如,下面的函数总是引发异常:
fun exceptionEveryTime(): Nothing {
throw IllegalArgumentException()
}
注意: 如果我们在代码中调用了上面的函数,那么这个函数调用后的代码语句将不会被执行,编译器将显示警告。
为什么不能用 Void?
你一定在想,为什么我们不能像在 Java 中那样对不返回任何东西的 Kotlin 函数使用 Void。我们可以,但不能直接说。
例如,
fun setReturnTypeVoid() : Void {
println("This function has return type as Void")
}
但是该函数不会被编译,您将看到以下错误:
错误:Kotlin:在具有块体的函数中需要“return”表达式(' { 0...}')
您一定认为该函数根据错误消息需要一个返回类型,所以继续,并尝试在末尾添加一个return null
语句。
fun setReturnTypeVoid() : Void {
println("This function has return type as Void")
return null
}
这也不行。
错误:Kotlin: Null 不能是非 Null 类型的值 Void
看这也行不通。为什么呢?因为 Kotlin 没有将Void
视为空类型,所以提供return null
语句会产生编译错误。\
但是在 Kotlin 中,我们可以通过使用?
运算符使函数返回类型为可空的。
例如,
fun setReturnTypeVoid() : Void? {
println("This function has return type as Void")
return null
}
但是,这也适用于任何其他返回类型,如Int
等。而不仅仅是针对Void
数据类型。
摘要
在本教程中,我们讨论了 Kotlin 用户定义函数。我们看到了为什么要使用函数,以及如何使用fun
关键字创建用户定义的函数。我们学习了用不同的返回类型定义新函数。我们还介绍了如何使用Unit
和Nothing
类型定义不返回任何内容的函数。
在接下来的教程中,我们将讨论递归、内联函数、函数中不同类型的参数、lambda 函数等。
Kotlin 递归函数
原文:https://www.studytonight.com/kotlin/kotlin-recursive-functions
在本教程中,我们将讨论 Kotlin 递归函数。Kotlin 中的一个函数不断地调用自己被称为递归函数。这个概念并不是 Kotlin 的母语,而是存在于所有语言中。递归函数可以看作一个循环,但两者并不完全相同。
递归函数必须有中断条件才能停止递归;否则它将无限期运行。中断条件主要基于传递给函数的参数。
递归函数的基本语法是:
fun sayBye(){
sayBye()
}
当一个函数在自身内部被调用时:这使得函数递归。
让我们编写一个程序来寻找一个数的阶乘。我们将首先使用for
循环编写它,然后使用递归函数编写。
下面是使用for
循环的实现:
fun main() {
println("Factorial of 5 is: ${factorial(5)}")
}
fun factorial(n: Int): Int{
var factorialOfN = 1
for(i in n downTo 1){
factorialOfN *= i
}
return factorialOfN
}
5 的阶乘为:120
现在让我们使用递归函数来实现它:
fun main() {
println("Factorial of 5 is: ${factorial(5)}")
}
fun factorial(n: Int): Int{
if(n == 1)
return 1
return n * factorial(n - 1)
}
它也会产生同样的输出。
说明:
-
首先,从 main()函数调用
factorial(5)
。 -
在
factorial(5)
内检查条件,返回值为5 * factorial(4)
。 -
现在,调用
factorial(4)
,它将返回4 * factorial(3)
。 -
接下来,调用
factorial(3)
,它将返回3 * factorial(2)
。 -
同样,调用
factorial(2)
,它将返回2 * factorial(1)
。 -
最后
factorial(1)
通过检查if
条件返回 1,递归到此结束。 -
从步骤 6 获得的值将返回到步骤 5,即
2 * factorial(1)
将变为2 *1
。 -
类似地,这些值在每一步返回,最后返回到主功能的值将是
5*4*3*2*1
。
摘要
在本教程中,我们讨论了递归函数以及如何在 Kotlin 中实现同样的功能。您可以搜索更多关于递归函数及其用法的信息。在下一个教程中,我们将讨论 Kotlin 中的参数类型。
Kotlin 位置、默认和命名函数参数
原文:https://www.studytonight.com/kotlin/kotlin-positional-default-and-named-function-arguments
在本教程中,我们将讨论 Kotlin 函数中不同类型的参数。参数是调用函数时传递给函数的值。
在 Kotlin 中,有多种类型的参数可以在声明和调用Kotlin 用户定义函数时使用。它们是:
-
位置参数
-
默认参数
-
命名参数
最后我们还会看到什么是vararg
。
Kotlin 位置论点
这些是任何语言中存在的基本类型的参数。这些是基于位置的参数。第一个参数对应函数定义中的第一个参数,第二个参数对应第二个参数,依此类推。
例如,
fun main() {
printInfo("Groot", 2)
}
fun printInfo(name: String, age: Int) {
println("Hi! My name is $name and I'm $age months old.")
}
在上面的代码中,"Groot"
和2
是name
和age
功能参数的位置参数。如果我们先试着颠倒他们的位置,即2
后试着颠倒"Groot"
,这在位置论证中是行不通的。我们可以通过使用命名参数来实现这一点。
Kotlin 默认参数
默认参数用于为函数参数提供默认值。考虑这样一种情况:如果用户在调用函数时没有传递任何值,我们希望为函数参数指定一个默认值,那么将使用默认值。我们可以使用默认参数来实现这一点。
我们可以在函数定义中定义默认值:
fun printInfo(name: String = "XYZ", age: Int = 18) {
println("Hi! My name is $name and I'm $age months old.")
}
这里,我们为name
定义了默认值 XYZ ,为age
定义了默认值 18 。让我们使用不同数量的参数来调用这个函数:
fun main() {
// Providing both the arguments
printInfo("Groot", 2)
// Providing none of the arguments
printInfo()
// Providing only name
printInfo("Groot")
}
// function definition
fun printInfo(name: String = "XYZ", age: Int = 18) {
println("Hi! My name is $name and I'm $age months old.")
}
嗨!我叫格鲁特,今年 2 个月。
嗨!我叫 XYZ,今年 18 个月。
嗨!我叫格鲁特,今年 18 个月。
说明:
-
在第一种情况下,提供了两个参数,并且选择这些参数而不是默认参数。
-
在第二种情况下,没有提供任何参数。因此,使用默认参数。
-
在第三种情况下,为
name
提供参数,但为age
采用默认参数。
但是在这种情况下,如果我们试图只通过age
,我们将会得到一个错误。
// Providing only age
printInfo(10) // ERROR
这是因为编译器会尝试将第一个参数即10
与第一个参数 name
进行映射。为了实现这种功能,我们将使用命名参数。
Kotlin 命名论证
在调用函数时,我们可以使用参数的名称来指定特定参数的特定参数。这些类型的参数被称为命名参数。
让我们通过只传递age
来调用同一个prinfInfo()
方法。这次我们就用命名的论点来称呼它:
fun main() {
// Providing only age
printInfo(age = 10)
}
fun printInfo(name: String = "XYZ", age: Int = 18) {
println("Hi! My name is $name and I'm $age months old.")
}
嗨!我叫 XYZ,今年 10 个月。
使用命名参数,我们还可以重新排列参数。我们只需要给出参数的名称,在调用函数时使用name = value
格式即可。
请记住一件事,如果我们开始在函数中使用命名参数,我们不能对其余参数使用位置参数。例如:
fun main() {
printInfo("XYZ", gender = "Male", "India") // ERROR
}
fun printInfo(name: String, gender: String, Nationality: String) {
println("Hi! My name is $name")
println("My gender is $gender")
println("I'm from $name")
}
在使用命名参数性别后,我们需要为每个参数命名。
锅vararg
vararg
代表可变数量的参数。Kotlin 允许我们使用vararg
向函数传递可变数量的参数。
让我们创建一个函数,它可以将变量数作为参数并返回它们的和:
fun main() {
findSum(1,2,10,6,5)
findSum(1)
}
// function taking variable number of arguments
fun findSum(vararg numbers: Int): Int {
var sum = 0
// loop around the arguments
for (number in numbers)
sum += number
return sum
}
摘要
在本教程中,我们讨论了各种类型的参数及其用法。我们还讨论了 Kotlin 中的 varargs。在下一个教程中,我们将讨论 Kotlin 中的 Lambda 函数/表达式。
Kotlin Lambda 表达式
原文:https://www.studytonight.com/kotlin/kotlin-lambda-expression
在本教程中,我们将讨论 Kotlin 中的λ表达式。Lambda 函数或表达式在 Kotlin 中并不新鲜,在 Python、Java 和 Javascript 等许多其他语言中都存在。
Lambda 函数类似于匿名函数。一个匿名函数是一个没有名字的函数。基本上,Lambda 表达式是一种简洁地创建函数并将它们作为参数传递、返回等的方式。我们可以称它们为简单函数。
λ表达式可以被视为一个变量。这意味着,我们可以将其作为参数传递给函数、从函数等返回。
Kotlin Lambda 表达
Kotlin 中 lambda 表达式的语法是:
val nameOfLambda : DataType = { argruments -> bodyOfLambdaFunction }
在兰达斯:
-
->
左侧提到论点。如果左边没有参数,可以去掉->
(我们将在例 1 中看到)。 -
λ的体在
->
之后出现,它不能为空。 -
λ的最后一个表达式被认为是返回语句(见例 2)。
-
如果没有返回值或者没有提到返回类型,
Unit
类型将被认为是返回类型,就像我们在 Kotlin 用户定义函数中解释的那样。 -
使用
invoke()
方法或通过在 Lambda 名称后添加()
来调用 lambda 函数(带参数)。
这与 Javascript 箭头函数非常相似。
让我们举几个代码示例。
Kotlinλ表达式-示例 1:
让我们从创建一个简单的 lambda 开始,它打印一个字符串:
fun main() {
// lambda expression with no argument
val lambda = { println("Lambdas are awesome!")}
// Calling lambda function using ()
lambda()
// Calling lambda function using invoke() function
lambda.invoke()
}
兰姆达斯真棒!
兰姆达斯真棒!
在这个例子中,参数和返回类型被删除了。
Kotlinλ表达式-示例 2:
让我们创建另一个寻找矩形区域的例子:
fun main() {
val area = {length: Int, breadth: Int -> length*breadth}
/*
This lambda is same as:
fun area(length: Int, breadth: Int){
return length*breadth
}
*/
println("Area of rectangle of dimension 4 and 5 is: ${area(4,5)}")
}
尺寸为 4 和 5 的矩形面积为:20
这里返回类型自动推断为Int
。
它在 Kotlinλ表达式中
如果 lambda 表达式中只有一个参数,则可以用it
关键字替换它。这是 Kotlin 使用的速记,非常有用。it
关键字将代表传递给 lambda 函数的单个参数。
让我们创建一个数组,并使用forEach
循环打印其中元素的方块:
fun main() {
val array = arrayOf(10,2,3)
// Long way
array.forEach { num -> println(num * num) }
// Shorthand
array.forEach { println(it*it) }
}
100
4
9
100
4
9
当我们在数组上使用 forEach 循环时,it
关键字指的是当前元素。
摘要
在本教程中,我们讨论了 Kotlin lambdas 或 Lambda 表达式。Lambdas 是有用的,使我们的代码简洁。Lambdas 在安卓应用开发中也大量使用。在下一个教程中,我们将讨论高阶函数。
Kotlin 高阶函数
原文:https://www.studytonight.com/kotlin/kotlin-higher-order-function
在上一个教程中,我们讨论了 Kotlin lambda 函数。在本教程中,我们将前进一步,讨论 Kotlin 中的高阶函数。
Kotlin 认为它的功能是作为一级公民。它允许一个函数被用作变量。因此,一个函数可以作为参数传递给另一个函数,从一个函数返回,存储在变量或数据结构中,等等。
Kotlin 高阶函数
将另一个函数作为自变量或返回一个函数的函数称为高阶函数。lambda 表达式通常作为参数传递给高阶函数,或者从高阶函数返回。匿名函数也可以用于同样的目的。
我们将看到一些例子,其中我们将传递函数和 lambdas 作为参数,或者从另一个函数返回它们。
Kotlin 函数作为参数
在本例中,函数sayHello()
作为参数传递给higherOrderFunction()
,并从main()
函数调用:
fun sayHello(name: String){
println("In sayHello() function")
println("Say hello to $name")
}
fun higherOrderFunction(functionName: (name: String)-> Unit, name: String){
println("In higher order function")
println("Calling sayHello() function...")
functionName(name)
}
fun main() {
higherOrderFunction(::sayHello, "Ninja")
}
在高阶函数
中调用 sayHello()函数...
在 sayHello()功能中
向忍者问好
上面的代码发生了什么:
-
sayHello()
函数只打印两个字符串。 -
higherOrderFunction()
函数接受两个参数。第一个参数是一个函数,第二个是一个字符串。要接受函数作为参数,我们需要在参数中以 lambda 表达式的形式定义它的定义。让我们看看它的分段:-
作为参数的函数名称为
functionName
。所以我们现在开始用functionName()
调用接受的函数(即sayHello()
)。 -
接下来我们添加了
(name: String)
,它反映了sayHello()
函数的参数。 -
->
之后我们提到了sayHello()
功能的返回类型。
-
-
在
higherOrderFunction()
函数内部我们调用functionName()
(也就是sayHello()
)并传递name
作为参数。 -
T o 传递一个函数作为参数我们使用
::
运算符。我们从main()
调用higherOrderFunction()
函数,并通过sayHello()
作为参数。
作为返回值的 Kotlin 函数
在本例中,我们将从higherOrderFunction()
函数返回sayHello()
函数。
fun sayHello(name: String){
println("In sayHello() function")
println("Say hello to $name")
}
fun higherOrderFunction(): (name:String) -> Unit{
println("In higher order function")
// return the sayHello function
return ::sayHello
}
fun main() {
val functionName = higherOrderFunction()
functionName("Ninja")
}
在高阶功能
中在 sayHello()功能
中向忍者问好
代码说明:
-
在
main()
函数中,调用higherOrderFunction()
,返回值存储在functionName
变量中。 -
在
higherOrderFunction()
功能中,返回类型被称为(name:String) -> Unit
。它表示sayHello()
函数的参数和返回类型(这是要返回的函数)。 -
使用
::
操作符返回sayHello()
功能。 -
返回的函数存储在
functionName
变量中。用functionName("Ninja")
叫,和叫sayHello("Ninja")
一样。
Kotlin·拉姆达作为论据
大多数情况下,我们传递λ表达式作为参数或者返回它,而不是函数。让我们看看我们讨论过的相同的例子,但这次我们将使用 lambdas。
fun higherOrderFunction(functionName: (name: String)->Unit, name: String){
println("In higher order function")
println("Calling received function...")
functionName(name)
}
fun main() {
higherOrderFunction({ name: String ->
println("Inside the lambda function")
println("Say hello to $name")
}, "Ninja")
}
在高阶函数
中调用接收函数...
在 lambda 功能里面
跟忍者打招呼
在这个例子中,我们没有单独创建一个函数sayHello()
,然后将其名称作为参数传递,而是创建了一个 lambda 表达式,并将其直接传递给我们的高阶函数。它的工作方式与在函数作为参数的情况下解释的方式相同。
Kotlin Lambda 作为返回值
最后,让我们看一个例子,其中 lambda 是从一个函数返回的:
fun higherOrderFunction(): (name:String) -> Unit{
println("In higher order function")
return {name ->
println("Inside the lambda function")
println("Say hello to $name")}
}
fun main() {
val functionName = higherOrderFunction()
functionName("Ninja")
}
在高阶功能
里面的λ功能
跟忍者打招呼
摘要
在本教程中,我们用多个例子讨论了 Kotlin 高阶函数。在下一个教程中,我们将讨论 Kotlin 中的内联函数。
Kotlin inline
关键字
原文:https://www.studytonight.com/kotlin/kotlin-inline-keyword
在本教程中,我们将使用inline
关键字讨论 Kotlin 中的内联函数。内联函数帮助我们在运行时节省内存,从而提高应用的性能。
在之前的教程中,我们讨论了 lambda 表达式和高阶函数。让我们举同一个例子:
fun higherOrderFunction(functionName: (name: String)->Unit, name: String){
println("In higher order function")
println("Calling received function...")
functionName(name)
}
fun main() {
higherOrderFunction({ name: String ->
println("Inside the lambda function")
println("Say hello to $name")
}, "Ninja")
}
在 IntelliJ 中,我们可以生成我们的 Kotlin 程序的字节码。为此,请转到工具>Kotlin>显示 Kotlin 字节码。我们可以反编译这个字节码,生成等价的 Java 代码。
我们将观察到,对于λ表达式,创建了一个新的函数对象。但这不是我们想要的。
每个高阶函数将创建一个新对象,并为其分配内存。这会增加运行时间开销。为了克服这个问题,我们使用内联函数。
Kotlin 内联函数
为了避免为每个高阶函数创建新对象,我们可以使用inline
关键字。它将帮助我们提高代码的性能。inline
关键字不是为高阶函数创建新对象,而是将内联函数内部的代码复制到调用它的地方。
功能前增加inline
关键字。
inline fun higherOrderFunction(functionName: (name: String)->Unit, name: String){
println("In higher order function")
println("Calling received function...")
functionName(name)
}
fun main() {
higherOrderFunction({ name: String ->
println("Inside lambda function")
println("Say hello to $name")
}, "Ninja")
}
如果我们在普通函数之前添加 inline 关键字,它不会导致任何性能变化。甚至 Intellij 也会建议去掉。
请记住内联关键字只应在高阶函数短时使用。如果高阶函数包含大量代码,那么生成的代码将非常长。
摘要
在本教程中,我们讨论了内联函数。他们一开始有点难以理解。添加 inline 关键字的唯一目的是提高性能。
Kotlin OOP
Kotlin 类和对象
原文:https://www.studytonight.com/kotlin/kotlin-class-and-object
在本教程中,我们将开始讨论 Kotlin 中的面向对象编程。
不同的语言遵循几种类型的编程范例来提供不同的特性。主要的编程范例有:
-
必要的
-
逻辑学的
-
功能的
-
面向对象的
最常用的范例是面向对象编程。Kotlin 还提供了抽象、封装、继承等 OOP 特性。以类、对象、接口等形式。但是 Kotlin并不是一个纯粹的 OOP 语言,因为它还提供了功能编程特性像 lambdas 、高阶函数等。因此,Kotlin 支持函数式和面向对象编程。
这是一段精彩的视频,解释了基本的 OOPs 概念:
现在我们将讨论 OOPs 的基础知识:类和对象
实际上,我们可能会发现不同的同类物体,但性质不同。让我们举一个手机的例子。每个手机都有一些属性,如型号、价格、颜色、尺寸、内存、内存等。为了能够定义不同的移动配置,我们必须有一些空白空间来归档,就像一个蓝图,使用它我们可以创建多个移动设备对象。我们可以通过一个类来实现这一点。
该类用于创建对象的蓝图。让我们继续这个例子,下面我们将定义一个名为移动的类,在其中我们将定义它的所有属性和方法,然后我们将创建该类的对象,这些属性有不同的值。把对象看成不同公司提供的手机,或者不同型号的手机,像 iPhone 11 Pro 可以是一个对象,三星 Galaxy S 20** 可以是另一个有自己配置的对象,然后一加 7 等等。**
Kotlin 班
使用class
关键字定义一个类。创建类的语法是:
class <class-name> // class header
{
// class body
}
Kotlin 课程有两个主要部分:
-
类头:包含类名、主构造器、父构造器等。(我们将在后续教程中了解构造器)
-
类体:类体包含属性、方法、二级构造器、init 块等。
我们将在接下来的教程中详细讨论它们。
让我们从创建一个简单的类 Mobile 开始。它包含以下属性和方法:
-
属性:
-
品牌
-
模型
-
物资需求计划(material requirements planning)
-
折扣
-
-
方法:
-
getActualPrice():会返还手机的折扣价。
-
printDetails():该功能将打印手机的详细信息。
-
class Mobile {
// brand of type String
var brand: String = ""
// model of type String
var model: String = ""
// mrp of type float
var mrp: Float = 0f
// discount of type float
var discount: Float = 0f
fun getActualPrice():Float{
return mrp - discount
}
fun printDetails(){
println("Mobile details:")
println("Brand: $brand")
println("Model: $model")
println("MRP: $mrp")
println("Discount: $discount")
}
}
我们已经创建了一个包含属性和方法的基本类。
关于 Kotlin 课程的要点是:
-
属性必须在创建对象时初始化。我们已经将
brand
&model
初始化为空字符串,并将mrp
&discount
初始化为 0 作为默认值。 -
默认情况下,Kotlin 中的类是公共的。
Kotlin 类对象
对象是真实世界的实体。它拥有类中声明的所有属性和方法。声明类的对象的语法是:
var varName = ClassName()
我们可以使用.
(点)运算符来访问一个类的属性和方法。在对象名称后添加.
和属性/方法名称:
var varName = ClassName()
varName.property = 0
varName.functionName()
让我们创建一个 Mobile 类的对象,并调用它的方法:
fun main() {
val mobile = Mobile()
mobile.brand = "iPhone"
mobile.model = "11 pro"
mobile.mrp = 100000f
mobile.discount = 1000f
println("Discounted price is: ${mobile.getActualPrice()}")
mobile.printDetails()
}
折扣价为:99000.0
手机详情:
品牌:iPhone
型号:11 pro
MRP: 100000.0
折扣:1000.0
说明:
-
在第 2 行中,创建了移动类的对象。
-
从第 3 行到第 6 行,提供了所有类属性的值。
-
在第 8 行,使用 getActualPrice()函数打印折扣价。
-
在第 10 行,调用 printDetails()函数。
摘要
在本教程中,我们讨论了类和对象。我们创建了一个基本类并创建了它的对象。在下一个教程中,我们将讨论构造器。
Kotlin 构造器——主构造器和辅助构造器
原文:https://www.studytonight.com/kotlin/kotlin-constructor-primary-and-secondary-constructor
在本教程中,我们将讨论 Kotlin 类构造器。创建类对象时,构造器用于初始化类属性。它可以被认为是一种特殊的功能。构造器在对象创建时被调用。每当我们创建一个类的对象时,都会自动调用构造器。
Kotlin 中有两种类型的构造器:
-
主构造器
-
二级建造师
只能有一个一级建造师****多个二级建造师。
Kotlin 主构造器
Kotlin 最重要的特点之一是简洁。从主构造器的声明可以看出。主构造器是类头的一部分。类的所有属性也成为了主构造器的一部分。
通过在类名末尾添加constructor()
来创建主构造器:
class ClassName constructor(){
}
也可以删除constructor
关键字:
class ClassName(){
}
这意味着,当我们定义一个普通类时,主承包商被创建。
让我们为在上一个教程中创建的 Mobile 类创建一个主构造器:
class Mobile (var brand: String, var model: String, var mrp: Float, var discount: Float) {
// class methods
fun getActualPrice():Float{
return mrp - discount
}
fun printDetails(){
println("Mobile details:")
println("Brand: $brand")
println("Model: $model")
println("MRP: $mrp")
println("Discount: $discount")
}
}
这里所有的类属性都被定义为主构造器的参数。
现在,让我们创建一个这个类的对象:
fun main() {
val mobile: Mobile = Mobile("iPhone", "11 pro", 100000f, 1000f)
println("Discounted price is: ${mobile.getActualPrice()}")
mobile.printDetails()
}
折扣价为:99000.0
手机详情:
品牌:iPhone
型号:11 pro
MRP: 100000.0
折扣:1000.0
现在变量由主构造器初始化。
但是有必要提供类属性的所有值。为此,我们还可以向主构造器提供默认值:
class Mobile (var brand: String = "", var model: String = "", var mrp: Float = 0f, var discount: Float = 0f)
带init
块的主构造器
在主构造器中,提供的值直接分配给类属性。如果我们想在赋值之前改变这些值,或者给主构造器添加一些逻辑,我们可以使用init
块。
下面是一个代码示例,
class Mobile constructor(brand: String, model: String, mrp: Float, discount: Float) {
var brand: String
var model: String
var mrp: Float
var discount: Float
// init function
init {
println("In init")
this.brand = brand.toUpperCase()
this.model = model.toUpperCase()
this.mrp = mrp
this.discount = discount
}
fun getActualPrice():Float{
return mrp - discount
}
fun printDetails(){
println("Mobile details:")
println("Brand: $brand")
println("Model: $model")
println("MRP: $mrp")
println("Discount: $discount")
}
}
现在我们可以创建对象并打印详细信息:
fun main() {
val mobile: Mobile = Mobile("iPhone", "11 pro", 100000f, 1000f)
println("Discounted price is: ${mobile.getActualPrice()}")
mobile.printDetails()
}
In init
折扣价为:99000.0
手机详情:
品牌:IPHONE
型号:11 PRO
MRP: 100000.0
折扣:1000.0
关于init
区块的要点:
-
init
块总是在主构造器之后调用。 -
一个类可以有多个
init
块。
Kotlin 二级建造师
辅助构造器用于初始化一组值。使用constructor
关键字创建辅助构造器。一个类可以有一个或多个二级构造器。
让我们在 Mobile 类中创建两个构造器:
class Mobile {
var brand: String = ""
var model: String = ""
var mrp: Float = 0f
var discount: Float = 0f
// first secondary constructor
constructor(_brand: String, _model: String){
this.brand = _brand
this.model = _model
}
// second secondary constructor
constructor(_mrp: Float, _discount: Float){
this.mrp = _mrp
this.discount = _discount
}
fun getActualPrice():Float{
return mrp - discount
}
fun printDetails(){
println("Mobile details:")
println("Brand: $brand")
println("Model: $model")
println("MRP: $mrp")
println("Discount: $discount")
}
}
现在我们可以通过根据构造器传递值来创建一个对象:
fun main() {
val mobile: Mobile = Mobile("iPhone", "11 pro")
println("Discounted price is: ${mobile.getActualPrice()}")
mobile.printDetails()
}
折扣价为:0.0
手机详情:
品牌:iPhone
型号:11 pro
MRP: 0.0
折扣:0.0
关于二级构造器的几点:
-
二级建造师没那么常见。它们通常被避免,在对象创建之前,
init
块可以用来执行任何特定的任务。 -
If the Primary constructor is already present then each secondary constructor should call the primary constructor. It is called using this():
constructor(_brand: String, _model: String): this()
-
我们也可以使用 this() 从另一个二级构造器调用一个二级构造器:
constructor(_brand: String, _model: String): this(10f,1f)
该构造器正在调用其他具有值 10.0 和 1.0 的构造器用于
mrp
和discount
。 -
我们也可以使用 super() 调用父类的构造器(在继承的情况下)。我们将在 Kotlin 继承教程中讨论它。
总结
在本教程中,我们讨论了 Kotlin 中的构造器。我们看到了主构造器、带init
块的主构造器和次构造器。我们将在下一个教程中讨论伴随对象。
Kotlin 伴随对象
原文:https://www.studytonight.com/kotlin/kotlin-companion-object
在本教程中,我们将了解 Kotlin 伴随对象。在一个类中,属性链接到对象,即我们可以使用对象名来访问它们。每个对象都有自己值的所有属性。
可能会有这样一种情况,我们希望类的所有对象都有一些共同的属性。这些类型的属性和方法被称为类级别字段。它们由编译器在创建类时初始化,并在类的所有对象之间共享。在 Java 等其他语言中,它们是使用static
关键字创建的。在 Kotlin 中,伴随对象用于声明类级别字段。
创建和访问伴随对象
伴随对象是使用companion
关键字创建的。让我们创建一个类员工并创建一个名为测试的伴随对象:
class Employee {
var salary:Int = 0
fun printSalary(){
println("Salary is: ${this.salary}")
}
companion object Test{
var i: Int = 1
fun printI(){
println("Value of i: $i")
i++
}
}
}
雇员类包含一个名为测试的companion
对象,该对象包含一个变量i
和函数printI()
。该类还包含一个变量salary
和一个函数printSalary()
,可以使用该类的对象进行访问。
使用类名访问伴随对象中的字段。也可以使用类名或对象名来访问它们。让我们在main()
函数中使用这个类:
fun main() {
Employee.printI() // Access printI() method using class name
Employee.Test.printI() // Access printI() method using class name and companion object name
}
I 值:1
I 值:2
关于伴随对象的几个要点:
-
使用类名而不是对象名来访问伴随对象。
-
如果缺少伴随对象名称,则为其指定默认名称
Companion
。 -
一个类中只能有一个伴随对象。
-
当加载类时,伴随对象被初始化。
-
If we try to access class level fields using objects or objects fields using the class name, an error will be thrown:
val employeeObject = Employee() employeeObject.printI() // Error Employee.printSalary() // Error
摘要
在本教程中,我们讨论了 Kotlin 中的伴随对象。它们可以被认为是 Java static
关键字的替换。它们在创建类时会派上用场。在下一个教程中,我们将讨论 Kotlin 中的获取者和设置者。
Kotlin 获取器和设置器函数
原文:https://www.studytonight.com/kotlin/kotlin-getter-and-setter-functions
在本教程中,我们将学习 Kotlin 中用于获取类属性值和设置类属性值的获取器和设置器。在前面的教程中,我们看到类内部声明的属性是使用.
运算符访问的。如果我们有一个定义如下的类员工:
class Employee{
var salary: Int = 0
var name: String = ""
}
我们可以创建员工类的对象,并使用.
运算符访问属性:
val employee = Employee()
employee.salary = 340000
employee.name = "Ninja"
println("The salary of ${employee.name} is ${employee.salary}")
每当我们试图获取或设置某个属性的值时,属性不会被直接访问。获取器和设置器函数用于获取和设置属性值。
什么是吸气剂和沉降剂?
Getter 和 Setter 是由 Kotlin 为每个类属性默认生成的函数。它们用于访问该属性。
如果我们试图调用classname.property = value
内部调用set()
函数,如果我们试图使用classname.property
获取属性值,则内部调用get()
函数。
为什么 Getter 和 Setter 函数?
最好不要将类的变量暴露在它之外。如果您来自 Java,那么您必须已经将类属性声明为私有,并为其创建了获取器和设置器方法。默认情况下,Kotlin 提供此功能。
Kotlin 的吸气剂和设置剂
默认get()
和set()
功能如下:
class Person{
var name: String = ""
get() = field
set(value) {
field = value
}
val age: Int = 0
get() = field
}
用var
声明的属性同时具有get()
和set()
功能。但是用val
声明的属性只有get()
功能。这是因为val
的值不能重新分配。
field
关键字用于表示变量。value
用于表示要分配给变量的值。它也可以改变。这些get()
和set()
功能是多余的,因为 Kotlin 默认提供它们。
定义自定义获取器和设置器
我们还可以提供自定义 get()
和set()
功能:
class Person{
var name: String = ""
get() {
println("Inside get() of name")
return field.toString()
}
set(value) {
println("Inside set() of name")
if (value.length < 3)
field = "INVALID NAME"
else
field = value
}
val age: Int = 18
get(){
println("Inside get() of age")
return field
}
}
这里我们为name
创建了自定义get()
和set()
功能,为age
创建了自定义get()
。让我们创建这个类的对象并打印输出:
fun main() {
val person = Person()
person.name = "Ninja" // calls set() function
println("The age of ${person.name} is ${person.age}") // calls get() functions
}
姓名
内定()姓名
内定()年龄
忍者年龄 18
摘要
在本教程中,我们讨论了 Kotlin 中的获取器和设置器函数,并创建了自定义的获取器和设置器。使用自定义的获取器和设置器,我们可以在给属性赋值之前添加验证,或者对值执行一些操作。我们将在下一个教程中讨论继承。
Kotlin 访问修饰符
原文:https://www.studytonight.com/kotlin/kotlin-access-modifiers
在本教程中,我们将介绍 Kotlin 中的可见性修改器或访问修改器。访问修饰符或可见性修饰符用于定义类、函数、字段、接口等的范围。可见性修饰符关键字限制类、函数、属性等的使用,并声明它们是否在它们的子类、其他文件、类、其他包中可用。
在 Kotlin 中,可见性修饰符可以应用于类、构造器、对象、接口、函数、属性及其设置器。Getters 与属性具有相同的可见性。
Kotlin 中有四个可见性修饰符:
-
私人的
-
保护
-
内部的
-
公众
默认可见性修改器是公共的。这意味着,如果我们没有为类、函数、属性等指定任何可见性修饰符,那么默认情况下,编译器会将其视为公共的。
根据放置位置的不同,可见性修饰符有不同的含义。我们会一个一个来看。
顶级字段的可见性修饰符
顶级字段是放置在类或接口之外的字段。它们直接存在于任何 Kotlin 文件中。
对于顶级字段,不同的可见性修饰符意味着:
-
public
-是默认修饰符,可以省略。这意味着声明随处可见。它们可以用于不同的文件、类、包等。 -
internal
-内部标记的声明在同一个模块中可见。模块是指一起编译的一组 Kotlin 文件。在项目开发过程中,我们可以在同一个项目中有多个模块。其他模块可以是支持主应用的库或助手应用。 -
private
-标有private
的声明仅在同一 Kotlin 文件中可用。它们不能在 T2 之外使用。kt 文件。
受保护的修饰符不适用于顶级字段。
类和接口中的可见性修饰符
类中的函数、属性和对象可以访问修饰符。请注意,整个类或接口的可见性取决于它在顶层的可见性修饰符。
类中的可见性修饰符表示:
-
public
-任何能看到该类的人也能看到它的所有公开声明。这意味着公开声明随处可见。它们在其他文件、类、包甚至模块中都是可见的。 -
internal
-与顶级字段相同,它们在同一个模块中可见。 -
protected
-标记有protected
的声明仅在类及其子类中可见。他们在课外是看不见的。这意味着标有protected
关键字的函数不能在类或其子类之外使用。 -
private
-标有private
关键字的声明仅在该类中可见。它们在类外不可见,甚至在子类中也不可见。
让我们看一个类中可见性修饰符的例子:
package oop
open class Employee {
// Function visible only inside class
private fun privateFunction(){
}
// Function visible in same
internal fun internalFunction(){
}
// Function visible everyWhere
fun publicFunction(){
}
// Function visible only in Employee class and its subclasses
protected fun protectedFunction(){
}
}
class Developer: Employee() {
// privateFunction() is not visible here
}
fun main() {
// privateFunction() and protectedFunction() are not visible here
}
*有关继承概念,请参见下一个教程。
摘要
在本教程中,我们详细讨论了访问修饰符,即公共、私有、内部和受保护。在下一个教程中,我们将学习 Kotlin 中的继承概念。
Kotlin 继承
在本教程中,我们将学习 Kotlin 中的继承概念,这是面向对象编程的一个主要特征。我们将学习如何在 Kotlin 的类中实现继承,主构造器和次构造器如何在继承中起作用,我们还将学习如何重写类的方法和属性。
什么是继承?
继承是面向对象编程最重要的特征之一。它允许一个类继承另一个类的特性。
假设您创建了一个类Vehicle
,它具有与车辆相关的属性和方法。现在我们需要创建另一个类Car
,它有许多车辆共有的属性。因此,我们可以在Car
类中继承Vehicle
类,而不是重新编写相同的代码。类似地,我们可以创建一个类TwoWheeler
,它同样可以从 Vehicle 类继承一些基本的公共属性,并且可以有自己的一些属性。
通过这种方式,可以使用继承来正确地划分代码,从而实现代码的重用,并为代码提供更多的结构。
继承允许新类继承现有类的属性和方法。现有类或继承新类的类称为基类或父类或超类。继承已有类特征的新类称为派生类或子类或子类。
Kotlin 的继承
Kotlin 的所有职业默认都是final
。这意味着这些职业是不可继承的。为了使类可继承,我们在类头中添加open
关键字。
子类使用:
运算符继承父类。继承类的语法是:**
open class Parent{
// Parent class features
}
class Child : Parent(){
// Child class features
}
让我们创建一个非常基本的继承示例:
// parent class
open class Vehicle{
fun run(){
println("Vehicle runs....")
}
}
// child class
class Car : Vehicle(){
fun seats(){
println("Car has 4 seats")
}
}
fun main() {
val car = Car()
car.seats()
// calling method defined in parent class
car.run()
}
汽车有 4 个座位
车辆行驶....
在这个例子中,我们已经将类Vehicle
标记为开放,以使其可继承。类Car
继承类Vehicle
,从而继承其功能run()
。
在 Kotlin 中,一个类只能继承一个类,这与 Java 相同。由此可见, Kotlin 不允许多重继承。但是一个类可以实现很多接口,我们将在接下来的教程中讨论。
继承中的主构造器
如果父类有主构造器,那么子类必须调用父类的主构造器。在上面的例子中,在Car
类中,我们也调用了Vehicle
类的主构造器(由于我们没有提供主构造器,主构造器是由编译器创建的)。让我们将属性传递给父类,看看它们是如何工作的。
/*
Vehicla class has properties:
- is the vehicle for carrying passengers
- no. of tyres
- fuel capacity of vehicle
*/
open class Vehicle(carryPassenger: Boolean, tyres: Int, fuelCapacity: Int){
init {
println("Does Vehicle carry passenger: $carryPassenger")
println("Tyres in Vehicle: $tyres")
println("Fuel capacity of Vehicle: $fuelCapacity")
}
}
// child class with extra airBags property
class Car(carryPassenger: Boolean, tyres: Int, fuelCapacity: Int, airBags: Int) : Vehicle(carryPassenger, tyres, fuelCapacity){
// init function for child class
init {
println("No. of air bags in car: $airBags")
}
}
fun main() {
val car = Car(true, 4, 50, 4)
}
车辆是否载客:真
车内轮胎:4
车内燃油容量:50
车内气囊数量:4
在这个例子中,我们在创建子类的对象时传递了值。从这些属性中,我们将carryPassenger
、tyres
、fuelCapacity
传递给父类、Vehicle
的主构造器。
创建Car
类的对象时,调用子类 Car 的主构造器(默认),子类 Car 内部调用父类 Vehicle
的主构造器,首先调用,然后调用它的init
块。之后,子类Car
的主默认构造器完成,然后执行子类 Car
的init
块。
继承中的辅助构造器
如果基类没有主构造器,但是有次构造器,那么派生类应该使用super
关键字调用基类的次构造器。
open class Vehicle{
// secondary constructor
constructor(carryPassenger: Boolean, tyres: Int, fuelCapacity: Int){
println("Does Vehicle carry passenger: $carryPassenger")
println("Tyres in Vehicle: $tyres")
println("Fuel capacity of Vehicle: $fuelCapacity")
}
}
// child class
class Truck: Vehicle{
// secondary constructor calling super for parent class
constructor(carryPassenger: Boolean, tyres: Int, fuelCapacity: Int, loadCarryCapacity: Int): super(carryPassenger, tyres, fuelCapacity){
println("Load carrying capacity is: $loadCarryCapacity")
}
}
fun main() {
val truck = Truck(false, 10, 200, 1000)
}
车辆载客吗:假
车内轮胎:10
车辆燃油量:200
载重量:1000
在本例中,Truck
类的二级构造器使用super
关键字调用Vehicle
类的二级构造器。通过super
调用时,会提供父类所需的所有参数。
Kotlin 函数覆盖
在继承中,我们可以在派生类中提供基类函数的具体实现。这意味着如果一个函数存在于父类中,那么我们可以在子类中提供相同函数的不同实现。被称为功能超越。
在 Kotlin 中,默认情况下功能也是final
。要覆盖一个函数,它必须在父类中标记为open
(就像类一样),在子类中,我们必须使用关键字override
而不是open
来指定我们已经覆盖了该函数。
****功能名称和参数应相同**。
并且,子类函数的返回类型可以是父类函数的子类型。
让我们看一个例子,其中我们将重写基类的两个方法:
// parent class
open class Vehicle{
open fun run(){
println("Vehicle is running")
}
open fun drivenBy(name: String){
println("Vehicle is driven by: $name")
}
}
// child class
class Jeep: Vehicle(){
override fun run() {
println("Driving a Jeep")
}
override fun drivenBy(name: String) {
println("Jeep is driven by $name")
}
}
fun main() {
val jeep = Jeep()
jeep.run()
jeep.drivenBy("Ninja")
}
驾驶吉普车
吉普车由忍者驾驶
在这个例子中,我们覆盖了Vehicle
类的两个方法run()
和drivenBy()
,并在Jeep
类中覆盖了它们。
我们也可以使用super
关键字在子类内部调用父类函数。
Kotlin 覆盖属性
同样,我们也可以覆盖属性并在子类中更改它们的值。属性应该标记为open
以便覆盖它们,并且当我们覆盖属性时,在子类中使用override
关键字,就像我们覆盖类函数一样。
package inheritance
// parent class
open class Vehicle{
open val color: String = "Black"
open fun printColor(){
println("The color of vehicle is: $color")
}
}
// child class
class Jeep: Vehicle(){
override val color: String = "Red"
override fun printColor(){
println("The color of Jeep is: $color")
}
}
fun main() {
val jeep = Jeep()
jeep.printColor()
}
吉普的颜色是:红色
摘要
在本教程中,我们讨论了 Kotlin 中的继承、如何在类中创建父子关系、构造器在 inheritance 期间的行为以及方法和属性重写。在下一个教程中,我们将讨论 Kotlin 中的抽象类。
Kotlin 抽象类
原文:https://www.studytonight.com/kotlin/kotlin-abstract-class
在上一个教程中,我们讨论了继承。我们现在就先走一步,讨论一下 Kotlin 中的抽象类。
假设我们有一个类叫做Shape
。它具有计算形状面积的功能area()
。现在我们希望每个子类都必须实现这个area()
函数来计算它们各自的面积。不提供Shape
类的area()
法体,我们可以标记为abstract
。
通过将其标记为摘要,我们确保以下内容:
-
现在不需要在
Shape
类中提供area()
函数的函数定义体。 -
子类必须覆盖这个
area()
函数并提供自己的实现,否则编译器会给出错误。
然后如果类像Square
、Rectangle
、Circle
等。继承Shape
类,这些类必须覆盖area()
函数,否则编译器会抛出错误。
Kotlin 抽象类
如果一个类的任何功能都标有abstract
关键字,那么这个类也应该标有abstract
关键字。让我们首先看一个抽象类的基本例子:
abstract class Shape{
abstract fun area()
}
class Square: Shape() {
override fun area() {
println("Area of square: side*side")
}
}
class Circle: Shape() {
override fun area() {
println("Area of circle: 3.14*r*r")
}
}
fun main() {
val square = Square()
val circle = Circle()
square.area()
circle.area()
}
正方形面积:边边
圆形面积:3.14r*r
在这个例子中,我们创建了一个抽象类Shape
。Square
类和Circle
类继承了 Shape 类并覆盖了area()
方法。
让我们讨论一些关于抽象类的要点:
-
如果一个类有抽象属性或抽象函数,那么这个类必须被标记为抽象的。
-
抽象类不能被实例化。这意味着我们不能创建抽象类的对象。
-
不需要在抽象类中添加 open 关键字,因为它们是要被继承的,因此默认情况下是 open。
-
抽象可以具有抽象和非抽象(通常定义的)功能和属性。
-
抽象函数没有主体。
-
在抽象类中,默认情况下所有成员都是非抽象的。我们需要添加
abstract
关键字,让它们变得抽象。
让我们看一个例子来说明以上几点:
abstract class Shape{
abstract var sides: Int
abstract fun area()
fun sayShape(){
println("It is a shape...")
}
}
class Square: Shape() {
override var sides: Int = 4
override fun area() {
println("Area of square: side*side")
}
}
class Circle: Shape() {
override var sides: Int = 0
override fun area() {
println("Area of circle: 3.14*r*r")
}
}
fun main() {
val square = Square()
val circle = Circle()
println("Side of square: ${square.sides}")
println("Side of Circle: ${circle.sides}")
square.area()
circle.area()
square.sayShape()
circle.sayShape()
}
正方形边:4
圆边:0
正方形面积:边边
圆面积:3.14r*r
是一个形状...
是一个形状...
摘要
在本教程中,我们讨论了抽象类。在下一个教程中,我们将讨论接口及其实现。
Kotlin 接口
在本教程中,我们将学习 Kotlin 接口。Kotlin 中的接口类似于抽象类,但有一些关键区别。
一个接口可以被认为是一个完全抽象类。这意味着默认情况下,一个接口的所有功能和属性都是抽象的。
接口用于定义类的蓝图,这意味着我们可以在接口中提供函数的名称以及函数的完整声明,包括其参数和返回类型,当任何类将实现该接口时,该类将必须为这些函数提供定义。
在 Java 8 之前,接口中只允许函数声明。我们无法在接口中定义函数体。但是在 Java 8 中,我们得到了功能来添加功能体也。Kotlin 默认情况下提供此功能。因此在 Kotlin 中,函数在接口中也可以有一个主体。
这使得接口和抽象类非常相似。抽象类和接口的关键区别是:一个类只能继承一个抽象类,但是它可以继承很多接口。如果需要继承多个类,那么我们可以选择接口。
Kotlin 接口
在 Kotlin 中定义接口的语法是:
interface A{
var x:Int // abstract property
fun sayHello() // asbtract method
fun sayBye(){
// Default implementation of sayBye()
}
}
默认情况下,接口的所有属性和功能都是抽象的,除非我们提供它们的实现。
Kotlin:实现接口
接口也是使用用于继承类的相同:
运算符继承的。让我们创建一个继承接口A
和B
的类C
:
// first interface
interface A{
fun sayHelloByA()
fun sayByeByA(){
println("Bye from A....")
}
}
// second interface
interface B{
fun sayHelloByB()
fun sayByeByB(){
println("Bye from B....")
}
}
// class implementing first and second interface
class C: A,B{
override fun sayHelloByA() {
println("Hello from overridden A....")
}
override fun sayHelloByB() {
println("Hello from overridden B....")
}
}
在这个例子中,两个接口A
和B
都有两个功能:一个是抽象的,一个是默认实现的。类C
继承了两个接口,并覆盖了它们的抽象函数。
让我们创建类C
的对象,并调用它的函数:
fun main() {
val c = C()
c.sayHelloByA()
c.sayHelloByB()
c.sayByeByA()
c.sayByeByB()
}
超驰 A 的你好....
来自被覆盖的乙的你好....
拜拜....
再见....
如果两个接口功能相同?
假设接口A
和接口B
都有一个名为sayHello()
的函数,默认实现。现在如果类C
继承了两个接口A
和B
,那么就会有冲突。类C
会给出一个错误:
interface A{
fun sayHello(){
println("Hello from A....")
}
}
interface B{
fun sayHello(){
println("Hello from B....")
}
}
class C: A,B { // Error
}
错误:(11,1) Kotlin:类‘C’必须覆盖公共开放趣味 sayHello():A 中定义的单元,因为它继承了它的多个接口方法
这是因为类C
从接口A
和B
获得了方法sayHello()
的实现。为了解决这个冲突,类C
必须覆盖sayHello()
方法并提供其实现:
interface A{
fun sayHello(){
println("Hello from A....")
}
}
interface B{
fun sayHello(){
println("Hello from B....")
}
}
class C: A,B {
override fun sayHello() {
println("Hello from C....")
}
}
fun main() {
val c = C()
c.sayHello()
}
你好,来自 C....
调用 A 或 B 的实现:
如果我们想调用sayHello()
的A
或B
实现,而不是提供我们自己的实现,那么我们可以使用super
关键字和接口名称来调用它,如下所示:
interface A{
fun sayHello(){
println("Hello from A....")
}
}
interface B{
fun sayHello(){
println("Hello from B....")
}
}
class C: A,B {
override fun sayHello() {
super<A>.sayHello()
super<B>.sayHello()
}
}
fun main() {
val c = C()
c.sayHello()
}
你好,来自 A....
你好,来自 B....
摘要
在本教程中,我们学习了 Kotlin 中的接口及其实现。我们还看到了如果两个接口有相同的方法声明,如何解决冲突,并且我们讨论了在多个接口的情况下函数调用的顺序。在下一个教程中,我们将讨论嵌套类和内部类。
Kotlin 嵌套类和内部类
原文:https://www.studytonight.com/kotlin/kotlin-nested-and-inner-class
在本教程中,我们将讨论在 Kotlin 的另一个类中创建类的两种方法,第一种是 Kotlin嵌套类,另一种是 Kotlin内部类。
Kotlin 嵌套类
我们可以直接在另一个类中创建一个嵌套类。默认情况下,嵌套类本质上是静态的。这意味着我们可以使用嵌套类的属性和函数,而无需创建外部类的对象。可以使用.
运算符直接访问它们。
在嵌套类中:
-
在嵌套类中,我们不能访问外部类(动物)的成员。
-
使用
.
运算符直接访问嵌套类成员,而不创建外部类的对象。
以下是嵌套类的语法:
class Outer{
// Members of Outer class
class Nested{
// Members of Nested class
}
}
以及创建嵌套类对象的语法:
val obj = Outer.Nested()
我们可以使用外部类名创建嵌套类的对象。
Kotlin 嵌套类示例:
让我们举个例子,
class Animal{
// outer class property
val legs = 4
class Dog{
// nested class proprty
val say = "Woof"
val hasTail = true
fun tail(){
println("Dog has tail: $hasTail")
}
}
}
fun main() {
// Creating object of nested class directly
val dog = Animal.Dog()
// Accessing inner class
dog.tail()
println("Dog says: ${dog.say}")
}
狗有尾巴:真
狗说:汪汪
Kotlin 内班
Kotlin 内部类是使用inner
关键字创建的。可以认为是特殊嵌套类。
在内部类中:
-
内部类维护外部类的一个实例,因此,它可以访问外部类的成员。
-
我们不能在接口或非内部类中声明内部类。
-
我们不能直接创建内部类的对象。它可以使用外部类对象创建。
以下是语法:
class Outer{
// Members of Outer class
inner class Inner{
// Members of Inner class
}
}
为了创建内部类的对象,
val outerObj = Outer()
// using outer class object to create inner class object
val innerObj = outerObj.Inner()
正如您在上面的语法中看到的,我们首先创建外部类的对象,然后使用它来创建内部类的对象。
Kotlin 内部类示例:
让我们举个例子,
class Animal{
// outer class property
val legs = 4
inner class Dog{
// inner class property
val say = "Woof"
val hasTail = true
fun tail(){
println("Dog has tail: $hasTail")
}
fun printLegs(){
println("No of legs are: $legs")
}
}
}
fun main() {
// Creating object of outer class
val animal = Animal()
// Creating object of inner class
val dog = animal.Dog()
// Accessing inner class
dog.tail()
dog.printLegs()
println("Dog says: ${dog.say}")
}
狗有尾巴:真
腿数:4
狗说:汪汪
摘要
在本教程中,我们讨论了 Kotlin 嵌套类和内部类。我们还介绍了如何从main()
功能访问他们的成员。在下一个教程中,我们将介绍 Kotlin 的数据类。
Kotlin 数据类
在本教程中,我们将介绍 Kotlin 中数据类的概念。在每个项目中,我们需要一些类,它们的唯一目的是存储数据。这些类被称为数据类或数据访问对象或数据传输对象等。
数据类主要包含:
-
变量及其获取者和设定者,
-
构造器,
-
一些功能如
toString()
、equals()
、hashCode()
等。
在 Java 中,我们需要编写大量的样板代码来定义数据类。让我们在 Java 中创建一个简单的Person
类,它有一些属性。这就是 Java 中的代码:
public class Person {
private String name;
private String gender;
private int age;
public Person(String name, String gender, int age) {
this.name = name;
this.gender = gender;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", gender='" + gender + '\'' +
", age=" + age +
'}';
}
}
写这段代码真的很烦人,因为它只是保存数据并提供管理数据的实用功能。Kotlin 通过引入数据类解决了这个问题。
Kotlin 数据类
使用data
关键字创建数据类。默认情况下,Kotlin 数据类提供:
-
类属性的获取器和设置器(对于普通类也是如此)。
-
toString()
功能打印对象的详细信息。 -
copy()
将一个对象的内容复制到另一个对象的功能。 -
equals()
和hashCode()
函数用于散列和比较。 -
componentN()
在构造器中按照属性的声明顺序对应的函数。
让我们在 Kotlin 中创建相同的数据类Person
(就像我们在上面的 Java 中所做的那样):
data class Person(var name: String, var gender: String, var age: Int)
仅此而已。这是 Kotlin 简洁的一个很好的例子。
让我们创建一个这个类的对象并打印出来:
fun main() {
val man = Person("Ninja", "Male", 18)
println(man)
}
人(姓名=忍者,性别=男,年龄=18)
打印对象时,调用toString()
函数本身。所以从 Kotlin 数据类的例子中,我们可以看到创建一个数据类然后使用它是多么容易,所有的基本函数都是由 Kotlin 自动定义的。
对数据类的要求
要创建数据类,应满足以下要求:
-
在主构造器中,至少应该有一个参数。
-
主构造器中的所有参数必须用
val
或var
标记。 -
数据类不能是抽象的、开放的、密封的或内部的。
复制数据类中的对象属性
如果我们想为 Kotlin 中的任何数据类创建一个新对象,使用另一个对象的一些属性。然后我们可以使用copy()
功能来实现:
fun main() {
val man = Person("Ninja", "Male", 18)
val woman = man.copy(gender = "Female")
println(man)
println(woman)
}
人(姓名=忍者,性别=男,年龄=18)
人(姓名=忍者,性别=女,年龄=18)
当我们使用copy()
函数从任何对象复制单个属性值时,我们应该使用命名参数,否则该值可能会被分配给其他变量。
Kotlin 数据类:hashCode
和equals
函数
equals()
和hashCode()
功能用于检查两个物体是否相等。hashCode()
生成一个对象的哈希值。如果两个对象的所有对应值相等,则两个对象的哈希值相同。equals()
功能也用于检查两个物体是否相等。
让我们举一个代码示例:
fun main() {
val man = Person("Ninja", "Male", 18)
val manNew = Person("Ninja", "Male", 18)
val woman = man.copy(gender = "Female")
if (man.hashCode() == manNew.hashCode())
println("man and manNew are equal")
if (man.hashCode() == woman.hashCode())
println("It will not be printed")
if (man.equals(manNew))
println("man and manNew are equal")
if (man.equals(woman))
println("It will not be printed")
}
人和曼诺是平等的
人和曼诺是平等的
析构数据类对象- componentN()
函数
如果我们想把一个对象的属性映射成独立变量,那么这是一个乏味的任务。在 Kotlin 中,我们可以使用 销毁声明 来销毁一个对象并获取其在自变量中的属性。让我们把man
物体破坏成独立的变量:
fun main() {
val man = Person("Ninja", "Male", 18)
val (name,gender) = man
println("Independent variable name: $name")
println("Independent variable gender: $gender")
}
自变量名称:忍者
自变量性别:男
这是可能的,因为编译器将为每个属性生成componentN()
函数,如:
man.component1() // Ninja
man.component2() // Male
man.component3() // 18
因此,如果您有一个存储了大量属性值的数据类对象,我们可以使用这个析构声明将数据类对象的属性值存储到自变量中。
摘要
至此,本教程结束。在本教程中,我们了解了 Kotlin 数据类及其提供的功能。Kotlin 数据类减少了样板代码,并提供了获取器、设置器、toString、equals 等。自动通用功能。在下一个教程中,我们将讨论 Kotlin 中的枚举。
Kotlin 枚举
在本教程中,我们将了解 Kotlin Enum。在开发应用时,可能会出现这样一种情况,即我们希望一个变量只具有一组给定的允许值,例如,如果我们有一个变量pizzaSize
,那么它应该具有以下值:小、中、大。
在 Kotlin 和 Java 中,枚举帮助我们实现了这一点。
在 Kotlin 中,我们可以借助enum
关键字创建一个枚举类。Kotlin 枚举可以有属性、功能,可以实现接口等。
Kotlin 枚举类
让我们创建一个包含比萨饼大小的简单枚举类:
enum class pizza{
SMALL, MEDIUM, LARGE
}
让我们在main()
函数中使用这个枚举:
fun main() {
val pizzaSize = pizza.LARGE
println("Size of pizza ordered is $pizzaSize")
}
订购的披萨尺寸很大
每个枚举常量充当一个单独的对象。它们用逗号隔开。在上例中,SMALL
、MEDIUM
和LARGE
为对象。
Kotlin 枚举:初始化常量
在 Kotlin 枚举中可以有主构造器。因为枚举中的常量是实例,所以可以通过向构造器传递值来初始化它们:
enum class pizza(val diameter: Int){
SMALL(10),
MEDIUM(12),
LARGE(14)
}
让我们在main()
函数中使用这个枚举:
fun main() {
val pizzaSize = pizza.LARGE
println("Size of pizza ordered is $pizzaSize")
println("Diameter of LARGE pizza is ${pizzaSize.diameter}")
}
点的披萨尺寸大
大披萨的直径是 14
正如您在上面的示例中所看到的,我们在枚举类中包含了更多的数据,并将其与枚举实例相关联。同样,如果我们愿意,我们可以添加更多的信息。
Kotlin 枚举:实现接口
在 Kotlin 中,我们甚至可以在枚举类中实现一个接口。常量分别覆盖接口功能:
// interface for implementing
interface Price{
fun getPrice(): Int
}
// enum class
enum class pizza(val diameter: Int): Price{
// enum constant implementing interface function
SMALL(10){
override fun getPrice(): Int {
return 250
}
},
MEDIUM(12){
override fun getPrice(): Int {
return 450
}
},
LARGE(14){
override fun getPrice(): Int {
return 600
}
}
}
现在我们可以使用枚举常量访问这些函数:
fun main() {
val pizzaSize = pizza.LARGE
println("Size of pizza ordered is $pizzaSize")
println("Diameter of LARGE pizza is ${pizzaSize.diameter}")
println("Price of LARGE pizza is ${pizzaSize.getPrice()}")
}
点的披萨尺寸大
大披萨直径 14
大披萨价格 600
因此,使用这种方法,我们甚至可以向枚举常量提供函数,以便在代码需要时提供任何逻辑。
通过首先定义一个 Kotlin 接口,然后在我们的枚举类中使用它,我们可以对我们定义的枚举常量有更多的控制,甚至可以在其中包含更多的信息。
Kotlin 枚举:values
和valueOf
功能
在 Kotlin 中,默认情况下,我们在每个枚举中都有两个函数。values()
函数返回一个包含枚举类所有常量的数组。使用valueOf(name: String)
函数,我们可以使用枚举常量的字符串值获得常量。
让我们使用values
和valueOf
功能:
fun main() {
for(pizza in pizza.values()){
println(pizza)
}
val largePizza = pizza.valueOf("LARGE")
println("Diameter: ${largePizza.diameter}")
}
小
中
大
直径:14
在上面的代码示例中,我们使用values()
函数获取所有枚举值,然后使用 for 循环迭代这些值,最后使用valueOf
函数使用其字符串值获取枚举常量。
摘要
在本教程中,我们了解了 Kotlin Enums 及其用法。在下一个教程中,我们将讨论 Kotlin Sealed 类。
Kotlin 密封类
在本教程中,我们将学习Kotlin 密封类。密封类在 Kotlin 中是新的,在 Java 中不存在。
密封类用于表示受限类层次结构。这意味着密封类的对象只能有一个定义的类型。让我们借助一个例子来理解它。
假设在考试中需要根据题型来声明类别。题型可以是易、中或难。现在我们要创建一个类问题,所有的问题类型都要继承这个类。我们还想确保除了这个用例,没有其他类应该继承这个 Question 类。
这是我们可以通过密封类实现的。一个类只能有一些指定的子类。当我们知道父类的所有子类型,并且不想根据我们所知道的创建子类 aprt 时,这很有用。
密封类和枚举类的区别
枚举也提供了类似的功能。在枚举中,我们可以在其中定义特定的类型。密封类和枚举之间的主要区别是:
-
每个枚举实例仅作为单个实例存在,而密封类的子类可以有多个实例。意思是子类(密封类)的每个对象都可以有一个状态。
-
在枚举中,每个实例都有相同的属性和函数集。但是在 Sealed 类中,不同的子类可以有不同的属性和函数集。
-
密封类的子类可以是不同的类型,如:数据类、对象类或普通类。
创建 Kotlin 密封类
使用sealed
关键字创建密封类。需要注意的是,密封类的所有子类都必须在同一个 Kotlin 文件中声明。如果我们试图在其他 Kotlin 文件中创建一个密封类的子类,我们会得到一个错误。封存类默认为abstract
。意思是我们不能实例化密封类。
让我们创建一个名为Question
的密封类,并为其创建三个子类Easy
、Moderate
和Difficult
:
// this is our Kotlin sealed class
sealed class Question{
// these are child classes
class Easy(var mark: Int, var time: Int): Question()
class Moderate(var mark: Int, var time: Int, var hint: String): Question()
class Difficult(var mark: Int, var time: Int, var hint: String, var solution: String): Question()
}
fun main() {
val easyQuestion = Question.Easy(1, 1)
println("The marks and time limit for an easy question is ${easyQuestion.mark} mark and ${easyQuestion.time} min")
}
一个简单问题的分数和时间限制是 1 分 1 分
正如您在上面的示例中看到的,我们可以将密封类用于这样的用例,在这些用例中,我们知道所有子类都需要什么,并且创建的类严格地服务于一个目的,就像在上面的代码示例中,我们有一个由 3 个子类继承的 Question 类,就是这样。
Kotlin 密封类:when
表达式
我们经常使用带有when
表达式的密封类。因为when
表达式保证了密封类的所有子类都被处理。如果我们忘记处理密封类的一个特定子类,它会给出一个错误。现在没有必要有一个else
街区。但是只有当你把when
作为一个表达而不是一个陈述时,它才会起作用。
让我们修改上面的例子来使用when
表达式:
sealed class Question{
class Easy(var mark: Int, var time: Int): Question()
class Moderate(var mark: Int, var time: Int, var hint: String): Question()
class Difficult(var mark: Int, var time: Int, var hint: String, var solution: String): Question()
}
fun questionDetail(question: Question): String {
return when(question){
is Question.Easy -> "Easy question Mark: ${question.mark} Time: ${question.time} min"
is Question.Moderate -> "Moderate question Marks: ${question.mark} Time: ${question.time} min and Hint: ${question.hint}"
is Question.Difficult -> "Difficult question Marks: ${question.mark} Time: ${question.time} min Hint: ${question.hint} and Solution: ${question.solution}"
}
}
fun main() {
val easyQuestion = Question.Easy(1, 1)
val difficultQuestion = Question.Difficult(5,6,"substitution method", "x = 5, y = 3")
println(questionDetail(easyQuestion))
println(questionDetail(difficultQuestion))
}
易问号:1 次:1 分钟
难问号:5 次:6 分钟提示:代入法和解法:x = 5,y = 3
使用带有密封类子类的when
表达式,我们可以基于密封类的子类轻松定义执行特定操作的条件。
摘要
在本教程中,我们了解了 Kotlin Sealed 类,它们为什么有用,如何定义密封类及其子类,以及代码示例和在 Kotlin 中使用带有密封类的when
表达式。在下一个教程中,我们将讨论 Kotlin 泛型。
Kotlin 泛型
在本教程中,我们将学习 Kotlin 泛型。泛型的概念允许我们使我们的类和函数数据类型独立。
让我们考虑一个场景,其中我们想要创建一个具有一些功能的类。该类的功能适用于特定的数据类型:String
。现在需要同样的函数来支持数据类型Int
。那你会怎么做?为此创建一个新的函数,或者创建一个新的类。嗯!使用泛型,您可以使用相同的类、相同的函数,并通过使函数通用来处理任何数据类型。
泛型允许我们定义类、函数和属性,可以使用不同的数据类型访问。泛型声明的数据类型是在编译时检查的。因此,如果有任何错误,那么它将只在编译时给出。
泛型类型类和函数使用尖括号 <>
定义为参数化类型。
Kotlin 参数化类
让我们创建一个参数化的类,它有一些函数:
class Rank<T>(var rank: T){
fun printRank(name: String) {
println("The rank of $name is $rank")
}
}
fun main(){
val rank = Rank<Int>(12)
rank.printRank("Ninja")
val rankNew = Rank<String>("First")
rankNew.printRank("New Ninja")
}
忍者等级为 12
新忍者等级为第一
在这个例子中,我们创建了一个参数化的类Rank
。它以同类型T
的参数rank
作为类类型。它包含一个打印等级的函数。在main()
函数中,我们创建了两个等级类的对象。第一个对象是Int
类型,第二个对象是String
类。
事实上,编译器也可以通过传递的构造器参数的数据类型,使用类型推断来解释类的数据类型。因此,这段代码也将像上面的代码一样工作:
fun main(){
val rank = Rank(12)
rank.printRank("Ninja")
val rankNew = Rank("First")
rankNew.printRank("New Ninja")
}
忍者等级为 12
新忍者等级为第一
Kotlin 参数化函数
同样,我们也可以创建通用函数:
fun <T>printMessage(message:T) {
println("Message is: $message")
}
fun main(){
printMessage("Hello World!!")
printMessage(123)
val map = mapOf("Maths" to 1, "Science" to 2, "English" to 3)
printMessage(map)
}
消息是:你好世界!!
消息为:123
消息为:{数学=1,科学=2,英语=3}
在本例中,我们创建了一个printMessage()
函数,该函数获取通用数据类型参数并打印它们。
摘要
在本教程中,我们学习了 Kotlin 中泛型的基础知识。在下一个教程中,我们将学习 Kotlin 中的扩展函数。
Kotlin 扩展函数
原文:https://www.studytonight.com/kotlin/kotlin-extension-function
在本教程中,我们将讨论 Kotlin 中的扩展函数。Kotlin 提供了向现有类添加新功能的功能。为此,没有必要继承它们。可以通过名为扩展的特殊声明来实现。
Kotlin 扩展函数
Kotlin Extensions 提供了向现有类添加新函数的功能。该功能称为扩展功能。我们可以向用户定义类以及库类添加扩展函数。
让我们创建一个类兴趣计算器,它包含一个函数simpleInterest()
来计算简单的兴趣:
class InterestCalculator(var principal: Double, var rate: Double, var time: Double){
fun simpleInterest(): Double{
return this.principal * this.rate * this.time * 0.01
}
}
假设,稍后我们想要添加计算复利的功能,但是类结构不能改变。在这个场景中,我们可以使用扩展函数。
在类名后使用.
运算符添加扩展函数。以下是为类添加扩展函数的语法:
fun ClassName.functionName(): returnType {
// body of function
}
让我们给兴趣计算器类添加一个扩展函数compoundInterest()
并调用它。扩展函数的调用方式与类函数的调用方式相似。
下面是代码:
fun InterestCalculator.compoundInterest(): Double {
val amount = this.principal * Math.pow(1 + (this.rate / 100), this.time)
return amount - this.principal
}
fun main() {
val educationLoanCalculator = InterestCalculator(100000.0, 11.0, 4.0)
println("Simple interest for this education loan is ${educationLoanCalculator.simpleInterest()}")
println("Compound interest for this education loan is ${educationLoanCalculator.compoundInterest()}")
}
本教育贷款单利为 44000.0
本教育贷款复利为 51807.04100000056
同样,我们也可以给任何库类添加扩展函数。
伴随对象的扩展功能
我们还可以向类中的伴随对象添加一个扩展函数。让我们编辑兴趣计算器类,并添加一个包含函数printSimpleInterestFormula()
的伴随对象:
class InterestCalculator(var principal: Double, var rate: Double, var time: Double){
fun simpleInterest(): Double{
return this.principal * this.rate * this.time * 0.01
}
companion object {
fun printSimpleInterestFormula(){
println("Simple interest formula is: principal * rate * time * 0.01")
}
}
}
现在向伴随对象添加一个函数printCompoundInterestFormula()
,并从main()
函数调用它:
fun InterestCalculator.Companion.printCompoundInterestFormula(){
println("Compound interest formula is: principal * ( 1 + rate / 100) ^ time")
}
fun main() {
InterestCalculator.printSimpleInterestFormula()
InterestCalculator.printCompoundInterestFormula()
}
单利公式为:本金利率时间* 0.01
复利公式为:本金* ( 1 +利率/ 100) ^时间
摘要
在本教程中,我们学习了 Kotlin 中的扩展函数,如果您想为不同库中的任何类添加更多的功能,这将非常有用。扩展函数主要用于库类。从下一个教程中,我们开始学习 Kotlin 中的异常处理。
Kotlin 异常处理
Kotlin 异常处理
原文:https://www.studytonight.com/kotlin/kotlin-exception-handling
在本教程中,我们将学习 Kotlin 中的异常处理。几乎所有的编程语言都提供了处理异常的机制。在开始异常处理之前,让我们先讨论什么是异常。
什么是例外?
异常是中断程序正常流程的事件(或错误)。异常在运行时发生,并突然终止程序。异常可能由于许多原因而发生,例如:
-
无效输入:
-
具有无效值的字符串
-
空输入
-
超出范围的输入数量
-
-
编程错误:
-
超出数组索引范围
-
无效操作,如被零除
-
-
系统错误:
- 被遗忘
什么是异常处理?
异常处理是处理运行时可能发生的异常的技术。如果我们想使我们的程序健壮,那么异常必须被处理。异常处理使我们的程序免于突然终止,并使我们能够向最终用户提供有意义的响应,解释异常发生的原因,而不是向他们显示异常消息(以及 strack trace)本身。
Kotlin 中的所有异常类都是类可投掷的后代。
在 Java 中,有两种类型的异常:
-
选中异常: 选中异常在编译时被选中。这些异常必须使用 try/catch 块来处理,或者通过在方法定义中提到
throws
关键字来进一步抛出异常。如果我们没有处理检查过的异常,程序就不会运行。 -
未检查的异常:编译时不检查这些异常。即使我们不处理这些异常,程序也会编译成功。
在 Kotlin,我们只有未检查的异常,即检查的异常在 Kotlin中不存在。消除检查异常背后的原因之一是,很大一部分开发人员认为检查异常会增加不必要的代码。
如果我们想让调用者知道函数可能抛出的异常,我们可以在 Kotlin 中添加@Throws
注释。
Kotlin 中的异常处理
Kotlin 中的异常处理可以用四个关键字来理解。它们是:
-
Try :可能发生异常的代码块被放在 Try 块中。try 块后面必须至少有一个 catch 块或一个 finally 块,或者两者都有。
-
接住:放在试块后。它捕获由 try 块中的代码引发的异常。这是实际处理异常的块。我们可以在一个试块之后有多个 catch 块。
-
最后:即使没有捕捉到异常或者根本没有发生异常,也始终执行 Finally block。Finally block 用于执行一些重要的操作,如关闭打开的文件。它被放置在 try 或 catch 块之后。最后只能有一个街区。
-
Throw : Throw 关键字用于显式抛出异常。如果开发人员想在某些情况下抛出异常,我们可以使用 throw 关键字。
在接下来的教程中,我们将详细介绍它们以及代码示例。
总结
在本教程中,我们了解了什么是异常,以及 Java 和 Kotlin 中异常类型的区别。在下一个教程中,我们将详细介绍如何使用try
、catch
、finally
和throw
关键字来处理科特灵中的异常。
Kotlin try-catch
在本教程中,我们将了解 Kotlin 中的try
和catch
块,以及我们如何使用它们来处理运行时可能导致异常/错误的代码。try
和catch
块用于处理异常。可能抛出异常的代码放在try
块内,由try
块抛出的异常使用catch
块捕获。
让我们看看在 Kotlin 中使用try
和catch
块的语法。
Kotlin try
& catch
块
try-catch
块的语法是:
try {
// The code which may throw an error
}catch (e: SomeException){
// Handling the exception
}
在上面的语法中, SomeException 是异常类的名称。您可以提供父类的名称来捕获单个 catch 块中的多个子类异常类,或者提供某个特定异常类的名称来处理单个异常。
Kotlin try
&catch
——例子
让我们首先看看一个会抛出异常的程序,如果我们不处理它会发生什么:
fun main() {
val a: Int = 101
val b: Int = 0
println("Division of $a and $b is: ${a/b}")
}
线程“main”Java . lang . arithmetic 异常:/在 Try_catchKt.main(try-catch.kt:4)
在 Try _ catch kt . main(Try-catch . kt)被零
取代
这里我们得到了ArithmeticException
,因为我们试图将一个数除以零。
让我们使用try
和catch
块来处理这个异常:
fun main() {
val a: Int = 101
val b: Int = 0
try {
println("Division of $a and $b is: ${a/b}")
}catch (exception: ArithmeticException){
println("Exception is handled....")
println("$a and $b cannot be divided!!")
}
}
异常被处理....
101 和 0 不能分!!
在上面的代码中,我们已经特别提到了在我们的catch
块中捕捉ArithmeticException
。如果我们的代码有更多的逻辑,并且一些其他的语句导致了一些非ArithmeticException
类型的异常,那么我们的程序将会再次突然停止执行异常消息。
所以我们必须找到合适的异常类来捕捉。
Kotlin try
& catch
的表达
Kotlin try-catch
区块的独特之处在于可以作为表达。这意味着它将返回值。try
和catch
块的最后语句被认为是返回值。
让我们编写一个程序,将两个数字相除,并将结果赋给res
变量。如有异常,我们将-1
分配给res
:
fun main() {
val a: Int = 100
val b: Int = 10
val res: Int = try {
a/b
}catch (exception: ArithmeticException){
-1
}
println("The result is: $res")
}
结果是:10
现在将b
的值改为0
,输出将是:
结果为:-1
摘要
在本教程中,我们学习了 Kotlin 中简单的try-
catch
块以及如何使用它们。在下一个教程中,我们将学习如何使用多个catch
块,根据异常类型不同地处理异常。
Kotlin 多重catch
块
原文:https://www.studytonight.com/kotlin/kotlin-multiple-catch-blocks
在本教程中,我们将学习如何以及为什么在 Kotlin 中使用多个catch
块和try
块来处理异常。一个try
区块可以有多个catch
区块。多个 catch 块用于捕获不同类型的异常。
多重catch
块的语法是:
try {
// Code which may throw multiple exceptions
}catch (exception: ExceptionType1){
// Handling exception
}catch (exception: ExceptionType2){
// Handling exception
}catch (exception: ExceptionType3){
// Handling exception
}
如上所述,我们为每个catch
块指定了不同的异常类型。多个catch
块用于不同地处理不同类型的异常,例如,在不同的异常情况下为用户打印不同的消息。
Kotlin 多重catch
块-示例
让我们首先看一个例子,在这个例子中,我们将捕捉多个异常。我们将从用户那里获得两个数字作为输入,并对它们进行划分:
fun main() {
try {
val a: Int = Integer.parseInt(readLine())
val b: Int = Integer.parseInt(readLine())
println("The Division of $a and $b is: ${a/b}")
}catch (exception: NumberFormatException){
println("Caught NumberFormatException: Numbers entered are invalid!!")
}catch (exception: ArithmeticException){
println("Caught ArithmeticException: Divided by zero!!")
}catch (exception: Exception){
println("Caught Exception!!")
}
}
这里我们抓到了NumberFormatException
、ArithmeticException
和Exception
将军。对于不同的输入,输出为:
-
a = 10, b = 5
10 和 5 的除法是:2
-
a = 10, b = 0
捕捉到算术异常:被零除!!
-
a = 10, b = "Hello"
捕获的数字格式异常:输入的数字无效!!
正如您在上面的代码示例中看到的,我们已经处理了 3 个异常,使用了 3 个不同的catch
块。我们已经习惯了特定的异常类,即NumberFormatException
和ArithmeticException
,它们将处理特定的用例。
然后我们有第三个带有Exception
类的 catch 块,它是许多异常类的父类。多个catch
区块中异常的顺序也很重要。
-
catch
区块的顺序必须是特定于将军。特定的异常必须先被捕获(就像我们NumberFormatException
和ArithmeticException
一样),然后广义的异常应该最后被捕获。
如果我们将Exception
类放在第一位,所有其他异常将仅被该 catch 块捕获。 -
另一个需要记住的要点是,只有一个
catch
区块会被执行。一次只能出现一个异常,并执行该特定异常的catch
块。
摘要
在本教程中,我们学习了如何在 Kotlin 中使用多个catch
块来处理多个不同的异常类型。在下一个教程中,我们将讨论 Kotlin 中嵌套的catch
块。
Kotlin 嵌套try-catch
原文:https://www.studytonight.com/kotlin/kotlin-nested-try-catch
在本教程中,我们将学习如何在 Kotlin 中使用嵌套的try
和catch
块进行异常处理。一个try-catch
积木可以放在一个try-catch
积木里面,这种排列方式被称为嵌套try-catch
积木。
嵌套try-catch
块的语法是:
try {
// Try inside try
try {
}catch (exception: InnerException){
// Handling inner exception
}
}catch (exception: OuterException){
// Handling outer exception
}
如果内部try
块出现异常,则首先用内部catch
块进行检查。如果没有在那里处理,那么将使用外部catch
块进行检查,以此类推。
Kotlin 嵌套try-catch
-示例:
让我们使用嵌套的try-catch
块编写一个程序:
fun main() {
var a: Int = 0
var b: Int = 0
val result: Int
try {
try {
a = Integer.parseInt(readLine())
b = Integer.parseInt(readLine())
println("Result of division is: ${a/b}")
}catch (exception: NumberFormatException){
println("Invalid inputs!!")
}
}catch (exception: ArithmeticException){
println("Division by zero is not allowed!!")
}
}
这里,在父try
块内部,添加了一个嵌套的try
块。如果数字的格式不正确,我们将尝试从用户那里获取输入并捕获异常。之后我们会进行除法运算,如果除法运算中出现异常,我们会用外catch
块捕捉异常,
不同输入的输出为:
-
a = 10, b = 5
除法结果为:2
-
a = 10, b = "Hello"
无效输入!!
-
a = 10, b = 0
不允许零除!!
同样,您可以拥有任意多的嵌套 try-catch 块。尽管拥有太多的 try-catch 块会使您的代码可读性降低。
摘要
在本教程中,我们学习了 Kotlin 中用于异常处理的嵌套 try-catch 块。我们将在下一个教程中讨论finally
块。
Kotlin finally
块
在本教程中,我们将了解 Kotlin 中的finally
块,以及它在 Kotlin 的异常处理中扮演什么角色。finally
块用于执行重要的清理操作,以防代码执行被异常中断。
finally
块可以放在catch
块之后,也可以直接放在try
块之后。与catch
街区不同的是,只能有一个finally
街区。
Kotlin finally
关键字
try-finally
块的语法是:
try {
// Code to be executed
}finally {
// Body of finally block
}
try-catch-finally
块的语法是:
try {
// Code to be executed
}catch (exception: SomeException) {
// Body of Exception
}
finally {
// Body of finally block
}
在以下情况下将执行finally
块:
-
完全不会出现异常。
-
异常发生并得到处理。
-
异常发生并且没有被处理。
让我们看看他们每个人的例子。
Kotlin finally
:完全没有异常发生
在这种情况下,异常不会发生,但将执行finally
块:
fun main() {
try {
val a: Int = 10
val b: Int = 5
println("Division of $a and $b results in: ${a/b}")
}catch (exception: ArithmeticException) {
println("Division by zero!!")
}
finally {
println("Finally block is always executed.")
}
}
10 和 5 的除法结果为:2
最终总是执行块。
Kotlin finally
:异常发生并处理
在这种情况下,异常发生并由catch
块处理。最后,执行finally
块:
fun main() {
try {
val a: Int = 10
val b: Int = 0
println("Division of $a and $b results in: ${a/b}")
}catch (exception: ArithmeticException) {
println("Division by zero!!")
}
finally {
println("Finally block is always executed.")
}
}
除以零!!
最终始终执行块。
Kotlin finally
:???????异常发生并且没有被处理
出现异常,但没有处理。程序将停止工作,但将执行finally
块:
fun main() {
try {
val a: Int = 10
val b: Int = 0
println("Division of $a and $b results in: ${a/b}")
} finally {
println("Finally block is always executed.")
}
}
最后始终执行块。
线程“main”中的异常 Java . lang . arithmetic 异常:/在 finallykt . main(finallykt . main:5)被零
取代
在 FinallyKt.main(finally.kt)
什么时候用 Kotlin finally
?
如果你想知道我在哪里可以使用这个finally
块,那么这里有几个强有力的竞争者:
-
在发生异常之前关闭代码执行期间打开的文件。
-
关闭数据库连接(如果已创建)。
-
通过发送电子邮件向开发团队报告执行情况,或者可能将异常存储在数据库中以供以后分析。
-
如果你有一个支付系统,在执行过程中出现异常,那么
finally
块可以用来做代币的清理,状态维护等。
说到使用finally
区块,这只是冰山一角。
摘要
在本教程中,我们学习了如何以及为什么在异常处理期间使用 Kotlin 中的finally
块。在下一个教程中,我们将看到如何使用throw
关键字故意抛出异常。
Kotlin throw
关键字
在本教程中,我们将了解 Kotlin 中的throw
关键字,以及如何使用它抛出异常。
Kotlin throw
关键字明确用于抛出异常。我们也可以创建自己的自定义异常,并使用 Kotlin throw
关键字抛出它。
Kotlin throw
关键字
throw
关键字的语法是:
throw SomeException("Custom Exception Message")
正如您在上面的例子中所看到的,我们可以抛出一个异常以及一些传播到catch
块的异常消息,在那里我们可以使用它向最终用户显示消息。
Kotlin throw
示例
当用户输入的密码长度小于 3:
fun main() {
val userName: String = "Ninja"
val password: String = "ps"
if(password.length <= 3){
throw Exception("The minimum length of password should be 3!!")
}
}
线程“main”Java . lang . Exception 中出现异常:密码最小长度应为 3!!
在最后的主星(最后的主星:5)
在最后的主星(最后的主星)
就像上面的例子一样,我们可以使用throw
关键字来中断代码的执行流程,然后处理使用catch
块生成的异常事件。
摘要
在本教程中,我们看到了如何显式抛出异常。我们还可以通过使用继承扩展异常类来创建自定义异常。
Kotlin 集合
Kotlin 集合
在本节中,我们将向您简要介绍 Kotlin 的集合。集合的概念对 Kotlin 来说并不陌生。它已经存在于许多其他编程语言中。Kotlin 标准库提供了一套创建和管理集合的工具。
什么是集合?
集合是一组相同类型的对象。集合中的对象被称为元素或项目。
假设我们想存储一个班级学生的分数,并对其进行运算,如求最大值、最小值、平均值等。我们可以使用集合。
数组可以是一个很好的选择,但数组的大小是固定的。从数组中添加或删除某些元素是不可能的。此外,集合提供了许多其他功能,我们将在本节中讨论。
集合类型
Kotlin 有三种类型的集合:
-
目录
-
一组
-
映射
Kotlin 标准库提供了创建列表、集合和映射对象的方法。根据要求,每一个都可以是:
-
不可变集合(只读)
-
可变集合(读和写)
我们将在单独的教程中讨论列表、集合和映射。让我们首先讨论可变和不可变集合类型。
不可变集合
不可变集合继承自Collection<T>
接口,该接口不提供添加或移除元素的功能。在不可变集合中,一个元素不能在声明后被添加、移除或更改。在定义了不可变集合之后,我们只能读取它的元素。
不可变集合也简称为集合。
可变集合
顾名思义,可变集合允许写和读操作。在可变集合中,我们可以添加、移除和改变元素的值。
可变集合继承自MutableCollection<T>
接口,该接口提供读取和更改元素的功能。它们还继承了相应集合接口的基本功能。
摘要
在本教程中,我们讨论了集合的基础知识和类型。从下一个教程开始,我们将详细讨论列表、映射和设置。
Kotlin 列表
在本教程中,我们将讨论 Kotlin 列表。列表包括:
-
元素的有序集合。
-
排序是通过索引(与数组相同)来维护的。
-
一个元素在列表中可以出现多次。
-
可变列表可以被认为是一个动态数组,其大小可以改变。
在 Kotlin,我们可以有一个可变列表和一个不可变列表。
Kotlin 不可变列表
使用List
接口创建不可变列表。List
接口继承了Collection
接口。它包含许多有用的功能,如contains()
、indexOf()
、isEmpty()
等。我们将借助一个例子来看它们。
在 Kotlin 中,我们可以使用listOf()
和listOf<T>()
函数创建不可变列表。listOf()
函数用于创建一个通用列表,该列表可以包含任何对象,如整数、字符串、浮点数等。listOf<T>()
用于创建特定类型的列表。
让我们使用这两个函数创建列表:
fun main() {
var genericList = listOf("Ninja", 10, 1.05f, 'a')
var specificList = listOf<String>("Ninja", "Study", "tonight")
println("Printing $genericList")
println("Printing $specificList")
}
印刷【忍者,10,1.05,a】
印刷【忍者,今晚学习】
这里我们已经创建了两个列表,一个是泛型,一个是字符串。
Kotlin 遍历列表:
fun main() {
val list = listOf<String>("Ninja", "Study", "tonight", "Ninja", "Kotlin")
// printing list
for (element in list)
println(element)
}
忍者
今晚学习
忍者
Kotlin
Kotlin 列表函数和属性
List
接口提供的一些重要功能和属性有:
属性:
-
size
:表示列表中存在的元素数量。 -
lastIndex
:表示列表中最后一个元素的索引。
功能:
-
get(index)
:返回列表中指定索引处的元素或抛出IndexOutOfBoundsException
。 -
contains(element)
:如果列表中存在元素,则返回 true,否则返回 false。 -
indexOf(element)
:返回列表中指定元素第一次出现的索引,如果列表中不包含指定元素,则返回-1。 -
lastIndexOf(element)
:返回列表中指定元素最后一次出现的索引,如果列表中不包含指定元素,则返回-1。 -
first()
:返回列表中的第一个元素,如果列表为空则抛出NoSuchElementException
。 -
last()
:返回列表中的最后一个元素,如果列表为空则抛出NoSuchElementException
。 -
isEmpty()
:如果列表为空则返回真,否则返回假。 -
subList(start, end)
:返回开始(包含)和结束(不包含)之间的子列表。
同样的例子是:
fun main() {
val list = listOf<String>("Ninja", "Study", "tonight", "Ninja", "Kotlin")
// Properties
println("The size of list is: ${list.size}")
println("The index of last element is: ${list.lastIndex}")
// Functions
println("Element at index 2 is: ${list.get(2)}")
println("Element at index 3 is: ${list[3]}") // Other way to get an element
println("Does Ninja exist in list: ${list.contains("Ninja")}")
println("Does Hatori exist in list: ${list.contains("Hatori")}")
println("The first index of Ninja is: ${list.indexOf("Ninja")}")
println("The first index of Hatori is: ${list.indexOf("Hatori")}")
println("The last index of Ninja is: ${list.lastIndexOf("Ninja")}")
println("The last index of Hatori is: ${list.lastIndexOf("Hatori")}")
println("First element in list: ${list.first()}")
println("Last element in list: ${list.last()}")
println("Is list empty: ${list.isEmpty()}")
println("Sublist from index 1 to 3 ${list.subList(1,3)}")
}
列表大小为:5
最后一个元素的索引为:4
索引处的元素为:今夜
索引处的元素为:忍者
列表中是否存在忍者:真
列表中是否存在哈托利:假
忍者第一个索引为:0
哈托利第一个索引为:-1
忍者最后一个索引为:3
哈托利最后一个索引为:-1
列表中第一个元素:忍者
列表中最后一个元素:Kotlin
列表是否为空:假
从索引 1 到 3 的子列表【今晚学习】
Kotlin 可变列表
使用MutableList
接口创建可变列表。MutableList
接口也继承了Collection
接口。可变列表本质上是动态的。在可变列表声明之后,我们可以在可变列表中添加或删除元素。因此可变列表的大小不是固定的。
与不可变列表类似,可变列表是使用mutableListOf()
和mutableListOf<T>()
函数创建的。mutableListOf()
函数用于创建一个通用列表,该列表可以包含任何对象,如整数、字符串、浮点数等。mutableListOf<T>()
用于创建特定类型的列表。
让我们使用这些方法创建可变列表:
fun main() {
var genericList = mutableListOf("Ninja", 10, 1.05f, 'a')
var specificList = mutableListOf<String>("Ninja", "Study", "tonight")
println("Printing $genericList")
println("Printing $specificList")
}
印刷【忍者,10,1.05,a】
印刷【忍者,今晚学习】
存在于不可变列表中的所有属性和方法也存在于可变列表中。可变列表有一些额外的功能来支持可变性:
-
add(element)
:将指定的元素添加到列表的末尾。 -
add(index, element)
:在列表中指定的索引处插入一个元素。 -
remove(element)
:从列表中删除第一个出现的元素。 -
removeAt(index)
:从列表中删除指定索引处的元素。 -
set(index, element)
:用指定的元素替换列表中指定索引处的元素。 -
clear()
:移除列表中的所有元素。
使用这些方法的示例:
fun main() {
val list = mutableListOf<String>("Ninja", "Study", "tonight", "Ninja", "Kotlin")
// New Functions
list.add("Java")
println(list)
list.add(2, "C++")
println(list)
list.remove("Ninja")
println(list)
list.removeAt(1)
println(list)
list.set(1, "PHP")
println(list)
list.clear()
println(list)
}
【忍者,学习,今晚,忍者,Kotlin,Java】
【忍者,学习,C++,今晚,忍者,Kotlin,Java】
【学习,C++,今晚,忍者,Kotlin,Java】
【学习,今晚,忍者,Kotlin,Java】
【学习,PHP,忍者,Kotlin,Java】
【】
摘要
在本教程中,我们学习了不可变和可变列表,它们的创建使用了listOf()
和mutableListOf()
函数以及提供的一些重要函数。在下一个教程中,我们将讨论 Kotlin 的映射。
Kotlin 映射
在本教程中,我们将讨论 Kotlin 映射。映射用于存储键和值对。键和值都是用户定义的。在映射中:
-
密钥应该是唯一的,并且每个唯一的密钥只能存储一个值。
-
值可以重复。
-
键和值可以是不同的数据类型。
-
to
关键字用于将一个键映射到一个值。 -
键值对也称为条目。
在 Kotlin,我们既可以有一张可变映射,也可以有一张不可变映射。
Kotlin 不可变映射
使用Map<K, V>
接口创建不可变映射。我们只能从不可变的映射中阅读。
在 Kotlin 中,不可变映射是使用mapOf()
和mapOf<K, V>()
函数创建的。与列表类似,mapOf()
函数用于创建一个通用映射,其中键和值可以是任何数据类型。mapOf<K, V>()
用于创建一个特定的映射,分别具有 K 和 V 数据类型的键和值。
让我们使用这两个函数创建不可变的映射:
fun main() {
val generalMap = mapOf("Rank" to 1, 1 to "First", 'A' to "Excellent")
val specificMap = mapOf<String, Int>("Physics" to 80, "Maths" to 97, "C++" to 89)
println(generalMap)
println(specificMap)
}
{Rank=1,1 =第一,A =优秀}
让我们使用for
和forEach
循环迭代这些映射:
fun main() {
val generalMap = mapOf("Rank" to 1, 1 to "First", 'A' to "Excellent")
val specificMap = mapOf<String, Int>("Physics" to 80, "Maths" to 97, "C++" to 89)
for ((k,v) in generalMap) {
println("Key is: $k and Value is $v")
}
specificMap.forEach { (k, v) ->
println("Key is: $k and Value is $v")
}
}
键为:秩和值为 1
键为:1 和值为第一
键为:A 和值为优秀
键为:物理和值为 80
键为:数学和值为 97
键为:C++和值为 89
Kotlin 映射的性质和函数
Map
接口提供的一些重要功能和属性有:
属性:
-
size
:返回映射的大小。 -
entries
:返回映射中所有键值对的集合。 -
keys
:返回映射中所有按键的集合。 -
values
:返回映射中所有值的集合。
功能:
-
get(key)
:返回对应键的值。如果键不存在,则返回 null。 -
getValue(key)
:返回给定键的值,如果映射中没有这样的键,则抛出NoSuchElementException
异常。 -
contains(key)
:如果映射包含指定的键,则返回真,否则返回假。 -
containsKey(key)
:如果映射包含指定的键,则返回真,否则返回假。这个函数与前面的函数相同。 -
containsValue(value)
:如果映射中存在一个或多个指定值的关键点,则返回真。 -
getOrDefault(key, defaultValue)
:返回该键对应的值,如果映射中没有该键,则返回defaultValue
。
使用这些方法和属性的示例如下:
package collections
fun main() {
val marks = mapOf<String, Int>("Physics" to 80, "Maths" to 97, "C++" to 89, "Chemistry" to 95)
// Properties
println("Size of map: ${marks.size}")
println("Set of entries: ${marks.entries}")
println("Set of keys: ${marks.keys}")
println("Set of values: ${marks.values}")
// Methods
println("Marks in Physics: ${marks.get("Physics")}")
println("Marks in English: ${marks["English"]}")
println("Marks in Maths: ${marks.getValue("Maths")}")
println("Does map contains Physics: ${marks.containsKey("Physics")}")
println("Does map contains C++: ${marks.contains("C++")}")
println("Does map contains Chemistry: ${"Chemistry" in marks}")
println("Does any subject has 100 marks: ${marks.containsValue(100)}")
println("Marks in English: ${marks.getOrDefault("English",0)}")
}
映射大小:4
条目集:【物理=80,数学=97,C++=89,化学= 95】
键集:【物理,数学,C++,化学】
值集:【80,97,89,95】
物理分:80
英语分:空
数学分:97
映射是否包含物理:真
映射是否包含 C++:真
映射是否包含
Kotlin 可变映射
可变映射使用MutableMap
接口创建。可变映射支持动态特性。在可变映射声明之后,我们可以在其中添加、删除或更新条目。因此可变映射的大小不是固定的。
可变映射使用mutableMapOf()
和mutableMapOf<K, V>()
功能创建。mutableMapOf()
功能用于创建一个通用映射,mutableMapOf<K, V>()
用于创建一个特定键和值数据类型的映射。
让我们使用以下方法创建可变映射:
fun main() {
val generalMap = mutableMapOf("Rank" to 1, 1 to "First", 'A' to "Excellent")
val specificMap = mutableMapOf<String, Int>("Physics" to 80, "Maths" to 97, "C++" to 89)
println(generalMap)
println(specificMap)
}
{Rank=1,1 =第一,A =优秀}
我们可以像迭代不可变映射一样迭代可变映射。
不可变映射中存在的所有属性和方法在可变映射的情况下也存在。可变映射有一些额外的功能来支持动态特性。它们是:
-
put(key, value)
:将指定的键值对添加到映射中。如果键已经存在,它将替换该值。 -
putIfAbsent(key, value)
:仅当键之前不存在时,将指定的键值对添加到映射中。 -
replace(key, newValue)
:用新值替换指定键的值。 -
replace(key, oldValue, newValue)
:仅当键和旧值对存在时,用新值替换指定键的旧值。 -
remove(key)
:从映射中移除带有指定键的条目。 -
remove(key, value)
:如果存在具有指定键和值的条目,则从映射中移除条目。 -
clear()
:从映射中移除所有条目。
使用这些方法的示例:
fun main() {
val marks = mutableMapOf<String, Int>("Physics" to 80, "Maths" to 97, "C++" to 89, "Chemistry" to 95)
marks.put("C++", 92)
println(marks)
marks["Chemistry"] = 93
println(marks)
marks.putIfAbsent("English", 95)
marks.putIfAbsent("Physics", 0)
println(marks)
marks.replace("Maths", 70)
println(marks)
marks.replace("Maths", 70, 95)
println(marks)
marks.remove("C++")
println(marks)
marks.remove("Maths", 95)
println(marks)
marks.clear()
println(marks)
}
{物理=80,数学=97,C++=92,化学=95}
{物理=80,数学=97,C++=92,化学=93 }
{物理=80,数学=97,C++=92,化学=93,英语= 95 }
{物理=80,数学=70,C++=92,化学= 93,英语= 95 }
摘要
在本教程中,我们讨论了不可变和可变映射,它们的创建使用了mapOf()
和mutableMapOf()
函数以及提供的一些重要函数。在下一个教程中,我们将讨论 Kotlin 中的集合。
Kotlin 集合
在本教程中,我们将讨论 Kotlin 集。集合有:
-
元素的无序集合。
-
集合中不允许有重复的元素。
在 Kotlin,我们既可以有一个可变集,也可以有一个不可变集。
Kotlin 不变集
使用Set
接口创建不可变集。Set
接口继承了Collection
接口。
在 Kotlin 中,我们可以使用setOf()
和setOf<T>()
函数创建不可变集。setOf()
函数用于创建一个通用集合,该集合可以包含任何对象,如整数、字符串、浮点数等。setOf<T>()
用于创建一组特定类型。
让我们使用这两个函数创建集合:
fun main() {
val genericSet = setOf("Hello", 1, "Bye", 'A', "Hello")
val specificSet = setOf<String>("C++", "Maths", "English")
println(genericSet)
println(specificSet)
}
【你好,1,拜拜,A】
【c++,数学,英语】
这里我们已经创建了两个集合,一个是泛型类型,一个是字符串。
迭代一个集合:
fun main() {
val genericSet = setOf("Hello", 1, "Bye", 'A', "Hello")
for (item in genericSet)
println(item)
}
你好
1
再见
A
Kotlin 集的性质和函数
Set
接口提供的一些重要功能和属性有:
属性:
size
:表示集合中存在的元素数量。
功能:
-
elementAt(index)
:返回集合中指定索引处的元素或抛出IndexOutOfBoundsException
。 -
contains(element)
:如果元素存在于集合中,则返回true
或者返回false
。 -
indexOf(element)
:返回集合中指定元素的索引,如果集合中不存在指定元素,则返回-1
。 -
lastIndexOf(element)
:返回集合中指定元素最后一次出现(或唯一一次出现)的索引,如果集合中不存在指定元素,则返回-1
。 -
first()
:返回集合中的第一个元素,如果集合为空,则抛出NoSuchElementException
。 -
last()
:返回集合中的最后一个元素,如果集合为空,则抛出NoSuchElementException
。 -
isEmpty()
:如果设置为空则返回true``false
。 -
count()
:返回该集合中的元素个数。 -
max()
:返回最大的元素,如果没有元素则返回null
。 -
min()
:返回最小的元素,如果没有元素则返回null
。 -
sum()
:返回集合中所有元素的总和。 -
average()
:返回该集合中所有元素的平均值。
同样的例子是:
fun main() {
val languages = setOf<String>("Kotlin", "C++", "C", "Java", "Angular", "Kotlin")
val marks = setOf<Int>(95,96,94,90)
// Properties
println("The size of set is: ${languages.size}")
// Functions
println("Does Java exist in set: ${languages.contains("Java")}")
println("Does PHP exist in set: ${languages.contains("PHP")}")
println("Element at index 1: ${languages.elementAt(1)}")
println("The index of Kotlin is: ${languages.indexOf("Kotlin")}")
println("The index of PHP is: ${languages.indexOf("PHP")}")
println("The last index of Kotlin is: ${languages.lastIndexOf("Kotlin")}")
println("First element in set: ${languages.first()}")
println("Last element in set: ${languages.last()}")
println("Is set empty: ${languages.isEmpty()}")
// Mathematical functions
println("No. of elements in set: ${marks.count()}")
println("Max element in set: ${marks.max()}")
println("Min element in set: ${marks.min()}")
println("Sum of elements in set: ${marks.sum()}")
println("Average of elements in set: ${marks.average()}")
}
集合的大小为:5
集合中是否存在 Java:true
集合中是否存在 PHP:false
索引处的元素:c++
Kotlin 的索引为:0
PHP 的索引为:-1
Kotlin 的最后一个索引为:0
集合中的第一个元素:Kotlin
集合中的最后一个元素:Angular
被设置为空:false
集合中的元素个数:4
集合中的 Max 元素:
Kotlin 可变集
使用MutableSet
接口创建可变集。MutableSet
接口也继承了Collection
接口。可变集合本质上是动态的。我们可以在可变集合声明之后,在可变集合中添加或移除元素。因此可变集合的大小不是固定的。
与不可变集类似,可变集是使用mutableSetOf()
和mutableSetOf<T>()
函数创建的。mutableSetOf()
功能用于创建通用集合,而mutableSetOf<T>()
用于创建特定类型的集合。
让我们使用这些方法创建可变集:
fun main() {
val generalSet = mutableSetOf("Kotlin", 10, 1.0f, 'A', "Kotlin")
val specificSet = mutableSetOf<String>("Kotlin", "C++", "C", "Java", "Angular", "Kotlin")
println(generalSet)
println(specificSet)
}
【kot Lin,10,1.0,a】【kot Lin,C++,c,Java,角度】
不可变集合中存在的所有属性和方法在可变集合的情况下也存在。可变集合有一些额外的功能来支持可变性:
-
add(element)
:将指定的元素添加到集合中。如果元素已经添加,返回true
,如果元素已经包含在集合中,返回false
。 -
remove(element)
:从集合中移除元素。 -
clear()
:移除集合中的所有元素。
使用这些方法的示例:
fun main() {
val languages = mutableSetOf<String>("Kotlin", "C++", "C", "Java", "Kotlin")
println(languages)
languages.add("Angular")
println(languages)
languages.remove("Java")
println(languages)
languages.clear()
println(languages)
}
【kot Lin,C++,c,Java】【kot Lin,C++,c,Java,角度】
【kot Lin,C++,c,角度】
摘要
在本教程中,我们讨论了不可变集和可变集,它们的创建使用了setOf()
和mutableSetOf()
函数以及提供的一些重要函数。我们已经完成了这个 Kotlin 教程系列的所有主要主题。我们将讨论其他部分留下的一些重要话题。
Kotlin 杂项
Kotlin 文件处理
在本教程中,我们将讨论 Kotlin 中文件处理的基础知识。文件用于将数据保存在内存中,因为程序执行后,如果不存储数据,数据就会丢失。
有许多方法可以创建文件,读取和写入文件。我们将简要讨论其中的一些。
创建文件
通常在许多写方法中,文件是自己创建的,但是我们会看到一种创建文件的方法。我们将使用java.io
包中提供的File
类。构造器以文件名作为参数。我们将使用createNewFile()
方法创建一个文件。
如果给定文件名的文件不存在,createNewFile()
方法将创建一个新文件,并返回 true 。如果文件名为的文件已经存在,它将返回 false:
import java.io.File
fun main() {
val fileName = "Demo.txt"
// Create file object
val file = File(fileName)
// Create file
var isCreated = file.createNewFile()
if (isCreated)
println("File is created")
else
println("File is not created")
// Again create file
isCreated = file.createNewFile()
if (isCreated)
println("File is created")
else
println("File is not created")
}
文件已创建
文件未创建
我们也可以使用file.exists()
方法检查文件的存在
Kotlin 写文件
我们可以使用writeText()
方法将数据写入文件。
-
它会将字符串作为参数,并将其写入文件。
-
如果不存在具有指定名称的文件,它将创建一个新文件。
-
如果文件已经存在,它将替换文件。
-
默认情况下,首先使用 UTF-8 字符集对给定数据进行编码。我们还可以指定任何其他字符集。
import java.io.File
fun main() {
val fileName = "Demo.txt"
val file = File(fileName)
file.writeText("Hello World")
file.writeText("Bye world")
}
如果我们查看 Demo.txt 文件,我们将只能在其中看到再见世界。因为writeText()
会替换文件中存在的所有内容。如果想防止现在的数据丢失,可以用appendText()
功能代替writeText()
功能。
Kotlin 从文件中读取
对于逐行阅读内容,我们可以使用forEachLine()
方法。它将从文件中逐行读取数据。
import java.io.File
fun main() {
val fileName = "Demo.txt"
val file = File(fileName)
file.forEachLine {
println(it)
}
}
我们也可以使用readText()
功能从文件中读取数据:
import java.io.File
fun main() {
val fileName = "Demo.txt"
val file = File(fileName)
val data = file.readText()
println(data)
}
摘要
在本教程中,我们讨论了创建文件、从中读取数据以及向其中写入数据的基本方法。
Kotlin 空安全
在本教程中,我们将讨论 Kotlin 最重要的特性之一:空安全。在编程世界中,当一个变量不引用任何东西时,它被认为是null
。如果我们尝试使用这个变量,那么我们将得到NullPointerException
或 NPE。
让我们看一个 Java 中发生NullPointerException
的小例子:
public class Student {
public static void main(String[] args) {
Integer rollNo = null;
Integer nextRollNo = rollNo + 1;
System.out.println("Roll No. of next student: " + nextRollNo);
}
}
线程“main”Java . lang . nullpointerexception 中的异常
在 Student.main(Student.java:4)
NullPointerException
被认为是一个十亿美元的错误,因为它导致程序突然终止。由于疏忽,NullPointerException
可以出现在代码中的任何地方。
Kotlin 通过提供一种机制来处理NullPointerException
来解决这个问题。Kotlin 的目标是从我们的整个代码中删除 NPE。让我们讨论一下它的功能。
可空和非空引用
在 Kotlin 中,类型系统区分两种类型的引用:
-
可空引用:这些引用可以保存空值。
-
非空引用:这些引用不能包含空值。
编译器在编译时解释这些引用。编译器默认将所有变量视为非空引用。
让我们用例子来理解它们:
fun main() {
var name:String = null // ERROR
}
错误:(2,23) Kotlin: Null 不能是非 Null 类型字符串的值
这里,默认情况下,编译器将name
变量视为非空引用。所以,我们不能给它赋值 null。当我们以后使用这个name
变量时,它消除了获得空指针异常的机会。
为了允许变量保存空值,我们在数据类型后使用?
:
fun main() {
var name:String? = null // NO ERROR
}
这里,我们故意允许 name 变量保存空值。但是现在在我们尝试使用的时候可能会抛出空指针异常。Kotlin 也将处理可空引用。如果我们试着用它作为:
fun main() {
var name:String? = "Ninja"
println(name.length) // ERROR
}
错误:(3,17)Kotlin:只安全(?。)或非空断言(!!。)字符串类型的可空接收器上允许调用?
这里编译器不允许我们直接找到字符串的长度,因为它可能会抛出空指针异常。
现在要调用可空引用的属性和函数,我们可以执行以下操作之一:
-
在条件中检查 null
-
安全通话
-
猫王接线员
-
那个!!操作员
让我们详细讨论这些方法,看看它们如何允许我们使用可空引用,以及如何处理 NPE。
在条件中勾选空
如果我们想调用一个函数或在可空引用上使用一个属性(比如在name
变量上使用name.length
,我们可以先检查空条件,然后使用它:
fun main() {
var name:String? = "Ninja"
if (name != null)
println(name.length)
}
5
现在编译器不会给出任何错误,因为我们已经先检查了空条件。这是处理可空引用的最基本的方法。但与此同时,在程序中处处使用也是繁琐的。
安全通话
如果我们想要:
-
如果
name
不为空,返回name
的长度。 -
或者如果
name
为空,则返回空
我们可以使用安全呼叫操作符(?.
)来实现这一点。让我们在同一个例子中使用它:
fun main() {
var name:String? = "Ninja"
println("Length of name is ${name?.length}")
name = null
println("Length of name is ${name?.length}")
}
名称长度为 5
名称长度为空
安全呼叫操作员类似于:
if(name != null)
// return length
else
// return null
猫王接线员
如果使用的变量为 null,则安全调用运算符返回 null。假设我们想要:
-
如果
name
不为空,返回name
的长度。 -
或者如果
name
为空,则给一个特定的值。
我们可以使用 Elvis 运算符(?:
)来实现这一点:
fun main() {
var name:String? = "Ninja"
println("Length of name is ${name?.length ?: -1}")
name = null
println("Length of name is ${name?.length ?: -1}")
}
名称长度为 5
名称长度为-1
这里我们结合了安全呼叫操作符和猫王操作符。
!!
操作员
!!
运算符允许我们将可空引用更改为非空引用。现在,如果我们尝试使用它,它将抛出空指针异常。Kotlin 编译器不会再处理它了。
所以,如果我们试图在这种情况下使用它:
fun main() {
var name:String? = "Ninja"
println("Length of name is ${name!!.length}") // prints 5
}
会没事的。但是如果我们试图在这种情况下使用它:
fun main() {
var name:String? = null
println("Length of name is ${name!!.length}") // Throws NullPointerException
}
所以!!
操作者要尽量避免。
摘要
在本教程中,我们讨论了 Kotlin 中的 Null 安全性。空安全是 Kotlin 的一个重要特性,它将我们从空指针异常中拯救出来。在下一个教程中,我们将讨论 Kotlin 中的正则表达式。
Kotlin 正则表达式
原文:https://www.studytonight.com/kotlin/kotlin-regular-expression
在本教程中,我们将讨论 Kotlin 中的正则表达式。正则表达式是用来定义模式的字符序列。这种模式也被称为正则表达式。
正则表达式可以用于很多事情,比如字符串中的模式匹配,字符串中的查找和替换等等。在 Kotlin 中,Regex
类用于创建和管理正则表达式。
创建正则表达式
为了定义一个正则表达式,我们将创建一个Regex
类的对象。创建仅包含字母数字字符(至少有一个长度)的用户名的模式是:
val usernamePattern = "[a-zA-Z0-9]+"
可以通过多种方式创建具有模式的正则表达式对象:
1.Regex 构造器
正则表达式模式作为参数传递给构造器:
val usernamePattern = "[a-zA-Z0-9]+"
val regex = Regex(usernamePattern)
2.使用 toRegex()函数
调用toRegex()
函数创建正则表达式对象:
val usernamePattern = "[a-zA-Z0-9]+"
val regex = usernamePattern.toRegex()
3.使用 fromLiteral()函数
我们也可以使用fromLiteral()
函数创建一个正则表达式。该函数返回一个正则表达式,该表达式与指定的模式字符串匹配。这意味着该字符串中没有字符会有特殊含义。因此/w
将仅被视为/w
字符串,而不是元字符:
val usernamePattern = "[a-zA-Z0-9]+"
val regex = Regex.fromLiteral(usernamePattern)
使用这三种方法中的任何一种,我们都可以创建一个 regex 对象。现在让我们看看如何对它进行操作。
匹配部分字符串
让我们看看如何使用正则表达式匹配部分字符串。如果输入的子串匹配正则表达式,那么我们将得到真:
fun main() {
val usernamePattern = "[a-zA-Z0-9]+"
val regex = Regex(usernamePattern)
println(regex.containsMatchIn("Ninja__Nin"))
println(regex.containsMatchIn("!#$%"))
}
真
假
在第一种情况下,仅匹配第一个字符“N”后,我们将得到真。但是在第二种情况下,甚至没有一个子串与模式匹配。因此,我们得到错误。
匹配完整字符串
要用正则表达式匹配全字符串,我们可以使用matches()
函数或matches
中缀运算符。只有当完整的字符串满足以下模式时,它们才会返回 true:
fun main() {
val usernamePattern = "[a-zA-Z0-9]+"
val regex = Regex(usernamePattern)
println(regex.matches("Ninja"))
println(regex matches "Ninja")
println(regex.matches("Ninja__Nin"))
}
真
真
假
这里,第一个和第二个字符串遵循模式,因此返回 true。在第二种情况下,字符串包含_
,因此我们得到假。
提取部分匹配字符串
如果我们想匹配然后提取部分匹配字符串,可以使用find()
和findAll()
函数。find()
函数返回包含第一个匹配子串的MatchResult
的对象,如果不存在,则返回 null。findAll()
函数返回包含所有匹配子串的MatchResult
集合:
fun main() {
val usernamePattern = "[a-zA-Z0-9]+"
val regex = Regex(usernamePattern)
println(regex.find("Nin_ja")?.value)
regex.findAll("Ninja__Nin-123").forEach {
println(it.value)
}
}
Nin
忍者
Nin
123
提取完整的匹配字符串
如果我们想要匹配然后提取完整的匹配字符串,我们可以使用 matchEntire()函数。它将返回包含字符串的MatchResult
类的对象。
fun main() {
val usernamePattern = "[a-zA-Z0-9]+"
val regex = Regex(usernamePattern)
println(regex.matchEntire("Ninja")?.value)
}
忍者
摘要
在本教程中,我们讨论了 Kotlin Regex。我们看到了如何创建 regex 对象并使用它们来匹配模式。在下一个教程中,我们将讨论 Kotlin 运算符重载。
Kotlin 运算符重载
原文:https://www.studytonight.com/kotlin/kotlin-operator-overloading
在本教程中,我们将学习 Kotlin 的运算符重载。我们使用的每个操作符,如+
、-
、++
等,都转化为一个功能。例如,以下算术函数转换为:
操作员 | 表示 | 基础函数 |
---|---|---|
+ | a + b | a .加(b) |
- | 美国罗克韦尔 | a 减 b |
* | a * b | a .时代(b) |
/ | a / b | 英格兰足球俱乐部 |
此外,对于不同的数据类型,所有这些函数也可能被重载。例如,plus()
函数为Int
类型添加两个数字,为String
类型连接两个字符串。
Kotlin 运算符重载
运算符重载可以通过重载该运算符的基础函数来实现。意思是过载+
操作符,我们要过载plus()
功能。
让我们创建一个类ComplexNumber
并为其重载+
运算符。我们将使用operator
关键字来重载它:
class ComplexNumber(var real: Int, var imaginary: Int){
// Operator Overloading
operator fun plus(c: ComplexNumber): ComplexNumber{
return ComplexNumber(this.real + c.real, this.imaginary + c.imaginary)
}
override fun toString(): String {
return "${this.real} + ${this.imaginary}i"
}
}
fun main() {
val c1 = ComplexNumber(2,4)
val c2 = ComplexNumber(3,3)
println("Complex no. obtained by adding c1 & c2: ${c1.plus(c2)}")
}
加 c1 & c2: 5 + 7i 得到的复数
在这个例子中,我们重载了plus()
函数来添加两个复数。它会给复数加上实数和虚数。
摘要
在本教程中,我们讨论了运算符重载,并看到了一个示例。至此,我们结束了这个 Kotlin 教程系列。有关参考资料,您可以随时参考官方文档:
Cordova
基础
Cordova:什么是 Apache Cordova?
原文:https://www.studytonight.com/apache-cordova/overview-of-apache-cordova
- 它允许软件程序员用
HTML
、CSS
和Javascript
为移动设备(安卓、iOS、视窗、Ubuntu 操作系统等)构建应用。 - 最重要的是- 是开源的。
这意味着,凭借良好的 HTML、CSS 和 Javascript 编码技巧,人们可以在 Cordova 的帮助下为大多数移动操作系统构建一个 App,而无需为各种平台学习不同的新编程语言。
以下是可以使用 Cordova 开发应用的平台:
- 机器人
- ios
- Windows 操作系统
- 黑莓
- Firefox 操作系统
- 智能移动终端操作系统
- 蒂森
- Web 操作系统
- 人的本质
Cordova 建筑
Cordova 为我们提供了可用于访问和激发原生移动操作系统功能的 API,如地理定位、加速度计、摄像头、存储、通知等。
网络应用不过是一个使用HTML
创建的简单网页,用户界面使用CSS
和Javascript
、jQuery
等样式。
Cordova,让我们创建一个应用,其中我们的网络应用在网络视图(HTML 渲染引擎)中初始化。
Cordova 插件是可用于利用本机操作系统功能的组件。
ApacheCordova 的优势
以下是使用 Apache Cordova 开发应用的一些主要优势:
- 如果你选择原生应用,那么你将不得不为不同的操作系统学习不同的语言。比如:安卓的
Java
,iOS 的Objective C
或者Swift
,Windows 的.NET
等等。但是使用 Apache Cordova,您可以一次构建多个平台的应用,而无需学习新的编程语言。 - 发展很快,因为在
HTML
、CSS
、Javascript
开发的一个应用可以很容易的转化成其他平台支持的应用。 - 最适合早期初创公司,因为产品可以同时在多个平台上推出。而且维护这个应用非常容易。
- 原型制作非常快。
- 由于设计涉及
CSS
,因此很容易产生优秀的设计,而没有 iOS、安卓等原生用户界面设计的麻烦。
我们开始学习:
Cordova:命令行界面
原文:https://www.studytonight.com/apache-cordova/command-line-interface
命令行界面(CLI) 是一个基于文本的界面,用于操作软件和操作系统,同时允许用户通过在界面中键入简单的命令并以相同的方式接收回复来响应视觉提示。命令行界面与目前在最新操作系统中使用的GUI有很大不同。
我们也称之为 Mac OS 中的终端或者 Windows 操作系统中的命令提示符。
- 在 Linux 或 Mac 中,我们称之为本地命令行界面终端。
- 在 Windows 中我们称之为原生 CLI CMD(命令提示符)。
CLI 在 Cordova 扮演什么角色?
- Cordova 完全依赖于 CLI,因此没有它,我们无法执行单个进程。
- 它被使用,
- 创建一个 Cordova 项目。
- 添加我们想要开发应用的平台。
- 添加插件。
- 去创造 APK。
对于这些列出的任务,我们必须传递命令行参数。
如何在 Windows 操作系统中打开 CMD?
-
Search cmd in the Menu search bar by typing cmd or command prompt, then click on the Command Prompt App option in search results.
-
We can also press
Ctrl + R
to open RUN dialog box, and type in cmd to open Command Prompt. -
It will open a black colored screen, this is the command prompt. Step 1 will open cmd in normal mode.
-
To open command prompt in administrator mode, search cmd in searchbar and click right button of mouse and choose option Run as administrator.
以下是一些在日常工作中使用的有用命令:
cls
→清除命令提示符屏幕cd [directory_path]
→转到任意目录cd ..
→从任何目录出来,到它的直接父目录。mkdir [directory_name]
→该命令用于创建任意目录。ipconfig
→获取您的 IP 地址信息和 DNS 相关信息。
在苹果操作系统中打开终端
-
Press
Command + Space
to open Spotlight Search, and type terminal in the search field. -
And click on the Terminal - Utilities option to open the Terminal.
Cordova:应用开发工具
原文:https://www.studytonight.com/apache-cordova/tools-for-app-development
现在,我们将了解应用开发所需的各种工具。我们必须下载 5 种不同的工具:
- NodeJS(节点名称)
- Cordova CLI
- Apache 人 Ant
- 安卓 SDK
- Java JDK
NodeJS(节点名称)
NodeJS 是一个 JavaScript 运行时,是开源的。我们使用 NodeJS 来执行用 Javascript 编写的后端代码。它是在 Chrome V8 javascript 引擎上制作的。它重量轻,效率很高。
NodeJS 的套餐是npm
。它是最大的开源图书馆生态系统之一。我们会用npm
下载Cordova,JS 库,各种插件,包等。
Cordova CLI
cordova 命令行界面用于创建、构建、部署、管理基于 cordova 的应用。从创建项目到构建可执行文件,我们将在本教程中使用命令行界面。
Apache 人 Ant
它的主要目标是构建一个 Java 应用。这是一个 JavaScript 库,也是使用命令行运行的。或者你可以说它是一个构建工具。使用 Ant,我们可以创建 Ant 构建文件,其中包含如何编译、组装、测试和运行特定 Java 应用的所有细节。
安卓 SDK
这是一个SDK(SDK) ,其中包含了构建安卓应用所需的所有必要库。所以如果我们想开发安卓应用,我们需要这个。
Java JDK
用于开发 Java 应用的是 Java 开发工具包(JDK) 。再次非常重要。
在这个快速教程中,我们将使用 Cordova 开发一个安卓应用,因此,上面提到的工具。在下一个教程中,我们将学习如何在您的计算机/笔记本电脑上设置所有这些工具。
Cordova:工具安装
原文:https://www.studytonight.com/apache-cordova/tools-installation
现在我们开始一个接一个地在 Windows 操作系统上安装工具。
安装节点
首先我们需要下载并安装 NodeJS。你可以从这里的下载。向下滚动,您将看到两个标题为下载窗口的下载选项。下载最稳定的 Nodejs 版本。稳定版前缀为 LTS
下载完成后,您需要安装它。要安装,只需双击刚刚下载的文件。安装后,打开 cmd 并键入node -v
。如果它显示 vx.y.z(x,y,z 是数字),那么你已经成功安装了。
下一个类型npm -v
。如果它还显示 x.y.z(x,y,z 是数字),那么一切都安装正确。
如果 cmd 抛出错误,在执行上述任何命令时,在节点检查。JS 命令提示符。
如何打开 NodeJs 命令提示符
只需在搜索栏中搜索节点。
如果 Nodejs cmd 也抛出了错误,那么您必须移除 Nodejs 并再次安装它,并遵循相同的过程。
安装 Cordova
在 cmd 或节点 cmd 中键入npm install -g cordova
。安装完成后,通过输入cordova -v
进行检查。
如果它显示的是版本(x.y.z),那么您已经成功安装了 cordova。
安装 Java 开发工具包(JDK)
跟着这个链接,
下载 X64。exe jdk 为 64 位窗口。下载 X86。exe jdk 为 32 位 Windows 操作系统。
如果您不知道您有哪个版本的 Windows 操作系统,只需在右键单击我的电脑或我的电脑后,从菜单中选择属性选项。
在那里,您将看到您的计算机/笔记本电脑的版本号(16 位、32 位、64 位),与标签系统类型相对应
成功安装 JDK 后。下一步是将其添加到我们系统的路径变量中。
如何打开和更新路径变量
在搜索栏中搜索环境变量。选择编辑系统环境变量选项,会显示一个新的对话框窗口。
点击对话框底部的环境变量按钮。
现在添加一个系统变量并将其命名为 JAVA_HOME ,并添加另一个系统变量,其名称为, _JAVA_OPTIONS 。
为了理解我们必须分配给系统变量 JAVA_HOME 和 _JAVA_OPTIONS 的值,请检查下面指定的地址:
爪哇 JDK 的地址将是c:\Program Files\Java\jdk_(x.y.z_k)
。让我们假设这是地址 1
‘bin’的地址将是c:\Program Files\Java\jdk_(x.y.z_k)\bin
。让我们假设这是地址 2
JRE 'bin '的地址将为c:\Program Files\Java\jre_(x.y.z_k)\bin
。让我们假设这是地址 2a
现在添加地址 1 作为变量名的变量值, JAVA_HOME 。在系统变量框中,有一个名为路径的变量。用分号;
分隔值,添加地址 2 和地址 2a 作为路径变量的变量值。例如:地址 2;地址 2a
接下来添加地址 2 和地址 2a 作为用户变量路径的变量值(用户变量面板就在系统变量上方)。
并添加 -Xmx512M ,作为系统变量 _JAVA_OPTIONS 的变量值。
保存所有这些更改并重新启动 cmd ,然后键入javac -version
。如果它显示了版本,那么您已经成功安装了 Java。
安装 Apache 蚂蚁
跟着这个链接下载最新的 zip 文件,把它解压到你想保存的地方。
让我们假设您是在用户/【系统名称】/蚂蚁位置提取的。
ant 的位置将是 user/[system _ name]/Apache _ ant _ x . y . z(x . y . z 将是 1.10.1,1.9.7,...).让我们假设这是地址 3
bin 的位置将是 user/[system _ name]/Apache _ ant _ x . y . z/bin(x . y . z 将是 1.10.1,1.9.7,...).让我们假设这是地址 3a
现在创建一个新的系统变量 ANT_HOME ,并添加地址 3 作为变量值。
在路径和路径中,使用 smeicolon ;
将地址 3a 添加到现有值中
保存所有更改后,重新启动 cmd 并键入ant -v
。如果它显示与我们下载的版本号相同,那么您已经安装了 apache ant。
安卓 SDK 安装
跟随这个链接:https://dl.google.com/android/installer_r24.4.1-windows.exe
安装后,查找安装安卓 SDK 和平台工具的目录。在我的电脑中,它安装在, *C:\Users[system_name]*
这里我们有完整的 Android SDK 目录结构,其中有 2 个目录对我们很重要,它们是:
C:\ Users [User _ name]\ AppData \ Local \ Android \ Android-SDK \工具和C:\ Users [User _ name]\ AppData \ Local \ Android \ Android-SDK \平台-工具”
现在创建一个新的系统变量 ANDROID_HOME ,只添加 Android SDK 目录作为变量值。
在路径变量中,添加安卓 SDK 的platform tools
目录和tools
目录。
现在保存所有更改,重启 cmd 并输入android
。
一个新的屏幕将会弹出,恭喜!您已经成功安装了 Android SDK。
在新窗口中,勾选(勾选)CheckBox
,仅下载安卓 SDK 工具、安卓 SDK 平台工具、工具面板中的 SDK 构建工具以及下载 SDK 平台等。
从下一课开始,我们将从应用的开发开始。
进阶
Cordova:所需编程语言
原文:https://www.studytonight.com/apache-cordova/programming-languages
对于 Cordova 中的 App DJevelopment,我们使用 HTML、CSS、JS、各种库,如:boostap、 jQuery 、 Angular 等。
超文本标记语言
超文本标记语言用于为任何网页创建 DOM 结构。它的主要动机是在浏览器中打开时在屏幕上显示内容。
HTML 基本结构:
<html>
<head>
<title> </title>
</head>
<body>
</body>
</html>
如果你是 HTML 新手,可以从这里学习: HTML 课程。
半铸钢ˌ钢性铸铁(Cast Semi-Steel)
层叠样式表用于设置 HTML 内容的样式,使其看起来不错。
CSS 基本结构:
假设我们必须为正文内容提供背景色。
<style type="text/css">
body {
background-color: blue;
}
</style>
我们把这个style
标签放在head
标签里。
<head>
<style>
//CSS Code
</style>
</head>
或者我们可以在另一个文件中编写 CSS 代码,并将其链接到我们的 HTML 文件。
为此,请命名一个文件 style.css ,并在该文件中编写以下单独的 css 代码:
body{
background-color: blue;
}
现在要将这个 CSS 文件添加到我们的 HTML 代码中,请执行以下操作:
index.html
<head>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
注意:在 style.css 文件中写 CSS 代码时,现在不要包含<style>
标签。
JS,或者叫 Javascript
我们使用 Javascript 对呈现在网页中的内容进行动态操作。
假设我们必须注入一个字符串,比如说我正在使用今晚学习动态地学习我们的网页的body
。
<script type="text/javascript">
document.getElementByTagName('body').innerHTML="I am learning using Studytonight";
</script>
我们可以将 javascript 代码放在script
标签中,该标签放在head
标签中。
<head>
<script>
//Javascript code
</script>
</head>
或者,我们可以在另一个文件中单独编写 JS 代码,并将其添加到我们预先存在的 HTML 文件中。例如:用 index.js 编写 JS 代码
index.js
document.getElementByTagName('body').innerHTML="I am learning using Studytonight";
alert("I am learning Hybrid app development on Studytonight ");
prompt("What is your name?");
在 HTML 文件中,我们可以添加 javascript 文件,
index.html
<head>
<script type="text/javascript" src="index.js"></script>
</head>
注意:不要在 index.js 中包含<script>
标签
Javascript 库
我们使用 javascript 库来最小化我们的努力。让我们举个例子:假设你必须动态更新一个div
标签的内容,由id="test-div"
标识。然后,您可以在平面 JS 中编写这段代码,也可以使用任何 JS 库。
平面 Javascript 中的代码
document.getElementById('test-div').innerHTML = "I am learning Hybrid App development on Studytonight";
相同代码,使用 jQuery
$('div').html("I am learning Hybrid App development on Studytonight");
注:第二种写代码方式比第一种更灵活。
Cordova:如何使用 JavaScript 库?
将它包含在您的 HTML 页面中,就像您添加了一个单独的 Javascript 文件并使用它一样。
<head>
<script type="text/javascript" src="library_name.js"></script>
</head>
所以任何一个网页的最终结构都是这样的:
<html>
<head>
<script type="text/javascript" src="library_name.js"></script> //Any library jquery.js etc
<script type="text/javascript" src="index.js"></script> // Your own JS code
<link rel="stylesheet" type="text/css" href="name.css"> // Your own CSS code
<link rel="stylesheet" type="text/css" href="css_library.css"> //CSS library
</head>
<body>
<div id="test-div" ></div>
</body>
</html>
注:要使用 Cordova 进行 App 开发,必须具备上述所有概念的知识。
Cordova:首个安卓应用
原文:https://www.studytonight.com/apache-cordova/first-android-application
现在我们准备使用 Apache Cordova 创建我们自己的第一个安卓应用。
-
打开
cmd
。 -
转到您想要创建第一个应用的位置。假设你想在桌面上创建你的第一个应用。所以在命令提示符下输入以下代码:
cd desktop
,如果你在这里“C:user \ system _ name”。命令cd desktop
将带你到桌面位置。 -
键入
cordova create [project_name] [package_name] [apk_name]
并按回车键。项目名称 →这将是你的项目名称,就像 myFirstApp 一样。执行第三步后,将在桌面上创建一个具有指定名称的文件夹。你可以去那里看看。
package_name →每个 App 都有一个唯一的应用 ID,称为 package name,如com . stytomnight . App、com . my firstatpp . Android、any . any . any other things等。
apk_name →是 apk 的名称。
-
键入
cd [project_name]
并按回车键,进入项目目录。 -
现在我们将指定我们想要为其创建移动应用的平台的名称,例如,我们可以通知 cordova,我们想要通过使用命令
cordova platform add android
来创建 android 应用。它将增加安卓平台。您可以在项目文件夹内的平台文件夹中看到它。 -
键入
cordova build android
。该命令将生成 apk。第一次第五步或者第六步需要时间,因为会下载梯度文件。
你的 apk 的位置将是:project _ name/platforms/Android/build/output/apk。
你可以在模拟器上运行这个 apk 或者复制到你的安卓手机上安装。启动应用后,您将看到默认的 apache HTML 编码屏幕。
Cordova:修改我们的应用
现在我们将在第 4 步之后把自己的文件添加到 app 文件夹中。
我们的 HTML 文件:index.html
<html>
<head>
<script type="text/javascript" src="index.js"></script>
<link rel="stylesheet" type="text/css" href="name.css">
</head>
<body onload="ask()">
<div id='question'>Tell us your experience on Studytonight</div>
<div id='answer'></div>
</body>
</html>
我们的 CSS 文件: style.css
#question {
margin-top:100px;
text-align:center;
color:red;
border: blue solid 2px;
}
#question:hover {
color:geen;
}
#answer {
margin-top:30px;
text-align:center;
color:yellow;
border: red solid 2px;
}
我们的 Javascript 文件: index.js
function ask(){
// This function will be called when page will be loaded.
var k = prompt("Tell us your experience on Studytonight");
if(k.length > 0) {
// Before inserting string into the div, it clear it first.
document.getElementById('answer').innerHTML = "";
// Now it will inject string into the div.
document.getElementById('answer').innerHTML = k;
}
else {
// If length of string is 0, then it will again ask you the same question.
ask();
}
}
现在打开项目 _ 名称文件夹,转到 www 文件夹,删除所有预先存在的文件,放置所有三个文件(index.html
、index.js
和style.css
)。然后再次遵循步骤 5 & 6。
config.xml
文件是干什么用的?
当你打开项目名称文件夹时,你会看到一个config.xml
文件。那么我们来探究一下这个文件是干什么用的?在记事本、记事本++、Atom 或任何好的编辑器中打开这个 config.xml 文件。
config.xml 是我们项目的全局配置文件。每个项目都会有这个文件。它指定了平台、使用的插件、打开的第一页、权限等。
-
它指定开发人员想要为哪个平台创建应用。
-
必需的插件。
-
在 config.xml 中,
content
标记用于指定要打开的第一页,<content src="index.html" />
每当打开应用时,它都会被重定向到此页
index.html
。只要修改 config.xml 文件中的配置,您就可以编辑它,并将其更改为类似firstpage.html
的任何内容。
更多信息,请点击链接:https://cordova.apache.org/docs/en/latest/config_ref/
Cordova:整合谷歌地图
原文:https://www.studytonight.com/apache-cordova/integrating-google-map
现在我们将创建另一个快速项目,其中我们将把谷歌地图集成到我们的安卓应用中。
-
创建新项目。你知道怎么做,我们在上一课已经做了。
-
Now go to Google's Developer Console → https://developers.google.com/maps
-
向下滚动点击谷歌地图 Javascript API
-
点击获取一个键。
-
现在点击创建项目,然后命名您的项目并启用 API。
-
把钥匙复制到夹板上。
-
Now it's time for writing HTML, JS and CSS code.
我们已经将 JS、CSS 和 HTML 代码集成在一个文件中。如果你愿意,你可以把这段代码分解成 3 个独立的文件。
index.htmlT3】
<html> <head> <style type="text/css"> #map_area { position:fixed; height:100%; width:100%; top:0; left:0; } </style> <script type="text/javascript"> function start() { var latlong = {lat: 24.801522, lng:84.995989}; var map = new google.maps.Map(document.getElementById('map_area'), { zoom: 17, center: latlong }); var marker = new google.maps.Marker({ position: latlong, map: map }); } </script> </head> <body> <div id="map_area"></div> <script src="https://maps.googleapis.com/maps/api/js?key=API_KEY&callback=start"><script> </body> </html>
-
将上述代码放入您的
index.html
文件中,并将该文件放入 www 文件夹中。 -
传递命令生成 apk 文件。
-
Transfer this apk to your phone and test it.
![Integrating Google Map](https://gitee.com/OpenDocCN/studytonight-zh/raw/master/docs/mobi/img/0b25781099c8a9eeff1659f3ae2f2167.png)
高级
Apache Cordova 插件
Plugina 允许用 Cordova 开发的应用访问设备的功能。插件是用 JavaScript 和本机库编写的。所有 cordova 的主要特性都是作为插件实现的。如果我们不使用插件,那么我们就不能使用任何原生特性。
科罗多娃:为什么我们使用插件?
让我们假设您想要访问设备的图库或联系人,在这种情况下,我们需要插件,它将与设备通信并请求设备授予所需的权限。
注意:你也可以创建自己的插件。
例如:
假设你想从联系人列表中选择一个联系人,那么你将如何通过你的应用做到这一点,所以这里我们需要一个插件,它与设备的本地功能进行通信,并请求授予权限。
比如,如果你想从树上摘一个芒果,但是树不是你的,那么你要做什么,你首先要问树的主人,如果他允许,那么只有你可以摘芒果,但是如果他不允许,那么你就不能去摘芒果。以同样的方式,插件请求权限,也提供了一种对权限采取行动的方式。
Cordova:插件的类型
插件有很多种,有些是:
- 相机插件(打开相机)
- 地理定位插件(它获取你的位置坐标→纬度,经度)
- 文件传输插件(它将文件从你的存储器传输到其他地方→比如服务器)
- 联系人列表插件
- 推送通知插件
在你的应用中使用 Cordova 插件
原文:https://www.studytonight.com/apache-cordova/plugin-integration
插件可以通过命令行集成到您的应用中。添加平台后,我们传递另一个命令给集成插件(可选)。
例如:
要添加相机插件,请键入cordova plugin add cordova-plugin-camera
。
上面的命令会添加相机插件,现在你可以用函数来调用它。
Cordova:使用地理定位插件
让我们创建一个应用,收集你的位置坐标,并显示在谷歌地图上。我们已经创建了一个与谷歌地图集成的应用,现在我们将创建另一个应用,它将在谷歌地图上显示您的设备的位置。
-
创建项目。
-
添加平台→安卓
-
添加地理定位插件-键入
cordova plugin add cordova-plugin-geolcation
并按回车键。 -
现在在您的index.html文件中编写以下代码,并将其放入项目文件夹中的 www 目录中。
<html> <head> <style type="text/css"> #map_area { position:fixed; height:100%; width:100%; top:0; left:0; } </style> <script type="text/javascript"> function getLocation() { if (navigator.geolocation) { function showLocation(position) { var latitude = position.coords.latitude; var longitude = position.coords.longitude; } navigator.geolocation.getCurrentPosition(showPosition); } else { alert('Not allowed by device'); } } function showPosition(position) { var lat = (position.coords.latitude); var long = (position.coords.longitude); start(lat, long); } function start(lat, long) { var latlong = {lat: lat, lng: long}; var map = new google.maps.Map(document.getElementById('map_area'), { zoom: 15, center: latlong }); var marker = new google.maps.Marker({ position: latlong, map: map }); } </script> </head> <body> <div id="*map_area*"></div> <script src="https://maps.googleapis.com/maps/api/js?key=*API_KEY*&callback=getLocation"><script> </body> </html>
脚本加载成功后,会调用
geo Location
函数。此功能请求设备授予所需的权限。如果设备授予权限,会将经纬度传递给start
功能。您的设备位置将显示在地图上。
Cordova:AJAX 简介
原文:https://www.studytonight.com/apache-cordova/introduction-to-ajax
AJAX 代表异步 Javascript 和 XML 。它是一个客户端脚本,在 Javascript 中用来与服务器通信,交换数据或任何东西,而不刷新页面。
让我们假设我们想要制作一个基于动态 cordova 的应用,其中用户需要与服务器交换数据,比如登录凭证验证,因此我们可以使用 AJAX 将数据发送到服务器,并通过同一个网关服务器将结果发送回用户。
Ajax 基本代码:我们将使用 jquery。
$.ajax
是一个 jQuery 函数,向服务器发出 http POST 、 GET 等请求并接收结果,无需刷新或重新加载页面。
$.ajax({
type : 'get', //Request method: GET, POST
url : 'http://studytonight.php/login.php', //Where to send the data
data: {name, password}, //What data you want to send
success:function(data) {
//Here you will receive data from server
//Do what you want to do with data
console.log(data) //This is a example, like we want to print the result
}
})
注意:涵盖 Ajax 和 jQuery 不在本教程的范围内。但是我们强烈建议您学习 Ajax,因为如果您想要创建动态应用,它非常有用。
Cordova:与后端的连接
原文:https://www.studytonight.com/apache-cordova/connection-with-backened
现在,我们将学习如何将基于 cordova 的应用与后端连接起来,以动态处理数据。
后端语言 → PHP
数据库 → MYSQL
你有没有想过,当你以某种登录形式输入你的用户名和密码时,会发生什么?它如何验证您的凭据?因此,让我们尝试理解并实现凭证验证。
当您输入用户名和密码时,客户端(大多数情况下是浏览器或应用)会将您的用户名、密码和一些头数据发送到服务器(比如基于 PHP 的服务器和基于 MySQL 的数据库)。在那里,Php 接收你的数据并采取相应的行动。执行一个 SQL 查询来获取数据,然后将数据与提交的用户名和密码进行比较。它通过同一个网关发回结果,然后客户端也根据收到的响应做出响应(比如,服务器响应是参数不正确,那么客户端会显示用户名和密码不匹配。消息)。
现在在本教程中,我们将创建一个与后端通信的应用。为此,我们需要XAMPP(https://www.apachefriends.org/index.html)申请。按照链接下载并安装 XAMPP。XAMPP 是一个本地服务器,运行 Apache、Php 和 MySQL,用于在本地机器上开发和测试网站和应用。它在你的笔记本电脑上本地复制一个 LAMP 网络服务器。
-
安装完成后,打开 XAMPP 服务器,点击
Apache
、MySQL
对应的Start
。注意:服务器默认端口为 80。
-
现在用 Php 编写一些代码,并把它放在 XAMPP 文件夹内的 htdocs 文件夹中。
index.php
<?php echo "hello world!; ?>
-
打开浏览器,在地址栏输入: http://localhost 或 http://127.0.0.1 ,应该会显示你好世界!在屏幕上。
这意味着我们的 XAMPP 服务器正在成功运行。现在我们准备开发一个动态的手机应用。客户端脚本(HTML、CSS、Javascript 和 jQuery,就像之前的教程一样)。将
jquery.js
文件与index.html
保存在一起(或两者放在同一个文件夹中) -
Here is the
index.html
file.<html> <head> <script type=”text/javascript” src=”*jquery.js*”></script> <script type=”text/javascript”> $(document).ready(function(){ $(“#sub”).click(function(){ var firstname = $(“#firstname”).val(); var lastname = $(“#lastname”).val(); if($.trim(firstname).length >0 & $.trim(lastname).length >0) { $.ajax({ type:”POST”, //Request type url: “http://localhost/firstname.php”, data:{firstname:firstname, lastname:lastname}, cache:false, success:function(data) { alert(data); } }) } else { alert(‘Input fields are empty’); } }) }) </script> </head> <body> <input type=”text” placeholder=”write your first name” id=”firstname”> <input type=”text” placeholder=”write your last name” id=”lastname”> <button id=”sub”>Submit result</button> </body> </html>
和
firstname.php
<?php $firstname = $_POST[‘firstname’]; $lastname = $_POST[‘lastname’]; echo $firstname.” “.$lastname; ?>
现在把这个 PHP 文件和 HTML 文件放在 htdocs 文件夹中。确保您的 XAMPP 服务器正在运行。在浏览器中运行index.html,输入并检查输出。
Cordova:将代码移植到安卓应用
现在我们将在手机上运行这个代码,所以首先用同一个热点连接你的笔记本电脑和手机(在其中你将测试你的应用)。一旦连接建立,打开笔记本电脑中的 cmd ,输入ipconfig
并按回车键。它会显示 IP 地址,如果你的电脑连接了 WIFI 路由器,那么复制无线局域网适配器 wifi 的 IP,否则复制局域网 IP 地址。将【index.html】中$.ajax
功能内的localhost
( url
属性)替换为该 IP 地址。
*
我们只需要 App 中的index.html
文件,firstname.php
文件将保留在 XAMPP 目录的 htdocs 文件夹中。
现在生成 apk 。将它复制到您的设备,并检查它是否工作。
万一它不工作,请确定您的服务器是否正在运行?两台设备是否连接到同一个 wifi 热点网络?如果连接到同一个 wifi 网络,请检查 IP 地址。接下来,我们将把用户的输入保存到 MySQL 数据库中。
为此,首先我们必须创建 MySQL 数据库。
-
在浏览器中打开http://localhost/phpmyadmin。
-
Click on SQL
-
在文本区域键入以下命令,然后单击开始。
CREATE DATABASE mydb;
该命令将创建数据库 mydb ,如果它还不存在的话。
-
现在打开 mydb 数据库,在边栏中点击它,然后再次点击 SQL。然后使用以下命令创建表格。
CREATE TABLE my_table ( id int AUTO_INCREMENT, firstname varchar(200), lastname varchar(200) )
它将在 mydb 数据库中创建一个名为 my_table 的表。
-
客户端代码,即
index.html
文件,将保持不变,但 Php 端代码将改变。firstname.php
<?php /* localhost is the location where the server is located root is the global username of server ' ' this root has no password protection, hence empty my_db is db with which we want to connect */ $con = mysqli_connect(‘localhost’,’root’,’’,’my_db) or die (‘unable to connect’); $firstname = $_POST[‘firstname’]; $lastname = $_POST[‘lastname’]; $sql = “INSERT INTO `my_table`(`firstname`,`lastname`) VALUES(‘$firstname’,’$lastname’); $result = mysqli_query($con,$sql); if($result) { echo $firstname.” “.$lastname; } else { echo “unable to insert data”; } ?>
现在尝试一下或者刷新 phpmyadmin 页面,检查数据是否被插入。