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@CallSuperprotected 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() {// 默認空實現,子類可按需重寫}@Overrideprotected 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@CallSuperpublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {_binding = createViewBinding(inflater, container);return _binding.getRoot();}@Override@CallSuperpublic 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() {// 默認空實現,子類可按需重寫}@Overridepublic void onDestroyView() {super.onDestroyView();// 清理 binding 引用,避免內存泄漏_binding = null;}
}
4. 使用示例
MainActivity
public class MainActivity extends BaseActivity<ActivityMainBinding, MainViewModel> {@Overrideprotected ActivityMainBinding createViewBinding() {return ActivityMainBinding.inflate(getLayoutInflater());}@Overrideprotected Class<MainViewModel> getViewModelClass() {return MainViewModel.class;}@Overrideprotected void setupViews() {// 使用 binding 訪問視圖getBinding().textView.setText("Hello, Optimized View Binding!");// 使用 ViewModel 數據getViewModel().getLiveData().observe(this, data -> {// 更新 UI});}@Overrideprotected void observeData() {// 觀察數據變化(可選)}
}
HomeFragment
public class HomeFragment extends BaseFragment<FragmentHomeBinding, HomeViewModel> {@Overrideprotected FragmentHomeBinding createViewBinding(@NonNull LayoutInflater inflater, @Nullable ViewGroup container) {return FragmentHomeBinding.inflate(inflater, container, false);}@Overrideprotected Class<HomeViewModel> getViewModelClass() {return HomeViewModel.class;}@Overrideprotected void setupViews() {// 使用 binding 訪問視圖getBinding().button.setOnClickListener(v -> {// 處理點擊事件});// 使用 ViewModel 數據getViewModel().getLiveData().observe(getViewLifecycleOwner(), data -> {// 更新 UI});}@Overrideprotected 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,并享受其帶來的便利和安全性!