Android 开发手册ANDROID DEV

CHAPTER 04原生 UI · IMPERATIVE

View
系统

命令式界面的工程基石:Activity/Fragment 生命周期、XML 布局、ViewBinding、RecyclerView 与事件处理。理解它,你才真正读懂 Compose 之下在发生什么。

开始阅读难度中级约3小时
04.1

命令式模型

View 系统里你持有视图对象、手动改它的属性。比 Compose 啰嗦但可控、调试直观,且大量存量代码与第三方库仍基于它。

为何还要学

SwiftUI 之下是 UIKit,同理 Compose 之下是 View 系统。懂底层,出问题能下钻;接入老 SDK、定制系统弹窗也离不开它。

04.2

Activity 生命周期

Activity 是屏幕级组件,生命周期回调清晰:onCreate → onStart → onResume → onPause → onStop → onDestroy。

回调时机用途
onCreate首次创建setContentView、初始化
onStart/onResume可见/可交互恢复数据、注册监听
onPause/onStop失焦/不可见暂停动画、注销监听
onDestroy销毁释放资源
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}
04.3

Fragment

Fragment 是 Activity 内的可复用 UI 片段,有自己的生命周期,适合平板多窗格与导航组件。

class ListFragment : Fragment(R.layout.fragment_list) {
    override fun onViewCreated(view: View, s: Bundle?) {
        super.onViewCreated(view, s)
        // 绑定视图、设置适配器
    }
}
04.4

XML 布局与 ViewBinding

布局写在 res/layout/*.xml;ViewBinding 在编译期为每个布局生成类型安全的绑定类,替代 findViewById。

private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)
    binding.title.text = "Hello"     // 类型安全、非空
}
避免 findViewById

findViewById 返回可空、且易因 id 拼错运行时崩溃。ViewBinding 或 DataBinding 更安全。

04.5

RecyclerView

高效列表靠 RecyclerView + Adapter + ViewHolder 复用视图,避免为每项创建新 View。

class UserAdapter : ListAdapter<User, UserViewHolder>(DIFF) {
    override fun onCreateViewHolder(p: ViewGroup, v: Int) =
        UserViewHolder(ItemUserBinding.inflate(inflater(p), p, false))
    override fun onBindViewHolder(h: UserViewHolder, i: Int) = h.bind(getItem(i))
}
04.6

事件处理

点击、长按、滑动通过监听器与手势检测器处理;复杂手势用 GestureDetector。

button.setOnClickListener { /* 点击 */ }
recyclerView.addOnItemTouchListener(...)   // 自定义触摸
04.7

与 Compose 互操作

在 View 中嵌入 Compose 用 ComposeView;在 Compose 中嵌入 View 用 AndroidView,渐进迁移。

// View 中放 Compose
composeView.setContent { MaterialTheme { Greeting("X") } }
// Compose 中放 View
AndroidView({ context -> TextView(context).apply { text = "old" } })
04.8

常见陷阱

为什么 onDestroy 后还内存泄漏?

常因匿名内部类/协程持有 Activity 强引用。用 viewLifecycleOwner 或 viewModelScope 绑定正确生命周期,避免静态持有 Context。

Configuration 变更会重建 Activity 吗?

默认会(旋转屏幕)。用 ViewModel 保存 UI 状态,避免重建时丢失;或在 manifest 配置 configChanges 自行处理(不推荐)。

04.9

实战练习

延伸资源