用 Tag、 反射原理 和 findFragmentByTag 少寫代碼實現Tab 切換時實例化、顯示、隱藏 Fragment

在一些場景裏, TabLayout 會對應一組Fragment,而後經過 onTabSelected(TabLayout.Tab tab) 來觸發Tab所對應Fragment的 add() (實例化) show()hide() ,那麼如何儘可能少寫代碼來實現這個場景呢?ide


個人解決方案是用 Tag反射原理 以及 FragmentManagerfindFragmentByTag(String tag) 方法this

  1. 將Fragment的類的限定名做爲 Tag 附加到 Tabcode

  2. onTabSelected(TabLayout.Tab tab) 時獲取 Tab 對應的 Tag
    這時得到的就是Fragment的限定名get

  3. 利用反射經過限定名實例化Fragment並 add()string

  4. show() 對應的Fragmentit

  5. hide() 也是一樣的道理io


代碼片斷:class

tabLayout = (TabLayout) findViewById(R.id.tab_layout);
            final TabLayout.Tab tab1 = tabLayout
                    .newTab()
                    .setText(R.string.text_1)
                    .setTag(Tab1Fragment.class.getName()); //用Fragment的限定名做爲Tag
            TabLayout.Tab tab2 = tabLayout
                    .newTab()
                    .setText(R.string.text_2)
                    .setTag(Tab2Fragment.class.getName());
            TabLayout.Tab tab3 = tabLayout
                    .newTab()
                    .setText(R.string.text_3)
                    .setTag(Tab3Fragment.class.getName());
            tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
                @Override
                public void onTabSelected(TabLayout.Tab tab) {
                    FragmentUtils.showBeforeAddByTag(SomeActivity.this, R.id.frame_layout_fragment_container, (String) tab.getTag()); //用Tab的Tag來進一步完成Fragment的add show hide
                }
                @Override
                public void onTabUnselected(TabLayout.Tab tab) {
                    FragmentUtils.hideByTag(SomeActivity.this, (String) tab.getTag());
                }
                @Override
                public void onTabReselected(TabLayout.Tab tab) {
                }
            });

FragmentUtils代碼片斷:原理

//經過反射實例化Fragment  
    @Nullable
    public static Fragment reflectionNewInstance(@NonNull String fragmentClassName, Object... args) {
        Class<?>[] parameterTypes;
        if (args == null) {
            parameterTypes = new Class[0];
        } else {
            parameterTypes = new Class[args.length];
            for (int i = 0; i < args.length; i++) {
                parameterTypes[i] = args[i].getClass();
            }
        }
        try {
            Method method = Class.forName(fragmentClassName).getMethod("newInstance", parameterTypes);
            return (Fragment) method.invoke(null, args);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }
    
    //添加Fragment
    public static Fragment addByTag(FragmentActivity fragmentActivity, int containerResourceId, String tag, Bundle arguments) {
        FragmentManager fragmentManager = fragmentActivity.getSupportFragmentManager();
        Fragment fragment = reflectionNewInstance(tag);
        fragment.setArguments(arguments);
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(containerResourceId, fragment, tag);
        fragmentTransaction.commit();
        return fragment;
    }

    //顯示Fragment
    public static void showByTag(FragmentActivity fragmentActivity, String tag) {
        FragmentManager fragmentManager = fragmentActivity.getSupportFragmentManager();
        Fragment fragment = fragmentManager.findFragmentByTag(tag); //經過Tab上的tag查找Fragment實例
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.show(fragment);
        fragmentTransaction.commit();
    }
    
    //隱藏Fragment
    public static void hideByTag(FragmentActivity fragmentActivity, String tag) {
        FragmentManager fragmentManager = fragmentActivity.getSupportFragmentManager();
        Fragment fragment = fragmentManager.findFragmentByTag(tag);
        if (fragment != null) {
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            fragmentTransaction.hide(fragment);
            fragmentTransaction.commit();
        }
    }
相關文章
相關標籤/搜索