命令式模型
View 系统里你持有视图对象、手动改它的属性。比 Compose 啰嗦但可控、调试直观,且大量存量代码与第三方库仍基于它。
SwiftUI 之下是 UIKit,同理 Compose 之下是 View 系统。懂底层,出问题能下钻;接入老 SDK、定制系统弹窗也离不开它。
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)
}
}Fragment
Fragment 是 Activity 内的可复用 UI 片段,有自己的生命周期,适合平板多窗格与导航组件。
class ListFragment : Fragment(R.layout.fragment_list) {
override fun onViewCreated(view: View, s: Bundle?) {
super.onViewCreated(view, s)
// 绑定视图、设置适配器
}
}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 返回可空、且易因 id 拼错运行时崩溃。ViewBinding 或 DataBinding 更安全。
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))
}事件处理
点击、长按、滑动通过监听器与手势检测器处理;复杂手势用 GestureDetector。
button.setOnClickListener { /* 点击 */ }
recyclerView.addOnItemTouchListener(...) // 自定义触摸与 Compose 互操作
在 View 中嵌入 Compose 用 ComposeView;在 Compose 中嵌入 View 用 AndroidView,渐进迁移。
// View 中放 Compose
composeView.setContent { MaterialTheme { Greeting("X") } }
// Compose 中放 View
AndroidView({ context -> TextView(context).apply { text = "old" } })常见陷阱
常因匿名内部类/协程持有 Activity 强引用。用 viewLifecycleOwner 或 viewModelScope 绑定正确生命周期,避免静态持有 Context。
默认会(旋转屏幕)。用 ViewModel 保存 UI 状态,避免重建时丢失;或在 manifest 配置 configChanges 自行处理(不推荐)。