将 UI 层的通用功能封装成基类和扩展函数,统一处理公共逻辑,业务层只需简单调用,减少重复代码。
BaseActivity - 基础 Activity 类(已存在)BaseFragment - 基础 Fragment 类(已存在)ActivityExtensions - Activity 扩展函数(已存在)FragmentExtensions - Fragment 扩展函数(已存在)base-common/src/main/java/com/narutohuo/xindazhou/common/
└── ui/ # UI 层封装
├── BaseActivity.kt # 基础 Activity 类
├── BaseFragment.kt # 基础 Fragment 类
├── ActivityExtensions.kt # Activity 扩展函数
└── FragmentExtensions.kt # Fragment 扩展函数
职责:封装 Activity 通用 UI 功能
功能:
showLoading() / hideLoading()showError() / showSuccess()initView() 和 initObserver()executeRequest() 方法(可选,简单场景使用)使用方式:
class LoginActivity : BaseActivity<ActivityLoginBinding>() {
private val viewModel: LoginViewModel by viewModels()
override fun getViewBinding(): ActivityLoginBinding {
return ActivityLoginBinding.inflate(layoutInflater)
}
override fun initView() {
binding.btnLogin.setOnClickListener {
viewModel.login(mobile, password)
}
}
override fun initObserver() {
observeStateFlow(viewModel.loginState) { state ->
when (state) {
is LoginState.Loading -> showLoading()
is LoginState.Success -> {
hideLoading()
showSuccess(state.message)
}
is LoginState.Error -> {
hideLoading()
showError(state.message)
}
}
}
}
}
职责:封装 Fragment 通用 UI 功能
功能:
showLoading() / hideLoading()showError() / showSuccess()initView() 和 initObserver()executeRequest() 方法(可选,简单场景使用)使用方式:
class LoginFragment : BaseFragment<FragmentLoginBinding>() {
private val viewModel: LoginViewModel by viewModels()
override fun getViewBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentLoginBinding {
return FragmentLoginBinding.inflate(inflater, container, false)
}
override fun initView() {
binding.btnLogin.setOnClickListener {
viewModel.login(mobile, password)
}
}
override fun initObserver() {
observeStateFlow(viewModel.loginState) { state ->
when (state) {
is LoginState.Loading -> showLoading()
is LoginState.Success -> {
hideLoading()
showSuccess(state.message)
}
is LoginState.Error -> {
hideLoading()
showError(state.message)
}
}
}
}
}
职责:提供便捷的扩展函数,简化业务层代码
功能:
observeStateFlow() 简化状态观察使用方式:
// 之前:繁琐
override fun initObserver() {
lifecycleScope.launch {
viewModel.loginState.collect { state ->
when (state) { ... }
}
}
}
// 现在:简洁
override fun initObserver() {
observeStateFlow(viewModel.loginState) { state ->
when (state) { ... }
}
}
职责:提供便捷的扩展函数,简化业务层代码
功能:
observeStateFlow() 简化状态观察使用方式:同 ActivityExtensions
用户操作(点击按钮)
↓
Activity/Fragment(UI 层)
↓ 调用
ViewModel(业务逻辑层)
↓ 调用
Repository(数据管理层)
↓ 调用
RemoteDataSource(网络请求层)
↓ 返回数据
Repository
↓ 返回数据
ViewModel(更新 UI 状态)
↓ 状态变化
Activity/Fragment(观察状态,调用 BaseActivity 方法更新 UI)
// LoginViewModel.kt
class LoginViewModel(
application: Application,
private val repository: AuthRepository
) : AndroidViewModel(application) {
private val _loginState = MutableStateFlow<LoginState>(LoginState.Idle)
val loginState: StateFlow<LoginState> = _loginState
fun login(mobile: String, password: String) {
viewModelScope.launch {
_loginState.value = LoginState.Loading
repository.login(mobile, password)
.onSuccess {
_loginState.value = LoginState.Success("登录成功")
}
.onFailure { e ->
_loginState.value = LoginState.Error(e.message ?: "登录失败")
}
}
}
}
// LoginActivity.kt
class LoginActivity : BaseActivity<ActivityLoginBinding>() {
private val viewModel: LoginViewModel by viewModels()
override fun getViewBinding(): ActivityLoginBinding {
return ActivityLoginBinding.inflate(layoutInflater)
}
override fun initView() {
binding.btnLogin.setOnClickListener {
val mobile = binding.etMobile.text.toString()
val password = binding.etPassword.text.toString()
viewModel.login(mobile, password) // 触发 ViewModel
}
}
override fun initObserver() {
// 使用扩展函数观察状态
observeStateFlow(viewModel.loginState) { state ->
when (state) {
is LoginState.Loading -> showLoading() // BaseActivity 提供
is LoginState.Success -> {
hideLoading()
showSuccess(state.message) // BaseActivity 提供
// 跳转到主页
}
is LoginState.Error -> {
hideLoading()
showError(state.message) // BaseActivity 提供
}
}
}
}
}
自动处理:
BaseActivity 自动初始化 bindingBaseFragment 自动初始化 bindinggetViewBinding() 方法优势:
findViewById方法:
showLoading() - 显示加载提示(子类可重写自定义 UI)hideLoading() - 隐藏加载提示(子类可重写自定义 UI)使用场景:
方法:
showError(message: String) - 显示错误提示(默认 Toast,子类可重写)showSuccess(message: String) - 显示成功提示(默认 Toast,子类可重写)使用场景:
方法:
observeStateFlow(stateFlow, action) - 观察 StateFlow 状态变化优势:
lifecycleScope.launch { flow.collect { } }方法:
executeRequest(request, onSuccess, onError, showLoading) - 统一执行网络请求使用场景:
注意:
class LoginActivity : BaseActivity<ActivityLoginBinding>() {
private val viewModel: LoginViewModel by viewModels()
override fun getViewBinding(): ActivityLoginBinding {
return ActivityLoginBinding.inflate(layoutInflater)
}
override fun initView() {
binding.btnLogin.setOnClickListener {
viewModel.login(mobile, password)
}
}
override fun initObserver() {
observeStateFlow(viewModel.loginState) { state ->
when (state) {
is LoginState.Loading -> showLoading()
is LoginState.Success -> {
hideLoading()
showSuccess(state.message)
}
is LoginState.Error -> {
hideLoading()
showError(state.message)
}
}
}
}
}
class LoginActivity : BaseActivity<ActivityLoginBinding>() {
private val repository = AuthRepository()
override fun initView() {
binding.btnLogin.setOnClickListener {
executeRequest(
request = { repository.login(mobile, password) },
onSuccess = { response ->
showSuccess("登录成功")
// 处理成功逻辑
}
)
}
}
}
class LoginActivity : BaseActivity<ActivityLoginBinding>() {
// 自定义加载 UI
override fun showLoading() {
binding.progressBar.visibility = View.VISIBLE
binding.btnLogin.isEnabled = false
}
override fun hideLoading() {
binding.progressBar.visibility = View.GONE
binding.btnLogin.isEnabled = true
}
// 自定义错误提示(使用 Dialog 而不是 Toast)
override fun showError(message: String) {
AlertDialog.Builder(this)
.setTitle("错误")
.setMessage(message)
.setPositiveButton("确定", null)
.show()
}
}
之前:
class LoginActivity : AppCompatActivity() {
private lateinit var binding: ActivityLoginBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityLoginBinding.inflate(layoutInflater)
setContentView(binding.root)
// 初始化视图
binding.btnLogin.setOnClickListener { ... }
// 观察状态
lifecycleScope.launch {
viewModel.loginState.collect { state ->
when (state) {
is LoginState.Loading -> {
// 显示加载
binding.progressBar.visibility = View.VISIBLE
}
is LoginState.Success -> {
// 隐藏加载
binding.progressBar.visibility = View.GONE
Toast.makeText(this@LoginActivity, state.message, Toast.LENGTH_SHORT).show()
}
is LoginState.Error -> {
// 隐藏加载
binding.progressBar.visibility = View.GONE
Toast.makeText(this@LoginActivity, state.message, Toast.LENGTH_SHORT).show()
}
}
}
}
}
}
现在:
class LoginActivity : BaseActivity<ActivityLoginBinding>() {
override fun getViewBinding() = ActivityLoginBinding.inflate(layoutInflater)
override fun initView() {
binding.btnLogin.setOnClickListener { ... }
}
override fun initObserver() {
observeStateFlow(viewModel.loginState) { state ->
when (state) {
is LoginState.Loading -> showLoading()
is LoginState.Success -> { hideLoading(); showSuccess(state.message) }
is LoginState.Error -> { hideLoading(); showError(state.message) }
}
}
}
}
代码减少:约 60%+
getViewBinding() - 必须实现,返回 ViewBinding 实例initView() - 初始化视图(可选)initObserver() - 初始化观察者(可选)showLoading() / hideLoading() - 自定义加载 UI(可选)showError() / showSuccess() - 自定义提示 UI(可选)observeStateFlow() 扩展函数executeRequest() 方法executeRequest() 方法UI 层(View)
├── BaseActivity / BaseFragment # UI 基类
│ ├── ViewBinding 支持
│ ├── 加载状态管理
│ ├── 错误提示
│ ├── 生命周期管理
│ └── executeRequest() 便捷方法(可选)
│
├── ActivityExtensions / FragmentExtensions # 扩展函数
│ └── observeStateFlow() 简化状态观察
│
└── Activity / Fragment # 业务 UI 组件
└── 继承 BaseActivity / BaseFragment
业务逻辑层(ViewModel)
└── ViewModel # 处理业务逻辑
└── 使用 Repository
数据层(Data)
├── Repository # 数据仓库
│ └── 继承 ApiBaseRepository
│
└── RemoteDataSource # 远程数据源
└── 继承 ApiBaseRemoteDataSource