【问题标题】:Why is my Fragments not hidden when I set the hide/show为什么我设置隐藏/显示时我的片段没有隐藏
【发布时间】:2016-09-12 05:55:46
【问题描述】:

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

我正在关注这个Navigation View - Material Design Support Library Tutorial。我做了一些更改,以便可以隐藏和显示FragmentsFragment 将与 FireBase 同步,所以我希望它们能够活得很好,而不是不断地重新创建。问题是我永远无法让他们隐藏起来。我在 LogCat 中清楚地看到 Fragment onAttach(),需要显示/隐藏才能正常工作吗? 我在这里完全错过了什么?

先添加一些代码 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 选择了 Fragment 可见时,这个方法应该隐藏除 @param fragment 之外的所有 Fragment。

/**
 * 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

【问题讨论】:

  • 你为什么不和replace一起工作?
  • 我认为replace 会让Fragment 转到onDetach(),我不希望这样
  • 为什么?如果您不想每次显示Fragment 时都重新加载它(使用replace(),您只需将它的一个实例存储在您的Activity 中,然后重复使用它。
  • @Amylinn 是的,你是对的,但我想尝试按本书去做,可以这么说,隐藏/显示

标签: android android-fragments


【解决方案1】:

好吧,在喝了一晚坏咖啡后,这是我的错误。

如果您需要,您可以使用此工作代码替换,另请注意,我添加了 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);
...............

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-06
    相关资源
    最近更新 更多