android - 如何检测当前正在使用的 fragment

标签 android android-fragments

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

如果用户关闭应用程序并再次打开它,最后访问的 fragment 将显示给用户。

我阅读了很多关于此的答案,但对于了解用户当前可见的 fragment 的解决方案并没有达成共识。

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

或者在 Fragment 中放置一些 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();
    }

在上面的代码中,我 pop Fragment 并且不知道 popt Fragment 下的 Fragment 是什么。

这是我添加或显示 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());
        }
    }

最佳答案

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

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 中添加此内容(不是 fragment ):

@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
}

关于android - 如何检测当前正在使用的 fragment ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42353028/

相关文章:

android - Viewpager 不显示第一个 fragment 的菜单项

android - 如何在细节PreferenceFragment中加载相同的屏幕首选项

Android: bundle 始终为空

java - 合并两个自定义对象类型的 ArrayList

java - android.os.FileUriExposedException 在 Oreo 中引起(仅!)

android - 如何使用每个建议行旁边的图标创建自定义自动完成 TextView - Android

android - 文件 URI 上的空指针异常?

android - 我的应用程序已被复制

java.lang.IllegalStateException : Can not perform this action after onSaveInstanceState while using FragmentTabHost 错误

java - 如何调用 onCreateView 方法或刷新我的 fragment ?