2

熙家伙,片段不断重复

我目前正在片段工作,我想管理它,这样当你在同一个菜单项,点击两次它不会把同样的片段2彼此的顶部。但它仍然如此。谁能告诉我我做错了什么?

/* 
* Method to check which action is behind the selected Menu item. Then call ShowFragment() 
* With the correct fragment parameter used with this Menu action value. 
*/ 
public void getAction(int position, Cursor cursor) { 
    // TODO Auto-generated method stub 
    mCursor = cursor; 
    cursor.moveToPosition(position); 
    String action = cursor.getString(cursor.getColumnIndex(AppMenu.ACTION)); 
    if (action != null) { 
     if (action.equalsIgnoreCase("home")) { 
      trans = manager.beginTransaction(); 
      BaseFragment newFragment = new HomeFragment(); 
      if (manager.findFragmentByTag(newFragment.getTag()) != null) { 
       mCursor.moveToPosition(position); 

       // Set the current fragment 
       mCurrentFragment = newFragment; 
       Bundle bundle = new Bundle(); 
       int fragId = mCursor.getInt(mCursor.getColumnIndex(AppMenu._ID)); 
       Log.i(TAG, fragId + " "); 
       bundle.putInt("fragmentID", fragId); 
       newFragment.setArguments(bundle); 

       trans.replace(R.id.fragmentContainer, newFragment).addToBackStack(
         newFragment.tag()); 
       trans.commit(); 
      } else { 
       trans.show(newFragment); 
      } 

     } else if (action.equalsIgnoreCase("event")) { 
      showFragment(new EventsFragment(), position); 
     } else if (action.equalsIgnoreCase("location")) { 
      showFragment(new LocationsFragment(), position); 
     } else if (action.equalsIgnoreCase("news")) { 
      showFragment(new NewsFragment(), position); 
     } else if (action.equalsIgnoreCase("bars")) { 
      showFragment(new BarsFragment(), position); 
     } else if (action.equalsIgnoreCase("currency")) { 
      showFragment(new CurrencyFragment(), position); 
     } else if (action.equalsIgnoreCase("map")) { 
      showFragment(new MapFragment(), position); 
     } 
    } else { 
     Log.i(TAG, "You've got a nullpointerexception on getAction()."); 
    } 
} 
/* 
* Method that's called when changing from fragment through Menu or HomeMenu. 
*/ 
public void showFragment(BaseFragment newFragment, int position) { 
    trans = manager.beginTransaction(); 
    if (manager.findFragmentByTag(newFragment.tag()) == null) { 
     mCursor.moveToPosition(position); 

     // Set the current fragment 
     mCurrentFragment = newFragment; 

     // Go on and set the bundle values and pass it on the fragment. 
     Bundle bundle = new Bundle(); 
     int fragId = mCursor.getInt(mCursor.getColumnIndex(AppMenu._ID)); 
     Log.i(TAG, fragId + " "); 
     bundle.putInt("fragmentID", fragId); 
     newFragment.setArguments(bundle); 

     trans.replace(R.id.fragmentContainer, newFragment).addToBackStack(
       newFragment.tag()); 
     trans.commit(); 
    } else { 
     trans.show(newFragment); 
    } 
} 

这里有2个回调,当有什么变化或者什么时候回来按下时。

/* 
* Interface method called whenever a new fragment is created. 
*/ 
@Override 
public void onNewFragment(BaseFragment newFragment) { 
    // TODO Auto-generated method stub 

    FragmentManager fm = getSupportFragmentManager(); 
    Class<? extends Fragment> newFragmentClass = newFragment.getClass(); 
    if (newFragmentClass == EventsFragment.class 
      || newFragmentClass == LocationsFragment.class 
      || newFragmentClass == MapFragment.class 
      || newFragmentClass == NewsFragment.class 
      || newFragmentClass == CurrencyFragment.class 
      || newFragmentClass == BarsFragment.class) { 
     for (Fragment fragment : fm.getFragments()) { 
      if (fragment != null && ((Object) fragment).getClass() == newFragmentClass) { 
       while (((Object) mCurrentFragment).getClass() != newFragmentClass) { 
        popFragment(); 
       } 
       popFragment(); 
       break; 
      } 
     } 
    } 
} 
/* 
* Interface method called when you navigate back from a fragment. 
* Checks which fragment is active, calls upon this fragments back function to clear any data, 
* then pops the first fragment on the backstack. 
*/ 
@Override 
public void onBackNavigated() { 
    // TODO Auto-generated method stub 
    if ((mCurrentFragment instanceof HomeFragment) 
      && !((HomeFragment) mCurrentFragment) 
      .isStackEmpty()) { 
     System.exit(0); 
     // break; 
    } 
    if ((mCurrentFragment instanceof LocationsFragment) 
      && !((LocationsFragment) mCurrentFragment) 
      .isStackEmpty()) { 
     ((LocationsFragment) mCurrentFragment).goBack(); 
     // return; 
    } 
    if ((mCurrentFragment instanceof EventsFragment) 
      && !((EventsFragment) mCurrentFragment) 
      .isStackEmpty()) { 
     ((EventsFragment) mCurrentFragment).goBack(); 
     // return; 
    } 
    if ((mCurrentFragment instanceof MapFragment) 
      && !((MapFragment) mCurrentFragment).isStackEmpty()) { 
     ((MapFragment) mCurrentFragment).goBack(); 
     // break; 
    } 
    if ((mCurrentFragment instanceof BarsFragment) 
      && !((BarsFragment) mCurrentFragment).isStackEmpty()) { 
     ((BarsFragment) mCurrentFragment).goBack(); 
     // break; 
    } 
    if ((mCurrentFragment instanceof CurrencyFragment) 
      && !((CurrencyFragment) mCurrentFragment).isStackEmpty()) { 
     ((CurrencyFragment) mCurrentFragment).goBack(); 
     // break; 
    } 
    popFragment(); 
} 
/* 
* Pops the first fragment in the backstack. Then sets this as the new current fragment. 
* If no fragment is in the backstack then finish() is called. Which will destroy the only fragment. 
* Which in this case exits the application. 
*/ 
public void popFragment() { 
    if (manager.getBackStackEntryCount() > 1) { 
     manager.popBackStack(); 
     manager.executePendingTransactions(); 
     ArrayList<Fragment> reversedFragments = new ArrayList<Fragment>(
       manager.getFragments()); 
     Collections.reverse(reversedFragments); 
     for (Fragment fragment : reversedFragments) 
      if (fragment != null) { 
       mCurrentFragment = (BaseFragment) fragment; 
       break; 
      } 
    } else { 
     finish(); 
    } 
} 

**注意:** tag()函数每次调用片段本身的最终字符串和相同的硬编码标签。所以同一类的每个片段都有相同的标签。 (应避免重复片段,但它仍然没有)

解决方案:

标签()的返回null人的时间。 (不知道为什么)所以我改变了showFragment(片段,标签,位置)并硬编码了mainactivity中的标签。然后使用:

trans.replace(R.id.fragmentContainer, newFragment, tag); 
//instead of 
trans.replace(R.id.fragmentContainer, newFragment).addToStackBack(tag); 

不要忘记仍然将其添加到堆栈中!否则你的后退导航将无法正常工作。 只需添加一行:trans.addToBackStack(tag);

回答

2

您可以设置标签,同时增加/更换的片段,其

所以,你需要提到它为:

trans.replace(R.id.fragmentContainer, newFragment,tag); 

传递标签值的方法根据片段

showFragment(new EventsFragment(),tag, position); 

希望它能帮助你

+0

它似乎没有达到真正的部分。所以我现在不能再点击菜单了。试图把它放入if/else语句中,仍然没有成功。 – 2014-11-25 09:21:26

+0

似乎你忘了重新启用它。你有没有重新启用它'list.setEnabled(true);'? – 2014-11-25 09:22:17

+0

是的,但代码不会去那里。可能在提交之前放置它? – 2014-11-25 09:22:58