在项目的开发过程中,动态创建fragment是没必要的,而且不太现实的,因为fragment要显示UI加载数据。因为我们的项目使用的跨平台的开发框架React Native,安卓的activity、fragment的只是用来显示js页面的容器,所有的业务都是js来实现的,包括底部的Tabbar切换都是js实现的,原生安卓只是显示出来。现在的需求是,根据底部的tabbar 创建fragment然后加载相应js的页面,默认只有一个fragment显示默认的js页面,比如默认首页,创建一个首页的fragment,切换到订单标签的时候再去创建订单的fragment,依次类推。
1、一般我们创建fragment的时候都是先一次性创建,然后往容器里面添加,像这样
private void initFragment() { //实例化fragment indexFragment = new IndexFragment(); newsFragment = new NewsFragment(); myFragment = new MyFragment(); originFragment = new OriginFragment(); //添加到数组 fragments = new Fragment[]{indexFragment, newsFragment, myFragment, originFragment}; //添加到容器并显示默认 getSupportFragmentManager().beginTransaction().add(R.id.fl_container, indexFragment) .add(R.id.fl_container, newsFragment).add(R.id.fl_container, myFragment) .add(R.id.fl_container, originFragment).hide(originFragment) .hide(newsFragment).hide(myFragment).show(indexFragment).commit(); }
下标签切换的时候
switch (tab) { case "job": index = 0; break; case "news": index = 1; break; case "my": index = 2; break; case "origin": index = 3; break; } if (currentIndex != index) { FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.hide(fragments[currentIndex]); if (!fragments[index].isAdded()) { ft.add(R.id.fl_container, fragments[index]); } ft.show(fragments[index]).commit(); } currentIndex = index;像这样的写法是通过下标来切换。
**********************************
2、项目需求的写法,通过Map集合来存储Fragment,在切换底部Tabbar的时候先判断Map集合里面是否包含该标签的fragment,
如果没有创建并添加到Map集合里面去
private Map<String, Fragment> mapFragments = new HashMap<>(); //初始化默认显示的页面 private void init() { indexFragment = new IndexFragment(); //fragment按标签添加到Map集合 mapFragments.put("job", indexFragment); //提交事务 getSupportFragmentManager().beginTransaction().add(R.id.fl_container, indexFragment, "job") .show(indexFragment).commit(); }底部TabBar切换的时候所做的处理//默认显示标签的fragment private String currentFragment = "job"; private void changeTab(String tab) { if (currentFragment.equals(tab)) return; FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); //把上个页面先隐藏 if (!currentFragment.equals(tab)) { ft.hide(mapFragments.get(currentFragment)); } //判断Map集合里面是否有该标签的fragment,如果没有创建并添加到集合 if (!mapFragments.containsKey(tab)) { newsFragment = new NewsFragment(); Bundle bundle = new Bundle(); bundle.putString("type", tab); newsFragment.setArguments(bundle); mapFragments.put(tab, newsFragment); ft.add(R.id.fl_container, newsFragment, tab); } ft.show(mapFragments.get(tab)).commit(); currentFragment = tab; }3、公用的fragmentpublic class NewsFragment extends Fragment { private String tag = "news"; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); Bundle bundle = getArguments(); if (bundle != null) tag = bundle.getString("type"); } @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.layout_news, container, false); FrameLayout layout = (FrameLayout) view.findViewById(R.id.fl_news); Bundle bundle = new Bundle(); bundle.putString("type", tag); // 缓存中不存在RootView,直接创建 ReactRootView mReactRootView = new ReactRootView(getActivity()); ReactInstanceManager reactInstanceManager = MainApplication.createReactInstanceManager(CodePushConstants.MAIN1_JS_BUNDLE_NAME); mReactRootView.startReactApplication( reactInstanceManager, "init_project", bundle); layout.addView(mReactRootView); return view; } }4、总结:创建两个fragment,一个用于默认显示第一个页面,一个用来做公共的fragment,创建的时候通过tag标签标记该fragment并存储