杰瑞科技汇

Android实例教程,如何快速上手?

目录

  1. 准备工作:搭建开发环境
    • 安装 Android Studio
    • 创建第一个项目
  2. Hello World - 你的第一个 Android 应用
    • 运行项目
    • 理解项目结构
    • 修改欢迎文字
  3. 用户交互 - 创建一个简单的计算器
    • 设计界面 (XML 布局)
    • 编写逻辑 (Kotlin/Java 代码)
    • 处理按钮点击事件
  4. 数据存储 - 创建一个“待办事项”应用
    • 使用 RecyclerView 显示列表
    • 使用 EditTextButton 添加新任务
    • 使用 Room 数据库持久化存储数据
  5. 进阶学习路径
    • 推荐资源
    • 下一步该学什么

准备工作:搭建开发环境

在开始之前,你需要安装官方的集成开发环境。

Android实例教程,如何快速上手?-图1
(图片来源网络,侵删)

安装 Android Studio

  1. 下载:访问 Android Developers 官网 下载适用于你操作系统的 Android Studio。
  2. 安装:像安装普通软件一样完成安装,安装过程中,它会自动下载所需的 Android SDK(软件开发工具包)和模拟器系统镜像,这可能需要一些时间,请耐心等待。
  3. 启动与配置:首次启动 Android Studio,它会引导你进行一些基本配置,比如导入设置、安装 SDK 组件等,按照提示一步步操作即可。

创建第一个项目

  1. 启动 Android Studio,点击 "New Project"
  2. 选择模板,对于初学者,推荐选择 "Empty Views Activity",它提供了一个最简洁的起点。
  3. 配置你的项目:
    • Name: 你的应用名称,"MyFirstApp"。
    • Package name: 应用的唯一标识符,通常用反向域名格式,com.example.myfirstapp
    • Save location: 项目保存的路径。
    • Language: 选择 Kotlin(现代、官方推荐)或 Java(传统,但依然广泛使用),本教程将以 Kotlin 为主。
    • Minimum SDK: 选择你的应用支持的最低 Android 版本,建议选择 API 24 或更高,以覆盖绝大多数设备。
  4. 点击 "Finish",Android Studio 会开始构建项目,同样需要一些时间。

实例一:Hello World - 你的第一个 Android 应用

你已经有了一个可以运行的项目,让我们来运行它,并稍微修改一下。

运行项目

  1. 在 Android Studio 顶部工具栏中,选择一个模拟器设备(如果没有,可以点击 "Create Device..." 创建一个)。
  2. 点击绿色的 "Run" 按钮(一个三角形图标)。
  3. 稍等片刻,模拟器会启动并显示你的应用,你应该能看到一个显示 "Hello World!" 的界面。

理解项目结构

在左侧的 Project 面板中,切换到 "Android" 视图,你会看到几个关键文件夹:

  • app/: 应用的主要代码和资源所在。
    • manifests/: AndroidManifest.xml 文件,是应用的“清单”,定义了应用的基本信息,如包名、权限、入口 Activity 等。
    • java/: 存放你的 Kotlin 或 Java 代码。com.example.myfirstapp 包下是你的主 Activity 文件,MainActivity.kt,Activity 是一个屏幕界面。
    • res/: (resources) 存放所有非代码资源。
      • layout/: 存放 XML 文件,用于定义 UI 布局。activity_main.xml MainActivity 对应的布局文件。
      • mipmap-xxx/: 存放应用图标。
      • values/: 存放字符串、颜色、样式等常量。strings.xml 定义了应用中使用的文本。

修改欢迎文字

这是你第一次修改应用的 UI。

  1. 打开 res/layout/activity_main.xml 文件,你会看到默认的代码视图。
  2. 切换到 "Split""Design" 视图,这样可以更直观地看到界面。
  3. 在中间的预览区域,找到显示 "Hello World!" 的 TextView
  4. 在右侧的 Attributes(属性)面板中,找到 text 属性。
  5. 点击它,或者直接双击布局文件中的 android:text="Hello World!"
  6. 将其修改为 android:text="你好,Android!"
  7. 重新运行应用(点击 Run 按钮),你会看到模拟器上的文字已经改变了。

恭喜!你已经成功修改了应用的界面。

Android实例教程,如何快速上手?-图2
(图片来源网络,侵删)

实例二:用户交互 - 创建一个简单的计算器

这个实例将教你如何创建 UI 布局,并通过 Kotlin 代码响应用户操作。

目标

创建一个简单的计算器,可以输入两个数字,点击加法按钮后显示结果。

步骤 1:设计界面 (activity_main.xml)

打开 res/layout/activity_main.xml,使用 Design 视图或直接编写代码来创建以下布局:

  • 两个 EditText 用于输入数字。
  • 一个 Button 用于触发计算。
  • 一个 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:gravity="center"
    android:padding="16dp"
    tools:context=".MainActivity">
    <EditText
        android:id="@+id/number1EditText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="输入第一个数字"
        android:inputType="number" />
    <EditText
        android:id="@+id/number2EditText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:hint="输入第二个数字"
        android:inputType="number" />
    <Button
        android:id="@+id/calculateButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="计算" />
    <TextView
        android:id="@+id/resultTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="结果将显示在这里"
        android:textSize="18sp" />
</LinearLayout>

关键点

  • LinearLayout: 一种线性布局,orientation="vertical" 表示垂直排列子元素。
  • android:id: 为每个视图分配一个唯一的 ID,方便在代码中引用它。@+id/... 表示这是一个新 ID。
  • android:hint: 当 EditText 为空时显示的提示文本。
  • android:inputType="number": 限制输入框只能输入数字。

步骤 2:编写逻辑 (MainActivity.kt)

现在打开 app/java/com.example.myfirstapp/MainActivity.kt,添加代码来处理点击事件。

package com.example.myfirstapp
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
class MainActivity : AppCompatActivity() {
    // 1. 声明视图变量
    private lateinit var number1EditText: EditText
    private lateinit var number2EditText: EditText
    private lateinit var calculateButton: Button
    private lateinit var resultTextView: TextView
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main) // 关联布局文件
        // 2. 通过 ID 找到视图并赋值给变量
        number1EditText = findViewById(R.id.number1EditText)
        number2EditText = findViewById(R.id.number2EditText)
        calculateButton = findViewById(R.id.calculateButton)
        resultTextView = findViewById(R.id.resultTextView)
        // 3. 为按钮设置点击事件监听器
        calculateButton.setOnClickListener {
            // 在这里编写点击后要执行的代码
            calculateSum()
        }
    }
    // 4. 创建一个计算方法
    private fun calculateSum() {
        // 获取两个输入框的文本
        val num1Str = number1EditText.text.toString()
        val num2Str = number2EditText.text.toString()
        // 检查输入是否为空
        if (num1Str.isEmpty() || num2Str.isEmpty()) {
            // 如果为空,显示一个提示
            Toast.makeText(this, "请输入数字!", Toast.LENGTH_SHORT).show()
            return
        }
        // 将字符串转换为数字
        val num1 = num1Str.toDouble()
        val num2 = num2Str.toDouble()
        // 计算和
        val sum = num1 + num2
        // 将结果显示在 TextView 上
        resultTextView.text = "计算结果是: $sum"
    }
}

代码解释

  1. lateinit var: 声明一个非空的变量,但稍后再初始化,这是在 onCreate 中通过 findViewById 初始化它们的常用方式。
  2. findViewById(R.id.xxx): 通过在 XML 中定义的 ID 来获取对应的视图对象。
  3. setOnClickListener: 为按钮设置一个监听器,当用户点击按钮时,大括号 中的代码块就会被执行。
  4. calculateSum(): 我们把核心计算逻辑放在一个单独的函数里,让代码更清晰。
  5. text.toString(): 从 EditText 获取的是 Editable 对象,需要转换成 String
  6. Toast.makeText(...).show(): 显示一个临时的、悬浮在屏幕上的提示信息,非常适合用于反馈。

运行测试

运行应用,你应该能看到一个功能完整的计算器界面了!


实例三:数据存储 - 创建一个“待办事项”应用

这个实例将教你如何使用列表显示数据,并使用数据库将数据永久保存下来。

目标

创建一个可以添加、显示待办事项的应用,并且关闭应用后重新打开,数据依然存在。

步骤 1:添加依赖 (Room 数据库)

Room 是 Google 官方推荐的一个 ORM(对象关系映射)库,可以让你更轻松地操作 SQLite 数据库。

  1. 打开 app/build.gradle.kts (或 app/build.gradle) 文件。
  2. dependencies 代码块中添加以下依赖:
// Room
def room_version = "2.6.1"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
// Kotlin Extensions and Coroutines support for Room
implementation "androidx.room:room-ktx:$room_version"
// Coroutines (用于异步操作数据库)
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'

注意:如果你使用的是 build.gradle (非 KTS DSL),依赖语法略有不同,确保在文件顶部有 apply plugin: 'kotlin-kapt'

  1. 点击 Android Studio 顶部出现的 "Sync Now" 按钮同步项目。

步骤 2:创建数据实体

创建一个 Kotlin 数据类,它代表了数据库中的一张表。

  1. app/java/com.example.myfirstapp 包下,右键 -> New -> Kotlin Class/File。
  2. 选择 "Data Class",命名为 Todo.kt
  3. 添加以下代码:
package com.example.myfirstapp
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "todos") // @Entity 表示这是一个数据库表
data class Todo(
    @PrimaryKey(autoGenerate = true) val id: Int = 0, // 主键,自动增长
    val text: String // 待办事项的文本内容
)

步骤 3:创建 DAO (Data Access Object)

DAO 是一个接口,定义了如何查询、插入、更新和删除数据库中的数据。

  1. 在同一个包下,创建一个新的 "Interface",命名为 TodoDao.kt
  2. 添加以下代码:
package com.example.myfirstapp
import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
@Dao // @Dao 表示这是一个数据访问对象
interface TodoDao {
    // @Insert 表示这是一个插入方法
    // onConflict = OnConflictStrategy.REPLACE 表示如果主键冲突,则替换旧数据
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insert(todo: Todo)
    // @Query 表示这是一个查询方法
    // "SELECT * FROM todos" 是标准的 SQL 查询语句
    // LiveData 表示查询结果是可观察的,当数据变化时,UI 会自动更新
    @Query("SELECT * FROM todos ORDER BY id DESC")
    fun getAllTodos(): LiveData<List<Todo>>
}

步骤 4:创建数据库

创建一个抽象类,作为数据库的入口点,并将实体和 DAO 关联起来。

  1. 在同一个包下,创建一个新的 "Abstract Class",命名为 AppDatabase.kt
  2. 添加以下代码:
package com.example.myfirstapp
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
@Database(entities = [Todo::class], version = 1, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
    abstract fun todoDao(): TodoDao
    companion object {
        @Volatile
        private var INSTANCE: AppDatabase? = null
        fun getDatabase(context: Context): AppDatabase {
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    AppDatabase::class.java,
                    "todo_database"
                ).build()
                INSTANCE = instance
                instance
            }
        }
    }
}

步骤 5:修改布局 (activity_main.xml)

我们需要一个 RecyclerView 来显示列表,以及一个 EditTextButton 来添加新任务。

<?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=".MainActivity">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:gravity="center_vertical"
        android:padding="8dp">
        <EditText
            android:id="@+id/todoEditText"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:hint="输入新任务..." />
        <Button
            android:id="@+id/addButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="添加" />
    </LinearLayout>
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="8dp" />
</LinearLayout>

步骤 6:创建列表项布局

创建一个 XML 文件来定义列表中每一项的样式。

  1. res/layout 目录下,右键 -> New -> Layout Resource File。
  2. 文件名命名为 item_todo.xml
  3. 设计一个简单的布局,
<?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="wrap_content"
    android:orientation="vertical"
    android:padding="16dp">
    <TextView
        android:id="@+id/todoTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="18sp" />
</LinearLayout>

步骤 7:创建适配器

适配器是连接 RecyclerView 和数据源的桥梁。

  1. 在包下,创建一个新的 "Class",命名为 TodoAdapter.kt
  2. 添加以下代码:
package com.example.myfirstapp
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class TodoAdapter(private val todos: List<Todo>) : RecyclerView.Adapter<TodoAdapter.TodoViewHolder>() {
    //ViewHolder 持有列表项的视图
    class TodoViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val todoTextView: TextView = itemView.findViewById(R.id.todoTextView)
    }
    // 创建新的 ViewHolder
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TodoViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_todo, parent, false)
        return TodoViewHolder(view)
    }
    // 绑定数据到 ViewHolder
    override fun onBindViewHolder(holder: TodoViewHolder, position: Int) {
        val todo = todos[position]
        holder.todoTextView.text = todo.text
    }
    // 返回数据总数
    override fun getItemCount() = todos.size
}

步骤 8:修改 MainActivity.kt 整合所有功能

这是最复杂的一步,我们将把所有组件连接起来。

package com.example.myfirstapp
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import androidx.activity.viewModels
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
class MainActivity : AppCompatActivity() {
    private lateinit var todoEditText: EditText
    private lateinit var addButton: Button
    private lateinit var recyclerView: RecyclerView
    // 使用 ViewModel 来管理 UI 相关的数据
    private val todoViewModel: TodoViewModel by viewModels()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // 初始化视图
        todoEditText = findViewById(R.id.todoEditText)
        addButton = findViewById(R.id.addButton)
        recyclerView = findViewById(R.id.recyclerView)
        // 设置 RecyclerView
        val adapter = TodoAdapter(emptyList()) // 先用空列表初始化
        recyclerView.adapter = adapter
        recyclerView.layoutManager = LinearLayoutManager(this)
        // 观察数据库中的数据变化
        todoViewModel.allTodos.observe(this, Observer { todos ->
            // 当数据变化时,更新适配器
            todos?.let { adapter.updateData(it) }
        })
        // 设置添加按钮的点击事件
        addButton.setOnClickListener {
            val todoText = todoEditText.text.toString()
            if (todoText.isNotEmpty()) {
                val todo = Todo(text = todoText)
                // 在后台线程插入数据
                todoViewModel.insert(todo)
                todoEditText.text.clear() // 清空输入框
            }
        }
    }
}

步骤 9:创建 ViewModel

ViewModel 用于保存和管理与 UI 相关的数据,以便在配置更改(如屏幕旋转)时数据不会丢失。

  1. 在包下,创建一个新的 "Class",继承自 AndroidViewModel,命名为 TodoViewModel.kt
  2. 添加以下代码:
package com.example.myfirstapp
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
class TodoViewModel(application: Application) : AndroidViewModel(application) {
    private val todoDao: TodoDao
    val allTodos: LiveData<List<Todo>>
    init {
        val database = AppDatabase.getDatabase(application)
        todoDao = database.todoDao()
        allTodos = todoDao.getAllTodos()
    }
    fun insert(todo: Todo) {
        viewModelScope.launch {
            todoDao.insert(todo)
        }
    }
}

步骤 10:修改适配器以支持数据更新

为了让 TodoAdapter 能够接收新数据,我们需要添加一个 updateData 方法。

打开 TodoAdapter.kt,在类中添加:

// 在 TodoAdapter 类中添加这个方法
fun updateData(newTodos: List<Todo>) {
    // 这里为了简化,我们直接创建一个新的适配器实例
    // 在实际项目中,可以使用 DiffUtil 来高效地更新列表
    // 这是一个简单的演示
    this.todos = newTodos
    notifyDataSetChanged()
}

注意:上面的 updateData 方法比较简单,在生产环境中,推荐使用 ListAdapterAsyncPagingDataListAdapter 配合 DiffUtil,它们能更高效地处理列表更新。

最后一步:在 AndroidManifest.xml 中添加 android:exported="true"

为了让其他应用可以启动你的 Activity(在从通知等地方启动时可能需要),或者在较新的 Android 版本上避免一些警告,打开 app/manifests/AndroidManifest.xml,找到 <activity> 标签,添加 android:exported="true" 属性。

<activity
    android:name=".MainActivity"
    android:exported="true">  <!-- 添加这一行 -->
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

运行测试

运行你的应用!你应该可以:

  1. 在输入框中输入文字,点击“添加”按钮。
  2. 新的任务会立即出现在下方的列表中。
  3. 关闭应用,然后重新打开,你会发现之前添加的任务依然存在!

恭喜!你已经掌握了 Android 开发中最核心的几个概念:UI 布局、用户交互、数据列表和本地数据持久化。


进阶学习路径

恭喜你完成了这三个实例!你已经具备了坚实的基础,你可以探索以下方向来提升自己:

  • 导航组件: 学习使用 Jetpack Navigation 来管理多个页面之间的跳转和返回栈,让应用导航更流畅。
  • 生命周期和作用域: 深入理解 Activity/Fragment 的生命周期,以及 Kotlin 的 lifecycleScopeviewModelScope 如何帮助你管理后台任务,避免内存泄漏。
  • 依赖注入: 学习使用 Hilt 或 Koin 等框架来管理对象的生命周期和依赖关系,让代码更易于测试和维护。
  • 网络请求: 使用 Retrofit 和 OkHttp 库从网络获取数据(从 API 获取新闻)。
  • 图片加载: 使用 Glide 或 Coil 库高效地加载和显示网络图片。
  • 工作管理器: 学习使用 WorkManager 来安排需要在后台执行的任务,即使应用关闭或重启,任务也能可靠执行。
  • Material Design 3: 学习使用 Google 的 Material Design 设计语言,让你的应用看起来更现代、更美观。

推荐资源

  • 官方文档: developer.android.com 是最权威、最准确的资料。
  • Android Codelabs: Google 提供的一系列动手编码教程,质量很高。
  • GitHub: 查看优秀的开源项目,学习别人的代码风格和架构。
  • 技术博客: 遵循一些知名的 Android 开发者或团队的博客。

持续学习和实践是成为优秀开发者的关键,祝你学习愉快!

分享:
扫描分享到社交APP
上一篇
下一篇