本节摘要:UI(用户界面)是用户与应用交互的唯一桥梁,也是 Android 开发体系中"最先被看见、最先被评价"的部分。本节从用户与开发者双视角说明 UI 的分量,并立起贯穿全册的实战主线——一个"猜数字"小游戏界面,后续每一节都在它身上生长。
想象一位用户在应用商店下载了你的 App,打开之后:文字挤成一团、按钮小得点不中、在平板上布局散架。他不会去看你的代码写得多优雅,三十秒内卸载,顺手留个一星。这就是 UI 的现实:它不代表应用的全部质量,却决定用户愿不愿意给你展示其余质量的机会。
反过来对开发者,UI 也同样重要。Android 的四大组件、网络、数据库这些模块,最终几乎都要落到界面上呈现结果。学习顺序上先啃 UI,好处很直接:反馈即时——改一行 XML、点一下运行,模拟器立刻告诉你对不对。这种快速反馈环,是新手期最高效的学习方式。
Android 的界面技术虽然庞大,入门核心其实就四块,正好对应本册的章节安排:
| 知识块 | 回答的问题 | 对应章节 |
|---|---|---|
| 组件(Widgets) | 屏幕上有哪些现成的"零件"? | 第 3 章 |
| 布局(Layouts) | 零件按什么规则摆放? | 第 4 章 |
| 事件(Events) | 用户操作怎么传到代码? | 第 5 章 |
| 样式与主题(Style/Theme) | 外观如何统一、批量更换? | 第 6、7 章 |
四块拼起来,一个静态界面的全部要素就齐了。剩下的工具与调试(第 8 章)是保障手段。这不是我随口排的顺序——组件和布局互相离不开,事件依赖组件存在,样式则是前两者的批量修饰,环环相扣。
空讲概念容易飘,本册全程围绕一个"猜数字"小游戏展开。需求很简单:
麻雀虽小,五脏俱全:文本显示(TextView)、输入(EditText)、按钮(Button)、提示反馈(Toast/Snackbar)、对话框(AlertDialog)、次数记录(简单状态管理)、重新开局(列表展示历史记录,RecyclerView)——把第 3 到第 7 章的知识点全部串了起来。
先把它的骨架版界面搭出来。这是本章后续两节要逐行讲解的布局,先感受一下"一份 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:padding="24dp" android:gravity="center_horizontal"> <TextView android:id="@+id/tv_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="猜数字" android:textSize="28sp" /> <EditText android:id="@+id/et_guess" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="输入 1 到 100 之间的整数" android:inputType="number" /> <Button android:id="@+id/btn_guess" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="猜!" /> </LinearLayout>
不需要全部看懂。只注意三件事:整份文件是一层套一层的标签;每个控件有 android:id 这样的身份标记;文本、尺寸、方向都是属性写出来的。1.2 节解释"层层嵌套"意味着什么,1.3 节解释 id 如何被代码使用。
对应的游戏核心逻辑只需要十几行 Kotlin,也一并立在这里作为全册的参照物:
class MainActivity : AppCompatActivity() { private var answer = 0 // 本局答案 private var count = 0 // 已猜次数 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) restart() } private fun restart() { answer = Random.nextInt(1, 101) count = 0 } }
初学阶段有两个普遍的误区,值得先说破:
其一,"先把功能全写完再调界面"。实践中界面结构会反过来影响代码组织——控件分了组,状态管理才好拆。边搭边接,每一步都可运行,才是顺路。
其二,"UI 就是美工的事"。Android UI 开发的重心其实是结构:层级怎么设计、组件怎么选、事件怎么流动。配色只是最后一层皮,而结构是骨。骨不正,皮再好看也会在适配和扩展时崩掉。