2013-02-22 92 views
30

我在我的MainActivity中有一个ListFragment。这是我如何设置我的片段对象。有没有办法从栈顶获取碎片?

FragmentManager fragmentManager = activity.getSupportFragmentManager(); 
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
Fragment newFragment = new MyFragment(); 
fragmentTransaction.replace(R.id.framecontainer, newFragment, "tag"); 
fragmentTransaction.addToBackStack(null); 
fragmentTransaction.commit(); 

问题是,当用户按下后退按钮,我必须这样做,至少,通过调用

getActionBar().setTitle(title); 
getActionBar().setDisplayHomeAsUpEnabled(isEnabled); 
invalidateOptionsMenu(); 

更改操作栏和菜单我都知道什么样的片段目前呈现,以便我知道如何设置操作栏。我将片段中的设置选项存储为参数。

String title = fragment.getArguments().getString("KEY_TITLE"); 
boolean isEnabled = fragment.getArguments().getBoolean("KEY_ISENABLED"); 

我做搜索有关的问题,我意识到我可以通过调用

MyFragment fragment = (MyFragment) getSupportFragmentManager() 
     .findFragmentByTag("tag"); 

然而得到的片段,我要所有的标签存储在自定义堆栈,并调用流行( )每当用户在onBackPressed()中按下按钮时。

所以,我的问题是,有没有办法让我直接从堆栈中获取当前可见片段?

注意:请记住片段类型不同,不仅仅是MyFragment。

回答

52

一些像这样的东西应该帮助你的活动身影这一点上backpress:

private Fragment getCurrentFragment(){ 
    FragmentManager fragmentManager = getSupportFragmentManager(); 
    String fragmentTag = fragmentManager.getBackStackEntryAt(fragmentManager.getBackStackEntryCount() - 1).getName(); 
    Fragment currentFragment = fragmentManager.findFragmentByTag(fragmentTag); 
    return currentFragment; 
} 

@Override 
public void onBackPressed() { 
    Fragment fragmentBeforeBackPress = getCurrentFragment(); 
    // Perform the usual back action 
    super.onBackPressed(); 
    Fragment fragmentAfterBackPress = getCurrentFragment(); 
} 

希望这有助于。

+6

看来,如果我在你的方式做到这一点,我必须设置* * fragmentTransaction.addToBackStack(标签)**;否则,我会得到一个NullPointerException。所以** fragmentManager.getBackStackEntryAt(fragmentManager.getBackStackEntryCount() - 1).getName(); **不参考标记名称 – 2013-02-22 16:59:10

+1

是的...你将不得不检查空值和不良数学((getBackStackEntryCount-1)> 0等)。我有点写得太快了。另外,没有标签添加的fragements会显示为空。 – petey 2013-02-22 17:25:52

+0

如果我使用addToBackStack(null),它会继续工作吗? – umerk44 2016-04-06 20:32:16

20
FragmentManager.findFragmentById(fragmentsContainerId) 

function链接返回到顶部在堆栈中Fragment。用例:

fragmentManager.addOnBackStackChangedListener(new OnBackStackChangedListener() { 
     @Override 
     public void onBackStackChanged() { 
      Fragment fr = fragmentManager.findFragmentById(R.id.fragmentsContainer); 
      if(fr!=null){ 
       Log.e("fragment=", f.getClass().getSimpleName()); 
      } 
     } 
    }); 
+0

这看起来有点怪异......但对我来说确实很好:)。文档确实说它搜索的是后台,所以希望它始终在堆栈的顶部搜索所有版本的Android(手指交叉)。 – delrocco 2014-07-24 21:39:17

+0

我一直在寻找这个这么久。感谢您澄清这位听众如何工作 – mikebertiean 2016-12-13 20:09:41

1

已经有标记为正确的答案和我的其他信息的不会 是不同的这一点。但是,当使用接收机尝试 判断接收方来自哪里的片段是当前栈顶的 片段时,我遇到了麻烦。你可以很容易地运行在很多NPE和索引越界之外。 因此,我写了这个,也许它有助于某人。

private boolean isFragmentOnTop(Activity parentActivity, final String fragmentName){ 
     FragmentManager fmManager = parentActivity.getFragmentManager(); 
     if(fmManager.getBackStackEntryCount() == 0){ 
      LOG.i("BackStack entry count is 0: " + this); 
      return false; 
     } 
     String fragmentNameOnStackTop = ""; 
     final FragmentManager.BackStackEntry topEntry = fmManager.getBackStackEntryAt(fmManager.getBackStackEntryCount() -1); 
     if(topEntry != null) { 
      fragmentNameOnStackTop = topEntry.getName(); 
     } 
     LOG.d("Got fragments name: " + fragmentNameOnStackTop); 
     return fragmentNameOnStackTop != null ? fragmentNameOnStackTop.equals(fragmentName) : false; 
    } 

请注意,这适用于有一些片段的活动。请注意,如果您是使用ViewPager childfragmentmanager的 。

而且不要忘记设置fragmentName在FragmentTransaction.addToBackStack(fragmentName)

0

这个辅助方法从堆栈的顶部得到片段:

public Fragment getTopFragment() { 
    if (getSupportFragmentManager().getBackStackEntryCount() == 0) { 
     return null; 
    } 
    String fragmentTag = getSupportFragmentManager().getBackStackEntryAt(getSupportFragmentManager().getBackStackEntryCount() - 1).getName(); 
    return getSupportFragmentManager().findFragmentByTag(fragmentTag); 
} 
相关问题