背景:mvvm + 组件化,很常见。但是组件化项目,采用 但是Activity + N Fragment这种形式我是第一次见,这样直接导致 navigtion 无法使用。Fragment 各种回退,替换混乱。项目后期绝对天崩。但是谁让咱是老实本分的乙方啊,甲方爸爸要求,捏着鼻子也要上。
1、抽离 封装 FragmentTransaction 工具类
由于MainActivity在独立模块,容器在 MainActivity上 所以我就要提供一个各个模块都可以
单利 + 容器提供
AppFragmentManagerProvider
public class AppFragmentManagerProvider {
private static FragmentManager fragmentManager;
private static int containerId;
// 私有构造函数,防止实例化
private AppFragmentManagerProvider() {}
// 初始化FragmentManager和containerId
public static void init(FragmentManager fm, int cid) {
fragmentManager = fm;
containerId = cid;
}
public static FragmentManager getFragmentManager() {
if (fragmentManager == null) {
throw new IllegalStateException("FragmentManager is not initialized");
}
return fragmentManager;
}
public static int getContainerId() {
if (containerId == 0) {
throw new IllegalStateException("Container ID is not initialized");
}
return containerId;
}
}
提供 布局容器 和 FragmentManager管理,在MainAcitvity 初始化。
FragmentController
public class FragmentController {
private static volatile FragmentController instance;
private FragmentManager fragmentManager;
private int containerId;
private FragmentTransactionCallback callback;
// 设置回调监听器
public void setFragmentTransactionCallback(FragmentTransactionCallback callback) {
this.callback = callback;
}
// 私有构造函数,防止外部实例化
private FragmentController(FragmentManager fragmentManager, int containerId) {
this.fragmentManager = fragmentManager;
this.containerId = containerId;
}
// 公共静态方法,提供全局访问点
public static FragmentController getInstance(FragmentManager fragmentManager, int containerId) {
if (instance == null) {
synchronized (FragmentController.class) {
if (instance == null) {
instance = new FragmentController(fragmentManager, containerId);
}
}
}
return instance;
}
// 添加Fragment
public void addFragment(Fragment fragment, String tag) {
String currentFragmentTag = getCurrentFragmentTag();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(containerId, fragment, tag);
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
transaction.addToBackStack(tag);
transaction.commit();
if (callback != null) {
if (StringUtils.isEmpty(currentFragmentTag)){
currentFragmentTag = "HomeFg";
}
callback.onFragmentAdded(currentFragmentTag, tag);
}
}
// 替换Fragment
public void replaceFragment(Fragment fragment, String tag) {
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(containerId, fragment, tag);
transaction.addToBackStack(tag);
transaction.commit();
}
// 移除Fragment
public void removeFragment(Fragment fragment) {
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.remove(fragment);
transaction.commit();
}
// 分离Fragment
public void detachFragment(Fragment fragment) {
if (fragment != null && fragment.isAdded()) {
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.detach(fragment);
transaction.commit();
}
}
// 重新附加Fragment
public void attachFragment(Fragment fragment) {
if (fragment != null && fragment.isDetached()) {
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.attach(fragment);
transaction.commit();
}
}
// 设置Fragment的最大生命周期
public static boolean setMaxLifecycle(FragmentManager fragmentManager,
Fragment fragment,
Lifecycle.State maxState) {
boolean isSuccess = false;
if (fragmentManager != null &&
fragment != null &&
fragment.isAdded() &&
maxState != null &&
maxState.isAtLeast(Lifecycle.State.CREATED)) {
Lifecycle.State curState = fragment.getLifecycle().getCurrentState();
if (curState != maxState) {
fragmentManager.beginTransaction()
.setMaxLifecycle(fragment, maxState)
.commitAllowingStateLoss();
isSuccess = true;
}
}
return isSuccess;
}
// 返回到指定的Fragment
public boolean popBackStackTo(String tag) {
return fragmentManager.popBackStackImmediate(tag, 0);
}
// 返回上一个Fragment
public boolean popBackStack() {
String currentFragmentTag = getCurrentFragmentTag();
boolean result = fragmentManager.popBackStackImmediate();
// 获取回退后的Fragment的tag值
String newFragmentTag = getCurrentFragmentTag();
if (result && callback != null) {
if (StringUtils.isEmpty(newFragmentTag)){
newFragmentTag = "HomeFg";
}
callback.onBackStackPopped(currentFragmentTag,newFragmentTag);
}
return result;
}
// 获取栈顶的Fragment
public Fragment getCurrentFragment() {
return fragmentManager.findFragmentById(containerId);
}
// 获取栈顶Fragment的tag值
public String getCurrentFragmentTag() {
Fragment currentFragment = getCurrentFragment();
if (currentFragment != null) {
return currentFragment.getTag();
}
return null;
}
}
容器是封装在MainActivity 中,所以还要提供两个回调方法,添加Fragment 和移除 Fragment,统一控制。
public interface FragmentTransactionCallback {
void onFragmentAdded(String currentTag, String tag);
void onBackStackPopped(String currentTag, String tag);
}
目前能想到暂时就这些,随着业务的增加 这些方法肯定满足不了需求。我已经能够想象到FragmentController的庞大程度了。
这里记录下,避免今后踩坑,如果得知项目要求组件化开发的时候,必须要问清楚 是否是独立Activity运行。