如何检测当前正在使用的Fragment

时间:2017-02-20 19:44:59

标签: android android-fragments

我有一个应用程序项目,其中有10个碎片。当用户打开片段我希望在代码中知道这一点并将片段保存为用户访问过的最后一个片段。

如果用户关闭应用并再次打开它,则会向用户显示最后访问过的片段。

我读了很多关于此问题的答案,并且对于了解用户当前可见的片段的解决方案没有达成共识。

我在考虑将FragmentManager子类化,以检测弹出和监视队列状态。

或者可能在GestureDetector.OnGestureListener中添加一些Fragment,当它触发时我可以保存用户访问过的最后一个片段。

对此有任何帮助

当Fragment中的用户按下按钮

时会发生这种情况
  /**
     * user press back button
     */
    @Override
    public void onBackPressed() {
        //Fragment fragment = getVisibleFragment();

        //get the name from the topmost BackStackEntry which is also the fragment tag.
        String fragmentTag = mFragManager.getBackStackEntryAt(mFragManager.getBackStackEntryCount()-1).getName();

        Fragment currentFrag = mFragManager.findFragmentByTag(fragmentTag);
        if (currentFrag == null ) {
            super.onBackPressed();
        }

        if (currentFrag != null) {
            if (currentFrag.getTag().equals(SettingsManager.FragmentsModel.CHAT_FRAGMENT.toString())) {
                if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
                    openDrawer(false);
                } else
                    requestBeginTransaction(SettingsManager.FragmentsModel.LAUNCHER_FRAGMENT.toString(), true, false);
            } else if (currentFrag.getTag().equals(SettingsManager.FragmentsModel.BILLBOARD_FRAGMENT.toString())) {

            } else if (currentFrag.getTag().equals(SettingsManager.FragmentsModel.NEWS_FRAGMENT.toString())) {

            } else if (currentFrag.getTag().equals(SettingsManager.FragmentsModel.INFO_FRAGMENT.toString())) {
                super.onBackPressed();
            } else if (currentFrag.getTag().equals(SettingsManager.FragmentsModel.SEARCH_FRAGMENT.toString())) {
                // exit app if the search address view is visible
                if (currentFrag.getView().findViewById(R.id.search_address_layout).getVisibility() == View.VISIBLE) {
                    exitApp();
                } else if (currentFrag.getView().findViewById(R.id.show_search_result_layout).getVisibility() == View.VISIBLE) {
                    // show search address view if Address already exist view is visible
                    currentFrag.getView().findViewById(R.id.search_address_layout).setVisibility(View.VISIBLE);
                    currentFrag.getView().findViewById(R.id.history).setVisibility(View.VISIBLE);
                    currentFrag.getView().findViewById(R.id.show_search_result_layout).setVisibility(View.INVISIBLE);
                    ((SearchFragment)currentFrag).onSearchLayoutVisible();
                }
            } else if (currentFrag.getTag().equals(SettingsManager.FragmentsModel.PREFERENCE_FRAGMENT.toString())) {
                super.onBackPressed();
                //requestBeginTransaction(SettingsManager.FragmentsModel.LAUNCHER_FRAGMENT.toString(), true, false);
            } else if (currentFrag.getTag().equals(SettingsManager.FragmentsModel.PREFERENCE_FRAGMENT_CHAT_SETTINGS.toString())) {
                super.onBackPressed();
                //requestBeginTransaction(SettingsManager.FragmentsModel.LAUNCHER_FRAGMENT.toString(), true, false);
            } else if (currentFrag.getTag().equals(SettingsManager.FragmentsModel.PREFERENCE_FRAGMENT_THEME_SETTINGS.toString())) {
                super.onBackPressed();
                //requestBeginTransaction(SettingsManager.FragmentsModel.LAUNCHER_FRAGMENT.toString(), true, false);
            } else if (currentFrag.getTag().equals(SettingsManager.FragmentsModel.LAUNCHER_FRAGMENT.toString())) {
                super.onBackPressed();
                //requestBeginTransaction(SettingsManager.FragmentsModel.LAUNCHER_FRAGMENT.toString(), true, false);
            }
        } else
            exitApp();
    }

在上面的代码中我弹出Fragment并且不知道片段在popt Fragment下面是什么片段。

这是我添加或显示片段

的时候
   /**
     * Change the current displayed fragment by a new one.
     * - if the fragment is in backstack, it will pop it
     * - if the fragment is already displayed (trying to change the fragment with the same), it will not do anything
     *
     * @param backStateName             the new fragment to display
     * @param saveInBackstack if we want the fragment to be in backstack
     * @param animate         if we want a nice animation or not
     */
    public void requestBeginTransaction(String backStateName, boolean saveInBackstack, boolean animate) {
        Fragment frag = null;
        if (mFragManager.findFragmentByTag(backStateName) != null) {
            frag = mFragManager.findFragmentByTag(backStateName);
        } else
            try {
                frag = (Fragment) Class.forName(backStateName).newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        try {
            FragmentManager manager = getSupportFragmentManager();
            boolean fragmentPopped = manager.popBackStackImmediate(backStateName, 0);

            if (!fragmentPopped && manager.findFragmentByTag(backStateName) == null) {
                //fragment not in back stack, create it.
                FragmentTransaction transaction = manager.beginTransaction();

                if (animate) {
                    LogManager.d(this, "Change Fragment: animate");
                    // transaction.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left, R.anim.slide_in_left, R.anim.slide_out_right);
                }

                transaction.add(R.id.frame, frag, backStateName);

                if (saveInBackstack) {
                    LogManager.d(this, "Change Fragment: addToBackTack " + backStateName);
                    transaction.addToBackStack(backStateName);
                    LogManager.d(this, "Change Fragment: NO addToBackTack");
                }

                transaction.commit();
            } else {
                mFragManager.beginTransaction().show(mFragManager.findFragmentByTag(backStateName)).commit();

                // custom effect if fragment is already instanciated
            }
        } catch (IllegalStateException exception) {
            LogManager.w(this, "Unable to commit fragment, could be activity as been killed in background. " + exception.toString());
        }
    }

2 个答案:

答案 0 :(得分:1)

您可以通过查看其实例来测试它。

Fragment fragment = getFragmentManager().findFragmentById(R.id.fragment_container);
if (fragment instanceOf Fragment1) {
 // It is fragment of class Fragment1
} else if (fragment instanceOf Fragment2) {
 // It is fragment of class Fragment2
}

当用户按下后退按钮时,请在activity(不是片段)中添加:

@Override
public void onBackPressed() {

    super.onBackPressed();

    Fragment fragment = getFragmentManager().findFragmentById(R.id.fragment_container);
    if (fragment instanceOf Fragment1) {
     // It is fragment of class Fragment1
    } else if (fragment instanceOf Fragment2) {
     // It is fragment of class Fragment2
    }

   // Save to prefs which fragment tag it is
}

答案 1 :(得分:0)

如果用户关闭应用程序时只需要知道最后一个可见的片段来恢复它,我建议在它启动时将片段的标记(或某些标识符)存储在SharedPreferences中。然后,您可以稍后使用该首选项值在应用程序启动时设置正确的片段。 你可以通过覆盖onStart()片段方法来实现。