当前位置: 首页 > news >正文

BaseActivity 和 BaseFragment 的现代化架构:ViewBinding 与 ViewModel 的深度整合

BaseActivity 和 BaseFragment 实现,集成了 View Binding,并增加了对 Lifecycle 和 ViewModel 的支持,同时进一步简化了代码结构,使其更易用、更灵活。

  1. 启用 View Binding
    确保在 build.gradle 中启用了 View Binding
android {
    ...
    viewBinding {
        enabled = true
    }
}

2. BaseActivity

import android.os.Bundle;
import androidx.annotation.CallSuper;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import androidx.viewbinding.ViewBinding;

public abstract class BaseActivity<VB extends ViewBinding, VM extends ViewModel> extends AppCompatActivity {

    private VB _binding;
    private VM _viewModel;

    // 提供 binding 的 getter 方法
    protected VB getBinding() {
        return _binding;
    }

    // 提供 ViewModel 的 getter 方法
    protected VM getViewModel() {
        return _viewModel;
    }

    @Override
    @CallSuper
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        _binding = createViewBinding();
        setContentView(_binding.getRoot());

        // 初始化 ViewModel
        _viewModel = new ViewModelProvider(this).get(getViewModelClass());

        setupViews();
        observeData();
    }

    // 创建 ViewBinding 实例
    protected abstract VB createViewBinding();

    // 获取 ViewModel 的 Class 类型
    protected abstract Class<VM> getViewModelClass();

    // 初始化视图
    protected abstract void setupViews();

    // 观察数据(可选)
    protected void observeData() {
        // 默认空实现,子类可按需重写
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 清理 binding 引用,避免内存泄漏
        _binding = null;
    }
}

3. BaseFragment

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import androidx.viewbinding.ViewBinding;

public abstract class BaseFragment<VB extends ViewBinding, VM extends ViewModel> extends Fragment {

    private VB _binding;
    private VM _viewModel;

    // 提供 binding 的 getter 方法
    protected VB getBinding() {
        return _binding;
    }

    // 提供 ViewModel 的 getter 方法
    protected VM getViewModel() {
        return _viewModel;
    }

    @Nullable
    @Override
    @CallSuper
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        _binding = createViewBinding(inflater, container);
        return _binding.getRoot();
    }

    @Override
    @CallSuper
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        // 初始化 ViewModel
        _viewModel = new ViewModelProvider(this).get(getViewModelClass());

        setupViews();
        observeData();
    }

    // 创建 ViewBinding 实例
    protected abstract VB createViewBinding(@NonNull LayoutInflater inflater, @Nullable ViewGroup container);

    // 获取 ViewModel 的 Class 类型
    protected abstract Class<VM> getViewModelClass();

    // 初始化视图
    protected abstract void setupViews();

    // 观察数据(可选)
    protected void observeData() {
        // 默认空实现,子类可按需重写
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        // 清理 binding 引用,避免内存泄漏
        _binding = null;
    }
}

4. 使用示例
MainActivity

public class MainActivity extends BaseActivity<ActivityMainBinding, MainViewModel> {

    @Override
    protected ActivityMainBinding createViewBinding() {
        return ActivityMainBinding.inflate(getLayoutInflater());
    }

    @Override
    protected Class<MainViewModel> getViewModelClass() {
        return MainViewModel.class;
    }

    @Override
    protected void setupViews() {
        // 使用 binding 访问视图
        getBinding().textView.setText("Hello, Optimized View Binding!");

        // 使用 ViewModel 数据
        getViewModel().getLiveData().observe(this, data -> {
            // 更新 UI
        });
    }

    @Override
    protected void observeData() {
        // 观察数据变化(可选)
    }
}

HomeFragment

public class HomeFragment extends BaseFragment<FragmentHomeBinding, HomeViewModel> {

    @Override
    protected FragmentHomeBinding createViewBinding(@NonNull LayoutInflater inflater, @Nullable ViewGroup container) {
        return FragmentHomeBinding.inflate(inflater, container, false);
    }

    @Override
    protected Class<HomeViewModel> getViewModelClass() {
        return HomeViewModel.class;
    }

    @Override
    protected void setupViews() {
        // 使用 binding 访问视图
        getBinding().button.setOnClickListener(v -> {
            // 处理点击事件
        });

        // 使用 ViewModel 数据
        getViewModel().getLiveData().observe(getViewLifecycleOwner(), data -> {
            // 更新 UI
        });
    }

    @Override
    protected void observeData() {
        // 观察数据变化(可选)
    }
}

5. 优化点说明
支持 ViewModel:

通过泛型参数 ,基类可以动态绑定具体的 ViewModel 类。

提供 getViewModelClass() 方法,子类只需返回 ViewModel 的 Class 类型即可。

observeData 方法

用于观察 ViewModel 中的数据变化(如 LiveData),子类可按需重写。

内存泄漏防护:

在 onDestroy(Activity)和 onDestroyView(Fragment)中清理 binding 引用,避免内存泄漏。

简化代码结构:

减少冗余代码,提高可读性和可维护性。

@CallSuper 注解:

确保子类在重写方法时调用 super,避免遗漏基类的关键逻辑。

6. 注意事项
确保布局文件的名称符合 View Binding 的命名规则(如 activity_main.xml 对应 ActivityMainBinding)。

如果某个布局不需要 Binding,可以在布局文件的根标签中添加 tools:viewBindingIgnore=“true”

通过这种方式,可以轻松在项目中集成 View Binding 和 ViewModel,并享受其带来的便利和安全性!

相关文章:

  • leetcode hot100特殊题型
  • 安装配置Anaconda
  • 前缀和算法第一弹(一维前缀和和二维前缀和)
  • c++图论(三)之图的遍历
  • 图解多头注意力机制:维度变化一镜到底
  • doris:安全概览
  • 【计算机视觉】工业表计读数(1)--基于关键点检测的读数识别方案
  • uboot源码结构
  • 树莓派 连接 PlutoSDR 教程
  • 给AI编程泼一盆冷水
  • 了解浏览器
  • [C语言]数据在内存中的存储
  • 二叉树的基本操作与实现:C语言深度剖析
  • Leetcode-回溯-子集型
  • 增量数据同步怎么做
  • Show、Hide和Setvisible的区别
  • 88.HarmonyOS NEXT 性能监控与调试指南:构建高性能应用
  • 神聖的綫性代數速成例題2. 行列式的性質
  • RAG数据嵌入和重排序:如何选择合适的模型
  • 软考系统架构师 — 3 操作系统
  • 滨江集团:一季度营收225.07亿元,净利润9.75亿元
  • 专访 | 杜普兰蒂斯:爱上中国文化,下一步努力提升速度
  • 辽宁辽阳火灾3名伤者无生命危险
  • 中国银行副行长刘进任该行党委副书记
  • 言短意长|政府食堂、停车场开放的示范效应
  • 杨国荣︱学术上的立此存照——《故旧往事,欲说还休》读后