BaseActivity 和 BaseFragment 实现,集成了 View Binding,并增加了对 Lifecycle 和 ViewModel 的支持,同时进一步简化了代码结构,使其更易用、更灵活。
- 启用 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,并享受其带来的便利和安全性!