为什么在设置隐藏/显示时我的碎片不会被隐藏

时间:2016-09-12 05:55:46

标签: android android-fragments

更新 添加了我自己的答案,因为我解决了它。问题是未触及的答案!

我正在关注此Navigation View - Material Design Support Library Tutorial。我做了一些更改,以便我可以隐藏并显示FragmentsFragment将与FireBase联系,因此我希望它们能够活得很好,并且不会经常重新创建。问题是我永远无法让它们隐藏起来。我清楚地在 LogCat 中看到Fragment onAttach(),是否要求show / hide正常工作? 我在这里完全错过了什么?

首先添加一些代码AppCompatActivity

/**
 * Main launcher
 */
public class FragmentActivityMain extends ManagedAppCompatActivity implements OnClickListener,
        ConfirmDialogListener, NotificationDialogListener, OnConnectionStateListener,
        NavigationView.OnNavigationItemSelectedListener {

    private static final String TAG = FragmentActivityMain.class.getName();
............

这是包含NavigationView菜单项(片段)的TypedArray

    <!-- NavigationView items -->
    <string-array name="navigationview_items">
        <item>com.port.android.ui.HomeFragment</item>
        <item>com.port.android.ui.ChatFragment</item>
        <item>com.port.android.ui.BillboardFragment</item>
        <item>com.port.android.ui.NewsFragment</item>
        <item>com.port.android.ui.settingsFragment</item>
        <item>com.port.android.ui.LoginFragment</item>
    </string-array>

加载TypedArray

@Override
protected void onCreate(Bundle savedInstanceState) {
...
navigationviewItems = getResources().obtainTypedArray(R.array.navigationview_items);

}

onNavigationItemSelected侦听器,它将检查Fragment是否已添加到supportFragmentManager并且是否添加它

    // This method will trigger on item Click of navigation menu
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
    String tag;
    //Closing drawer on item click
    drawerLayout.closeDrawers();
    View r = findViewById(R.id.landing_page);
    //Check to see which item was being clicked and perform appropriate action
    switch (menuItem.getItemId()) {
        case R.id.home: // HomeFragment
            tag = navigationviewItems.getString(0);
            if (fragmentManager.findFragmentByTag(tag) == null) {
                try {
                    fragmentManager.beginTransaction().add(R.id.frame, (Fragment) Class.forName(tag).newInstance(), tag)
                            .addToBackStack(tag)
                            .commit();
                    MyLog.i(TAG, "Class.forName(tag) = " + tag);
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            } else
                MyLog.i(TAG, "switch SHOW " + tag);
            hideAllFrags(tag);
            return true;
        case R.id.chat: // ChatFragment
            tag = navigationviewItems.getString(1);
            ....................

当上面的onNavigationItemSelected选择了片段可见时,此方法应该隐藏除@param片段之外的所有片段。

/**
 * Hide all Fragments except @param fragment
 */
private void hideAllFrags(String fragment) {
    for (int index = 0; index < navigationviewItems.length(); index++)
        try {
            if (!fragment.equals(navigationviewItems.getString(index))) {
                if (fragmentManager.findFragmentByTag(fragment) != null)
                    fragmentManager.beginTransaction().hide(fragmentManager.findFragmentByTag(fragment)).commit();
                Log.d(TAG, "HIDING " + navigationviewItems.getString(index));
            }else{
                if (fragmentManager.findFragmentByTag(fragment) != null)
                    fragmentManager.beginTransaction().show(fragmentManager.findFragmentByTag(fragment)).commit();
                Log.d(TAG, "SHOWING " + navigationviewItems.getString(index));

            }
        } catch (Exception e) {
            Log.d(TAG, "CANNOT LOAD navigationviewItems " + navigationviewItems.getString(index));
            throw new RuntimeException(e);
        }
}

This is what it looks like and both the chat and the home fragment are visible

1 个答案:

答案 0 :(得分:0)

好吧,经过一晚喝咖啡后,这是我的错误。

如果您需要,可以替换此工作代码,请注意我添加了executePendingTransactions()以立即进行交易。

/**
 * Hide all Fragments except @param fragment
 */
private void hideAllFrags(String fragment) {
    String name = "";
    for (int index = 0; index < navigationviewItems.length(); index++)
        try {
            name = navigationviewItems.getString(index);
            if (!fragment.equals(name)) {
                if (fragmentManager.findFragmentByTag(name) != null) {
                    fragmentManager.beginTransaction().hide(fragmentManager.findFragmentByTag(name)).commit();
                    fragmentManager.executePendingTransactions();
                }
                Log.d(TAG, "HIDING " + name);
            } else {
                if (fragmentManager.findFragmentByTag(fragment) != null) {
                    fragmentManager.beginTransaction().show(fragmentManager.findFragmentByTag(fragment)).commit();
                    fragmentManager.executePendingTransactions();
                }
                Log.d(TAG, "SHOWING " + fragment);
            }
        } catch (Exception e) {
            Log.d(TAG, "CANNOT LOAD navigationviewItems " + fragment);
            throw new RuntimeException(e);
        }
}

添加executePendingTransactions() ..而addToBackStack(null)是可选的。我认为用户习惯于按下后退按钮并期望在视图历史记录中返回。

        switch (menuItem.getItemId()) {
            case R.id.home: // HomeFragment
                tag = navigationviewItems.getString(0);
                if (fragmentManager.findFragmentByTag(tag) == null) {
                    try {
                        fragmentManager.beginTransaction().add(R.id.frame, (Fragment) Class.forName(tag).newInstance(), tag)
                                .addToBackStack(null)
                                .commit();
                        fragmentManager.executePendingTransactions();
                        MyLog.i(TAG, "Class.forName(tag) = " + tag);
...............