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