提交 f2f0d96b 编写于 作者: M Mr.Hope

feat: update android docs

上级 ecca42b3
......@@ -12,7 +12,17 @@ Android 开发基础知识介绍
## 目录
- [介绍](intro.md)
### 快速上手
- [介绍](get-started/intro.md)
- [创建项目](get-started/create.md)
- [构建简单的界面](get-started/interface.md)
- [启动另一个 activity](get-started/activity.md)
### 其他
- [基础知识](base.md)
......
---
title: Android 快速上手
icon: android
date: 2020-04-07
category:
- Android
- 快速上手
tag:
- 快速上手
article: false
---
## 快速上手
- [介绍](intro.md)
- [创建项目](create.md)
- [构建简单的界面](interface.md)
- [启动另一个 activity](activity.md)
---
title: 启动另一个 activity
icon: info
date: 2022-04-01
category:
- Android
- 快速上手
tag:
- 快速上手
---
在本课中,您将向 MainActivity 添加一些代码,以便在用户点按 Send 按钮时启动一个显示消息的新 activity。
<!-- more -->
## 响应“Send”按钮
您可按照以下步骤,向 MainActivity 类添加一个在用户点按 Send 按钮时调用的方法:
1. 在 app > java > com.example.myfirstapp > MainActivity 文件中,添加以下 sendMessage() 方法桩:
:::: code-group
::: coude-group-item Kotlin
```kotlin
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
/** Called when the user taps the Send button */
fun sendMessage(view: View) {
// Do something in response to button
}
}
```
:::
::: coude-group-item Java
```java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/** Called when the user taps the Send button */
public void sendMessage(View view) {
// Do something in response to button
}
}
```
:::
::::
您可能会看到一条错误,因为 Android Studio 无法解析用作方法参数的 View 类。若要清除错误,请点击 View 声明,将光标置于其上,然后按 `Alt + Enter`(在 Mac 上则按 `Option + Enter`)进行快速修复。如果出现一个菜单,请选择 Import class。
1. 返回到 activity_main.xml 文件,并从该按钮调用此方法:
1. 选择布局编辑器中的相应按钮。
1. 在 Attributes 窗口中,找到 onClick 属性,并从其下拉列表中选择 `sendMessage [MainActivity]`
现在,当用户点按该按钮时,系统将调用 `sendMessage()` 方法。
请注意此方法中提供的详细信息。系统需要这些信息来识别此方法是否与 android:onClick 属性兼容。具体来说,此方法具有以下特性:
1. 公开。
1. 返回值为空,或在 Kotlin 中为隐式 Unit。
1. View 是唯一的参数。这是您在第 1 步结束时点击的 View 对象。
1. 接下来,填写此方法,以读取文本字段的内容,并将该文本传递给另一个 activity。
## 构建一个 intent
`Intent` 是在相互独立的组件(如两个 activity)之间提供运行时绑定功能的对象。Intent 表示应用执行某项操作的意图。您可以使用 intent 执行多种任务,但在本课中,您的 intent 将用于启动另一个 activity。
在 MainActivity 中,添加 EXTRA_MESSAGE 常量和 sendMessage() 代码,如下所示:
:::: code-group
::: coude-group-item Kotlin
```kotlin
const val EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE"
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
/** Called when the user taps the Send button */
fun sendMessage(view: View) {
val editText = findViewById<EditText>(R.id.editTextTextPersonName)
val message = editText.text.toString()
val intent = Intent(this, DisplayMessageActivity::class.java).apply {
putExtra(EXTRA_MESSAGE, message)
}
startActivity(intent)
}
}
```
:::
::: coude-group-item Java
```java
public class MainActivity extends AppCompatActivity {
public static final String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/** Called when the user taps the Send button */
public void sendMessage(View view) {
Intent intent = new Intent(this, DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.editTextTextPersonName);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}
}
```
:::
::::
预计 Android Studio 会再次遇到 Cannot resolve symbol 错误。如需清除这些错误,请按 Alt+Enter(在 Mac 上则按 Option+Return)。您最后应导入以下内容:
:::: code-group
::: coude-group-item Kotlin
```kotlin
import androidx.appcompat.app.AppCompatActivity
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.widget.EditText
```
:::
::: coude-group-item Java
```java
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
```
:::
::::
DisplayMessageActivity 仍有错误,但没有关系。您将在下一部分中修复该错误。
sendMessage() 将发生以下情况:
- Intent 构造函数会获取两个参数:Context 和 Class。
首先使用 Context 参数,因为 Activity 类是 Context 的子类。
在本例中,系统将 Intent, 传递到的应用组件的 Class 参数是要启动的 activity。
- putExtra() 方法将 EditText 的值添加到 intent。Intent 能够以称为“extra”的键值对形式携带数据类型。
您的键是一个公共常量 EXTRA_MESSAGE,因为下一个 activity 将使用该键检索文本值。为 intent extra 定义键时,最好使用应用的软件包名称作为前缀。这样可以确保这些键是独一无二的,这在您的应用需要与其他应用进行交互时会很重要。
- startActivity() 方法将启动一个由 Intent 指定的 DisplayMessageActivity 实例。接下来,您需要创建该类。
::: tip
导航架构组件允许您使用导航编辑器将一个 activity 与另一个 activity 相关联。建立这种关联后,您可以利用 API 在用户触发关联的操作(例如,用户点击某个按钮时)时启动第二个 activity。如需了解详情,请参阅导航。
:::
## 创建第二个 activity
若要创建第二个 activity,请按以下步骤操作:
1. 在 Project 窗口中,右键点击 app 文件夹,然后依次选择 New > Activity > Empty Activity。
1. 在 Configure Activity 窗口中,输入“DisplayMessageActivity”作为 Activity Name。将所有其他属性保留为默认设置,然后点击 Finish。
Android Studio 会自动执行下列三项操作:
1. 创建 DisplayMessageActivity 文件。
1. 创建 DisplayMessageActivity 文件对应的布局文件 activity_display_message.xml。
1. 在 AndroidManifest.xml 中添加所需的 `<activity>` 元素。
如果您运行应用并点按第一个 activity 上的按钮,将启动第二个 activity,但它为空。这是因为第二个 activity 使用模板提供的空布局。
## 添加文本视图
新 activity 包含一个空白布局文件。请按以下步骤操作,在显示消息的位置添加一个文本视图:
1. 打开 app > res > layout > activity_display_message.xml 文件。
1. 点击工具栏中的 Enable Autoconnection to Parent 。系统将启用 Autoconnect。参见图 1。
1. 在 Palette 面板中,点击 Text,将 TextView 拖动到布局中,然后将其放置在靠近布局顶部中心的位置,使其贴靠到出现的垂直线上。Autoconnect 将添加左侧和右侧约束条件,以便将该视图放置在水平中心位置。
1. 再创建一个从文本视图顶部到布局顶部的约束条件,使该视图如图 1 中所示。
或者,您可以对文本样式进行一些调整,方法是在 Attributes 窗口的 Common Attributes 面板中展开 textAppearance,然后更改 textSize 和 textColor 等属性。
## 显示消息
在此步骤中,您将修改第二个 activity 以显示第一个 activity 传递的消息。
1. 在 DisplayMessageActivity 中,将以下代码添加到 `onCreate()` 方法中:
:::: code-group
::: coude-group-item Kotlin
```kotlin
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_display_message)
// Get the Intent that started this activity and extract the string
val message = intent.getStringExtra(EXTRA_MESSAGE)
// Capture the layout's TextView and set the string as its text
val textView = findViewById<TextView>(R.id.textView).apply {
text = message
}
}
```
:::
::: coude-group-item Java
```java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_message);
// Get the Intent that started this activity and extract the string
Intent intent = getIntent();
String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
// Capture the layout's TextView and set the string as its text
TextView textView = findViewById(R.id.textView);
textView.setText(message);
}
```
:::
::::
1.`Alt + Enter`(在 Mac 上则按 `Option + Return`)导入其他所需的类:
:::: code-group
::: coude-group-item Kotlin
```kotlin
import androidx.appcompat.app.AppCompatActivity
import android.content.Intent
import android.os.Bundle
import android.widget.TextView
```
:::
::: coude-group-item Java
```java
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
```
:::
::::
## 添加向上导航功能
在您的应用中,不是主入口点的每个屏幕(所有不是主屏幕的屏幕)都必须提供导航功能,以便将用户引导至应用层次结构中的逻辑父级屏幕。为此,请在应用栏中添加向上按钮。
若要添加向上按钮,您需要在 `AndroidManifest.xml` 文件中声明哪个 activity 是逻辑父级。打开 app > manifests > AndroidManifest.xml 文件,找到 DisplayMessageActivity 的 `<activity>` 标记,然后将其替换为以下代码:
```xml
<activity android:name=".DisplayMessageActivity"
android:parentActivityName=".MainActivity">
<!-- The meta-data tag is required if you support API level 15 and lower -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity" />
</activity>
```
Android 系统现在会自动向应用栏添加向上按钮。
## 运行应用
点击工具栏中的 Apply Changes 以运行应用。当应用打开后,在文本字段中输入一条消息,点按 Send 即会看到该消息显示在第二个 activity 中。
---
title: 创建项目
icon: info
date: 2022-04-01
category:
- Android
- 快速上手
tag:
- 快速上手
---
本课将介绍如何使用 Android Studio 创建新的 Android 项目,并介绍该项目中的一些文件。
如需创建新的 Android 项目,请按以下步骤操作:
1. 安装最新版 Android Studio。
1. 在 Welcome to Android Studio 窗口中,点击 Create New Project。
如果您已打开一个项目,请依次选择 File > New > New Project。
1. 在 Select a Project Template 窗口中,选择 Empty Activity,然后点击 Next。
1. 在 Configure your project 窗口中,完成以下操作:
- 在 Name 字段中输入“My First App”。
- 在 Package name 字段中输入“com.example.myfirstapp”。
- 如果您想将项目放在其他文件夹中,请更改其 Save 位置。
- 从 Language 下拉菜单中选择 Java 或 Kotlin。
- 在 Minimum SDK 字段中选择您希望应用支持的最低 Android 版本。
::: tip
点击 Help me choose 链接可打开 Android Platform/API Version Distribution 对话框。此对话框会提供有关各 Android 版本在设备间的分布情况的信息。您需要权衡的主要因素是,您想支持的 Android 设备所占的百分比,以及在这些设备所搭载的各个不同版本上维护应用所需的工作量。例如,如果您选择让应用与多个不同 Android 版本兼容,那么维护最旧版本与最新版本之间的兼容性所需的工作量就会增大。
:::
- 如果您的应用需要旧版库支持,请选中 Use legacy android.support libraries 复选框。
- 其他选项保持原样。
1. 点击 Finish。
经过一段时间的处理后,Android Studio 主窗口会出现。
下面花一点时间了解一下最重要的文件。
首先,确保已打开 Project 窗口(依次选择 View > Tool Windows > Project),并从该窗口顶部的下拉列表中选择 Android 视图。随后,您可以看到以下文件:
- app > java > com.example.myfirstapp > MainActivity
这是主 activity。它是应用的入口点。当您构建和运行应用时,系统会启动此 Activity 的实例并加载其布局。
- app > res > layout > activity_main.xml
此 XML 文件定义了 activity 界面 (UI) 的布局。它包含一个 TextView 元素,其中具有“Hello, World!”文本
- app > manifests > AndroidManifest.xml
清单文件描述了应用的基本特性并定义了每个应用组件。
- Gradle Scripts > build.gradle
有两个使用此名称的文件:一个针对项目“Project: My First App”,另一个针对应用模块“Module: My_First_App.app”。每个模块均有自己的 build.gradle 文件,但此项目当前仅有一个模块。使用每个模块的 build.gradle 文件控制 Gradle 插件构建应用的方式。如需详细了解此文件,请参阅配置 build。
---
title: 构建简单的界面
icon: info
date: 2022-04-01
category:
- Android
- 快速上手
tag:
- 快速上手
---
在本节课中,您将学习如何使用 Android Studio 布局编辑器创建包含一个文本框和一个按钮的布局。这将为下一课打下基础,下节课将学习如何在点按该按钮时让应用将文本框的内容发送到其他 activity。
<!-- more -->
Android 应用的界面 (UI) 以布局和微件的层次结构形式构建而成。布局是 ViewGroup 对象,即控制其子视图在屏幕上的放置方式的容器。微件是 View 对象,即按钮和文本框等界面组件。
![ViewGroup](./assets/viewgroup.png)
Android 提供了 ViewGroup 和 View 类的 XML 词汇表,因此界面的大部分内容都在 XML 文件中定义。不过,本节课将向您介绍如何使用 Android Studio 的布局编辑器创建布局,而不是教您编写 XML 代码。布局编辑器会在您拖放视图构建布局时为您编写 XML 代码。
## 打开布局编辑器
首先,请按照以下步骤设置工作区:
1. 在 Project 窗口中,依次打开 app > res > layout > activity_main.xml。
1. 若要给布局编辑器留出空间,请隐藏 Project 窗口。为此,请依次选择 View > Tool Windows > Project,或直接点击 Android Studio 屏幕左侧的 Project。
1. 如果您的编辑器显示 XML 源代码,请点击窗口右上角的 Design 标签页。
1. 点击 (Select Design Surface),然后选择 Blueprint。
1. 点击布局编辑器工具栏中的 (View Options),并确保选中 Show All Constraints。
1. 确保 Autoconnect 处于关闭状态。当 Autoconnect 处于关闭状态时,工具栏中的提示会显示 (Enable Autoconnection to Parent)。
1. 点击工具栏中的 (Default Margins),然后选择 16。如果需要,您可以稍后调整每个视图的外边距。
1. 点击工具栏中的 (Device for Preview),然后选择 5.5, 1440 × 2560, 560 dpi (Pixel XL)。
您的布局编辑器现在如下图所示。
![布局编辑器](./assets/layout-editor.png)
左下方的 Component Tree 面板显示布局的视图层次结构。在本例中,根视图是 ConstraintLayout,它仅包含一个 TextView 对象。
ConstraintLayout 是一种布局,它根据同级视图和父布局的约束条件定义每个视图的位置。这样一来,使用扁平视图层次结构既可以创建简单布局,又可以创建复杂布局。这种布局无需嵌套布局。嵌套布局是布局内的布局(如图 2 所示),会增加绘制界面所需的时间。
例如,您可以声明以下布局,如下图所示:
- 视图 A 距离父布局顶部 16 dp。
- 视图 A 距离父布局左侧 16 dp。
- 视图 B 距离视图 A 右侧 16 dp。
- 视图 B 与视图 A 顶部对齐。
![布局示例](./assets/constraint-example.png)
## 添加文本框
请按照下面的步骤添加文本框:
1. 首先,您需要移除布局中已有的内容。在 Component Tree 面板中点击 TextView,然后按 Delete 键。
1. 在 Palette 面板中,点击 Text 以显示可用的文本控件。
1. 将 Plain Text 拖动到设计编辑器中,并将其放在靠近布局顶部的位置。这是一个接受纯文本输入的 EditText 微件。
1. 点击设计编辑器中的视图。现在,您可以在每个角上看到调整视图大小的正方形手柄,并在每个边上看到圆形约束锚点。为了更好地控制,您可能需要放大编辑器。为此,请使用布局编辑器工具栏中的 Zoom 按钮。
1. 点击并按住顶边上的锚点,将其向上拖动,直至其贴靠到布局顶部,然后将其释放。这是一个约束条件:它会将视图约束在已设置的默认外边距内。在本例中,您将其设置为距离布局顶部 16 dp。
1. 使用相同的过程创建一个从视图左侧到布局左侧的约束条件。
## 添加按钮
1. 在 Palette 面板中,点击 Buttons。
1. 将 Button 微件拖到设计编辑器中,并将其放在靠近右侧的位置。
1. 创建一个从按钮左侧到文本框右侧的约束条件。
1. 如需按水平对齐约束视图,请创建一个文本基线之间的约束条件。为此,请右键点击按钮,然后选择 Show Baseline 在布局编辑器中显示基准操作。基线锚点显示在按钮内部。点击并按住此锚点,然后将其拖动到相邻文本框中显示的基线锚点上。
::: tip
您还可以根据顶边或底边实现水平对齐。但按钮的图片周围有内边距,因此如果以这种方式对齐,那么它们看上去是没有对齐的。
:::
## 更改界面字符串
若要预览界面,请点击工具栏中的 (Select Design Surface),然后选择 Design。请注意,文本输入和按钮标签应设置为默认值。
若要更改界面字符串,请按以下步骤操作:
1. 打开 Project 窗口,然后打开 app > res > values > strings.xml。
这是一个字符串资源文件,您可在此文件中指定所有界面字符串。您可以利用该文件在一个位置管理所有界面字符串,使字符串的查找、更新和本地化变得更加容易。
1. 点击窗口顶部的 Open editor。此时将打开 Translations Editor,它提供了一个可以添加和修改默认字符串的简单界面。它还有助于让所有已翻译的字符串井然有序。
1. 点击 (Add Key) 可以创建一个新字符串作为文本框的“提示文本”。此时会打开如图 7 所示的窗口。
在 Add Key 对话框中,完成以下步骤:
- 在 Key 字段中输入“edit_message”。
- 在 Default Value 字段中输入“Enter a message”。
- 点击 OK。
1. 再添加一个名为“button_send”且值为“Send”的键。
现在,您可以为每个视图设置这些字符串。若要返回布局文件,请点击标签页栏中的 activity_main.xml。然后,添加字符串,如下所示:
1. 点击布局中的文本框。如果右侧还未显示 Attributes 窗口,请点击右侧边栏上的 Attributes。
1. 找到 text 属性(当前设为“Name”)并删除相应的值。
1. 找到 hint 属性,然后点击文本框右侧的 (Pick a Resource)。在显示的对话框中,双击列表中的 edit_message。
1. 点击布局中的按钮,找到其 text 属性(当前设为“Button”)。然后点击 (Pick a Resource),并选择 button_send。
## 让文本框大小可灵活调整
若要创建一个适应不同屏幕尺寸的布局,您需要让文本框拉伸以填充去除按钮和外边距后剩余的所有水平空间。
继续操作之前,请点击工具栏中的 (Select Design Surface),然后选择 Blueprint。
若要让文本框大小可灵活调整,请按以下步骤操作:
1. 选择两个视图。若要执行此操作,请点击一个视图,在按住 Shift 键的同时点击另一个视图,然后右键点击任一视图并依次选择 Chains > Create Horizontal Chain。布局随即显示出来,如图 8 所示。
::: info
链是两个或多个视图之间的双向约束条件,可让您采用一致的方式安排链接的视图。
:::
1. 选择按钮并打开 Attributes 窗口。然后使用 Constraint Widget 将右外边距设为 16 dp。
点击文本框以查看其属性。然后,点击宽度指示器两次,确保将其设置为锯齿状线 (Match Constraints),如图 9 中的标注 1 所示。
1. “Match constraints”表示宽度将延长以符合水平约束条件和外边距的定义。因此,文本框将拉伸以填充去除按钮和所有外边距后剩余的水平空间。
## 运行应用
如果已在上一课中将您的应用安装到设备上,只需点击工具栏中的 (Apply Changes),即可使用新布局更新应用。或者点击 Run 'app' 以安装并运行应用。
---
title: 基础知识
icon: info
date: 2022-04-01
category:
- Android
- 快速上手
tag:
- 快速上手
---
本部分介绍如何构建简单的 Android 应用。首先,您将了解如何通过 Android Studio 创建“Hello, World!”项目并运行它。然后,您将为应用创建一个新界面,该界面会接受用户输入,并切换到应用中的一个新屏幕以显示用户输入内容。
开始之前,您需要了解有关 Android 应用的两个基本概念:它们如何提供多个入口点,以及它们如何适应不同的设备。
<!-- more -->
## 应用提供多个入口点
Android 应用都是将各种可单独调用的组件加以组合构建而成。例如,activity 是提供界面 (UI) 的一种应用组件。
“主”activity 在用户点按您的应用图标时启动。您还可以将用户从其他位置(例如,从通知中,甚至从其他应用中)引导至某个 activity。
其他组件(如 WorkManager)可使应用能够在没有界面的情况下执行后台任务。
构建您的首个应用后,请参阅 [应用基础知识][] 来详细了解其他应用组件。
## 应用可适应不同的设备
Android 允许您为不同的设备提供不同的资源。例如,您可以针对不同的屏幕尺寸创建不同的布局。系统会根据当前设备的屏幕尺寸确定要使用的布局。
如果应用的任何功能需要使用特定的硬件(例如摄像头),您可以在运行时查询该设备是否具有该硬件,如果没有,则停用相应的功能。您可以指定应用需要使用特定的硬件,这样,Google Play 就不会允许在没有这些硬件的设备上安装应用。
构建您的首个应用后,请参阅 [设备兼容性概览][] 来详细了解设备配置。
---
title: 运行应用
icon: info
date: 2022-04-01
category:
- Android
- 快速上手
tag:
- 快速上手
---
## 在真实设备上运行
按照以下步骤设置设备:
1. 使用一根 USB 线将设备连接到开发机器。如果您是在 Windows 上开发的,则可能需要为设备安装合适的 USB 驱动程序。
1. 执行以下步骤,在开发者选项窗口中启用 USB 调试:
1. 打开设置应用。
1. 如果您的设备使用 Android v8.0 或更高版本,请选择系统。否则,请继续执行下一步。
1. 滚动到底部,然后选择关于手机。
1. 滚动到底部,然后点按版本号七次。
1. 返回上一屏幕,滚动到底部,然后点按开发者选项。
1. 在开发者选项窗口中,向下滚动以查找并启用 USB 调试。
按照以下步骤操作,在设备上运行应用:
1. 在 Android Studio 中,从工具栏中的运行/调试配置下拉菜单中选择您的应用。
1. 在工具栏中,从目标设备下拉菜单中选择要用来运行应用的设备。
1. 点击 Run 。
Android Studio 会在已连接的设备上安装您的应用并启动它。您现在会看到设备上的应用中显示了“Hello, World!”。
## 在模拟器上运行
按照以下步骤操作,在模拟器上运行应用:
1. 在 Android Studio 中创建一个 Android 虚拟设备 (AVD),模拟器可以使用该设备安装和运行您的应用。
1. 在工具栏中,从运行/调试配置下拉菜单中选择您的应用。
1. 从目标设备下拉菜单中,选择要用来运行应用的 AVD。
1. 点击 Run 图标 。
Android Studio 会在 AVD 上安装应用并启动模拟器。您现在会看到应用中显示了“Hello, World!”。
---
title: 基本特性
icon: info
date: 2020-04-07
category: Android
tag:
- 介绍
---
## 应用提供多个入口点
Android 应用由各种可单独调用的组件构成。例如,Activity 是提供界面 (UI) 的一种应用组件。
“主” Activity 在用户点按您的应用图标时启动。您还可以将用户从其他位置(例如,从通知中,甚至从其他应用中)引导至某个 Activity。
其他组件(如广播接收器和服务)使应用能够在没有界面的情况下执行后台任务。
## 应用可适应不同的设备
Android 允许您为不同的设备提供不同的资源。例如,您可以针对不同的屏幕尺寸创建不同的布局。系统会根据当前设备的屏幕尺寸确定要使用的布局。
如果应用的任何功能需要特定的硬件,如摄像头,您可以在运行时查询该设备是否具有该硬件,如果没有,则停用相应的功能。您可以指定应用需要特定的硬件,这样,Google Play 就不会允许在没有这些硬件的设备上安装应用。
## 项目结构
- app > java > com.example.myfirstapp > MainActivity
这是主 Activity。它是应用的入口点。当您构建和运行应用时,系统会启动此 Activity 的实例并加载其布局。
- app > res > layout > activity_main.xml
此 XML 文件定义了 Activity 界面的布局。它包含一个 TextView 元素,其中具有“Hello, World!”文本
- app > manifests > AndroidManifest.xml
清单文件描述了应用的基本特性并定义了每个应用组件。
- Gradle Scripts > build.gradle
有两个使用此名称的文件: 一个针对项目“Project: My First App”,另一个针对应用模块“Module: app”。每个模块均有自己的 build.gradle 文件,但此项目当前仅有一个模块。您可以使用每个模块的 build.file 控制 Gradle 插件编译应用的方式
## 运行应用
### 在真实设备上运行
1. 在开发者选项窗口中启用 USB 调试。
1. 在 Android Studio 中,从工具栏中的运行/调试配置下拉菜单中选择您的应用。
1. 在工具栏中,从目标设备下拉菜单中选择要用来运行应用的设备。
1. 点击 Run
### 在模拟器上运行
1. 在 Android Studio 中创建一个 Android 虚拟设备 (AVD),模拟器可以使用它安装和运行您的应用。
1. 在工具栏中,从运行/调试配置下拉菜单中选择您的应用。
1. 从目标设备下拉菜单中,选择要用来运行应用的 AVD。
1. 点击 Run
## 术语介绍
- Intent 是在相互独立的组件(如两个 Activity)之间提供运行时绑定功能的对象。Intent 表示应用执行某项操作的意图。您可以使用 Intent 执行多种任务。
......@@ -14,12 +14,16 @@ tag:
```json
{
// 编辑器配置
"editor.accessibilitySupport": "off",
"editor.bracketPairColorization.enabled": true,
"editor.bracketPairColorization.independentColorPoolPerBracketType": true,
"editor.cursorSmoothCaretAnimation": true,
"editor.detectIndentation": false,
"editor.fontFamily": "'Fira Code', Consolas, 'Courier New', monospace",
"editor.fontLigatures": true,
"editor.formatOnSave": true,
"editor.formatOnPaste": true,
"editor.guides.bracketPairs": true,
"editor.mouseWheelZoom": true,
"editor.rulers": [80],
"editor.quickSuggestions": {
......@@ -70,7 +74,6 @@ tag:
"workbench.commandPalette.preserveInput": true,
"workbench.enableExperiments": false,
"workbench.editor.scrollToSwitchTabs": true,
"workbench.editor.untitled.experimentalLanguageDetection": true,
"workbench.iconTheme": "material-icon-theme",
"workbench.startupEditor": "none",
"material-icon-theme.folders.associations": {
......@@ -107,14 +110,16 @@ tag:
"vsintellicode.modify.editor.suggestSelection": "automaticallyOverrodeDefaultValue",
"problems.showCurrentInStatus": true,
// 在线服务设置
"telemetry.enableCrashReporter": false,
"telemetry.enableTelemetry": false,
"telemetry.telemetryLevel": "error",
// 终端设置
"terminal.integrated.confirmOnExit": "hasChildProcesses",
"terminal.integrated.copyOnSelection": true,
"terminal.integrated.enableBell": true,
"terminal.integrated.defaultProfile.windows": "PowerShell",
"terminal.integrated.defaultProfile.linux": "/bin/bash",
"terminal.integrated.env.windows": {
"NODE_OPTIONS": "--max_old_space_size=4096"
},
"terminal.integrated.profiles.windows": {
"PowerShell": {
"source": "PowerShell",
......@@ -125,13 +130,13 @@ tag:
},
"terminal.integrated.tabs.enabled": true,
"terminal.external.linuxExec": "bash",
// git
"diffEditor.ignoreTrimWhitespace": false,
"diffEditor.renderSideBySide": true,
"git.autofetch": true,
"git.confirmSync": false,
"git.enableSmartCommit": true,
"merge-conflict.autoNavigateNextConflict.enabled": true,
"security.workspace.trust.untrustedFiles": "open",
// npm 设置
"npm.enableRunFromFolder": true,
"npm.scriptExplorerAction": "run",
......@@ -147,6 +152,9 @@ tag:
"[cpp]": {
"editor.defaultFormatter": "ms-vscode.cpptools"
},
"[css]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[dart]": {
"editor.formatOnType": true,
"editor.selectionHighlight": false,
......@@ -158,6 +166,9 @@ tag:
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[latex]": {
"editor.defaultFormatter": "James-Yu.latex-workshop"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
......@@ -176,6 +187,9 @@ tag:
"[svelte]": {
"editor.defaultFormatter": "svelte.svelte-vscode"
},
"[scss]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
......@@ -183,10 +197,10 @@ tag:
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[vue]": {
"editor.defaultFormatter": "octref.vetur"
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[xml]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "DotJoshJohnson.xml"
},
"[yaml]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
......@@ -217,15 +231,11 @@ tag:
],
"C_Cpp.clang_format_fallbackStyle": "Google",
// dart
"dart.debugExternalLibraries": false,
"dart.debugSdkLibraries": false,
"dart.previewLsp": true,
"dart.openDevTools": "flutter",
// java
"java.home": "C:/Program Files/Java/jdk-16.0.1",
"java.semanticHighlighting.enabled": true,
"java.jdt.ls.java.home": "C:/Program Files/Java/jdk-16.0.1",
// python
"python.pythonPath": "C:/Users/zhang/AppData/Local/Programs/Python/Python39/python.exe",
"python.languageServer": "Pylance",
// css颜色提示配置
"colorInfo.fields": ["hex", "rgb", "alpha", "css-color-name", "preview"],
......@@ -261,10 +271,11 @@ tag:
"typescriptreact"
],
// Git Lens 设置
"gitlens.defaultDateFormat": "YYYY-MM-DD HH:mm",
"gitlens.defaultDateShortFormat": "YYYY-MM-DD",
"gitlens.defaultTimeFormat": "HH:mm",
"gitlens.gitCommands.closeOnFocusOut": true,
"gitlens.views.repositories.branches.layout": "list",
// live server
"liveServer.settings.donotShowInfoMsg": true,
// markdown 设置
"markdown.extension.orderedList.marker": "one",
"markdown.extension.print.imgToBase64": true,
......@@ -286,10 +297,6 @@ tag:
}
},
"markdown-pdf.executablePath": "C:/Users/zhang/AppData/Local/Google/Chrome/Application/chrome.exe",
// vetur 设置
"vetur.completion.tagCasing": "initial",
"vetur.validation.templateProps": true,
"vetur.useWorkspaceDependencies": true,
// stylus 设置
"stylusSupremacy.insertColons": false,
"stylusSupremacy.insertSemicolons": false,
......@@ -330,35 +337,178 @@ tag:
"leetcode.workspaceFolder": "C:/Users/zhang/.leetcode",
// stylelint 设置
"stylelint.packageManager": "yarn",
"stylelint.validate": [
"css",
"html",
"javascript",
"javascriptreact",
"less",
"markdown",
"postcss",
"sass",
"scss",
"source.css.styled",
"source.markdown.math",
"styled-css",
"sugarss",
"svelte",
"typescript",
"typescriptreact",
// "vue",
"vue-html",
"vue-postcss",
"xml",
"xsl",
"wxss"
],
// Java
"redhat.telemetry.enabled": false,
// latex
"latex-workshop.view.pdf.viewer": "tab",
"latex-workshop.latex.tools": [
{
"name": "xelatex",
"command": "xelatex",
"args": [
"-synctex=1",
"-interaction=nonstopmode",
"-file-line-error",
"%DOCFILE%"
],
"env": {}
},
{
"name": "latexmk (xelatex)",
"command": "latexmk",
"args": [
"-synctex=1",
"-interaction=nonstopmode",
"-file-line-error",
"-xelatex",
"-outdir=%OUTDIR%",
"%DOCFILE%"
],
"env": {}
},
{
"name": "latexmk (xelatex) with bibtex",
"command": "latexmk",
"args": [
"-synctex=1",
"-interaction=nonstopmode",
"-file-line-error",
"-bibtex",
"-xelatex",
"-outdir=%OUTDIR%",
"%DOCFILE%"
],
"env": {}
},
{
"name": "latexmk",
"command": "latexmk",
"args": [
"-synctex=1",
"-interaction=nonstopmode",
"-file-line-error",
"-pdf",
"-outdir=%OUTDIR%",
"%DOCFILE%"
],
"env": {}
},
{
"name": "lualatexmk",
"command": "latexmk",
"args": [
"-synctex=1",
"-interaction=nonstopmode",
"-file-line-error",
"-lualatex",
"-outdir=%OUTDIR%",
"%DOCFILE%"
],
"env": {}
},
{
"name": "latexmk_rconly",
"command": "latexmk",
"args": ["%DOCFILE%"],
"env": {}
},
{
"name": "pdflatex",
"command": "pdflatex",
"args": [
"-synctex=1",
"-interaction=nonstopmode",
"-file-line-error",
"%DODOCFILEC%"
],
"env": {}
},
{
"name": "bibtex",
"command": "bibtex",
"args": ["%DOCFILE%"],
"env": {}
},
{
"name": "rnw2tex",
"command": "Rscript",
"args": [
"-e",
"knitr::opts_knit$set(concordance = TRUE); knitr::knit('%DOCFILE_EXT%')"
],
"env": {}
},
{
"name": "jnw2tex",
"command": "julia",
"args": ["-e", "using Weave; weave(\"%DOC_EXT%\", doctype=\"tex\")"],
"env": {}
},
{
"name": "jnw2texmintex",
"command": "julia",
"args": [
"-e",
"using Weave; weave(\"%DOC_EXT%\", doctype=\"texminted\")"
],
"env": {}
},
{
"name": "tectonic",
"command": "tectonic",
"args": ["--synctex", "--keep-logs", "%DOC%.tex"],
"env": {}
}
],
"latex-workshop.latex.recipes": [
{
"name": "xelatex",
"tools": ["xelatex"]
},
{
"name": "latexmk 🔃",
"tools": ["latexmk"]
},
{
"name": "latexmk (xelatex)",
"tools": ["latexmk (xelatex)"]
},
{
"name": "latexmk (xelatex) with bibtex",
"tools": ["latexmk (xelatex) with bibtex"]
},
{
"name": "latexmk (latexmkrc)",
"tools": ["latexmk_rconly"]
},
{
"name": "latexmk (lualatex)",
"tools": ["lualatexmk"]
},
{
"name": "pdflatex ➞ bibtex ➞ pdflatex × 2",
"tools": ["pdflatex", "bibtex", "pdflatex", "pdflatex"]
},
{
"name": "Compile Rnw files",
"tools": ["rnw2tex", "latexmk"]
},
{
"name": "Compile Jnw files",
"tools": ["jnw2tex", "latexmk"]
},
{
"name": "tectonic",
"tools": ["tectonic"]
}
],
// matlab
"matlab.matlabpath": "C:/Program Files/Polyspace/R2021a/bin/win64/matlab.exe",
"matlab.mlintpath": "C:/Program Files/Polyspace/R2021a/bin/win64/mlint.exe"
"matlab.mlintpath": "C:/Program Files/Polyspace/R2021a/bin/win64/mlint.exe",
"jest.autoRun": {
"watch": false,
"onSave": "test-src-file"
}
}
```
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册