获取当前显示的片段
我正在玩Android的片段。
我知道我可以通过使用下面的代码来改变片段:
FragmentManager fragMgr = getSupportFragmentManager(); FragmentTransaction fragTrans = fragMgr.beginTransaction(); MyFragment myFragment = new MyFragment();//my custom fragment fragTrans.replace(android.R.id.content, myFragment); fragTrans.addToBackStack(null); fragTrans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); fragTrans.commit();
我的问题是,在一个Java文件中,如何获取当前显示的片段实例?
在交易中添加片段时,应该使用标签。
fragTrans.replace(android.R.id.content, myFragment, "MY_FRAGMENT");
…以后如果你想检查片段是否可见:
MyFragment myFragment = (MyFragment)getFragmentManager().findFragmentByTag("MY_FRAGMENT"); if (myFragment != null && myFragment.isVisible()) { // add your code here }
另见http://developer.android.com/reference/android/app/Fragment.html
我知道这是一个旧的post,但以前也遇到过麻烦。 find一个解决scheme,这是在onBackStackChanged()
监听function
Fragment f = getActivity().getFragmentManager().findFragmentById(R.id.fragment_container); if (f instanceof CustomFragmentClass) // do something with f ((CustomFragmentClass) f).doSomething();
这对我工作,因为我不想遍历每一个片段,我必须find一个可见的。 希望它也能帮助别人。
这是我的解决scheme,我发现低分段的情况下得心应手
public Fragment getVisibleFragment(){ FragmentManager fragmentManager = MainActivity.this.getSupportFragmentManager(); List<Fragment> fragments = fragmentManager.getFragments(); if(fragments != null){ for(Fragment fragment : fragments){ if(fragment != null && fragment.isVisible()) return fragment; } } return null; }
每次当你显示片段时,你必须把它放在后台:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.setTransition(FragmentTransaction.TRANSIT_ENTER_MASK); ft.add(R.id.primaryLayout, fragment, tag); ft.addToBackStack(tag); ft.commit();
然后,当你需要得到当前的片段,你可以使用这种方法:
public BaseFragment getActiveFragment() { if (getSupportFragmentManager().getBackStackEntryCount() == 0) { return null; } String tag = getSupportFragmentManager().getBackStackEntryAt(getSupportFragmentManager().getBackStackEntryCount() - 1).getName(); return (BaseFragment) getSupportFragmentManager().findFragmentByTag(tag); }
我用来find当前显示片段是在下面的代码。 这很简单,现在对我来说很有用。 它运行在持有碎片的活动中
FragmentManager fragManager = this.getSupportFragmentManager(); int count = this.getSupportFragmentManager().getBackStackEntryCount(); Fragment frag = fragManager.getFragments().get(count>0?count-1:count);
被动的方式:
Observable.from(getSupportFragmentManager().getFragments()) .filter(fragment -> fragment.isVisible()) .subscribe(fragment1 -> { // Do something with it }, throwable1 -> { // });
我的方法是基于try / catch这样的:
MyFragment viewer = null; try { viewer = (MyFragment) getFragmentManager().findFragmentByTag(MY_TAG_FRAGMENT); } catch (ClassCastException e) { // not that fragment }
但是可能有更好的办法
1)
ft.replace(R.id.content_frame, fragment, **tag**).commit();
2)
FragmentManager fragmentManager = getSupportFragmentManager(); Fragment currentFragment = fragmentManager.findFragmentById(R.id.content_frame);
3)
if (currentFragment.getTag().equals(**"Fragment_Main"**)) { //Do something } else if (currentFragment.getTag().equals(**"Fragment_DM"**)) { //Do something }
受泰妮答复的启发,这是我的两分钱。 从大多数其他的实现很less修改。
private Fragment getCurrentFragment() { FragmentManager fragmentManager = myActivity.getSupportFragmentManager(); int stackCount = fragmentManager.getBackStackEntryCount(); if( fragmentManager.getFragments() != null ) return fragmentManager.getFragments().get( stackCount > 0 ? stackCount-1 : stackCount ); else return null; }
将"myActivity"
replace为"myActivity"
,如果它是您当前的活动或使用对您的活动的引用。
那么,这个问题得到了很多意见和关注,但仍然没有包含我最后的最简单的解决scheme – 使用getFragments()。
List fragments = getSupportFragmentManager().getFragments(); mCurrentFragment = fragments.get(fragments.size() - 1);
这有点晚,但对于任何感兴趣的人:如果你知道在FragmentManager中你想要的片段的索引,只需要引用它并检查isMenuVisible()函数! 这里 :
getSupportFragmentManager().getFragments().get(0).isMenuVisible()
如果true
对用户可见等等!
如果您从父级活动获取当前的片段实例,则可以
findFragmentByID(R.id.container);
这实际上得到了在视图上填充的片段的当前实例。 我遇到过同样的问题。 我必须加载相同的碎片两次,一个在后台。
以下方法不起作用。 它只是得到一个有标签的片段。 不要浪费你的时间在这个方法上。 我相信它有它的用途,但得到相同的片段的最新版本是不是其中之一。
findFragmentByTag()
SupportFragmentManager
有一个名为findFragmentById()
的方法。 我在活动容器中使用它,如:
public Fragment currentFragment(){ return getSupportFragmentManager().findFragmentById(R.id.activity_newsfeed_frame); }
这就是如何得到你当前的Fragment
。 如果你有自定义Fragment
并且需要检查它是什么Fragment
,我通常使用instanceof
:
if (currentFragment() instanceof MyFrag){ // Do something here }
这是为我工作。 我希望这会帮助某人。
FragmentManager fragmentManager = this.getSupportFragmentManager(); String tag = fragmentManager .getBackStackEntryAt( fragmentManager .getBackStackEntryCount() - 1) .getName(); Log.d("This is your Top Fragment name: ", ""+tag);
final FragmentManager fm=this.getSupportFragmentManager(); final Fragment fragment=fm.findFragmentByTag("MY_FRAGMENT"); if(fragment != null && fragment.isVisible()){ Log.i("TAG","my fragment is visible"); } else{ Log.i("TAG","my fragment is not visible"); }
在主要活动中,当将新片段附加到活动时,将调用onAttachFragment(片段片段)方法。 在这个方法中,你可以得到当前片段的实例。 但是,当从堆栈中popup一个片段时,即在按下后退button以获取堆栈顶部的片段时,不会调用onAttachFragment方法。 我仍然在寻找一个callback方法,当一个片段在活动内部可见时,在主活动中被触发。
我遇到了一个类似的问题,我想知道当后退键被按下时最后显示的是什么片段。 我使用了一个非常简单的解决scheme,为我工作。 每次我打开一个片段,在onCreate()方法中,我在单例中设置一个variables(用你的片段的名称replace“myFragment”)
MySingleton.currentFragment = myFragment.class;
该variables在单例中声明为
public static Class currentFragment = null;
然后在onBackPressed()我检查
if (MySingleton.currentFragment == myFragment.class){ // do something return; } super.onBackPressed();
确保调用super.onBackPressed(); 之后的“返回”,否则该应用程序将处理返回键,这在我的情况下导致应用程序终止。
Sev的答案适用于当您按下后退button或以其他方式更改后台。
不过,我做了一些稍微不同的事情。 我有一个基础片段及其派生片段上的后台更改侦听器设置,并且此代码位于侦听器中:
Fragment f = getActivity().getSupportFragmentManager().findFragmentById(R.id.container); if (f.getClass().equals(getClass())) { // On back button, or popBackStack(), // the fragment that's becoming visible executes here, // but not the one being popped, or others on the back stack // So, for my case, I can change action bar bg color per fragment }
也许最简单的方法是:
public MyFragment getVisibleFragment(){ FragmentManager fragmentManager = MainActivity.this.getSupportFragmentManager(); List<Fragment> fragments = fragmentManager.getFragments(); for(Fragment fragment : fragments){ if(fragment != null && fragment.getUserVisibleHint()) return (MyFragment)fragment; } return null; }
它为我工作
使用事件总线(如Otto , EventBus或RxJava总线 )在这些情况下特别方便。
尽pipe这种方法并不一定会把当前可见的片断作为一个对象(虽然这也可以做,但会导致更长的调用链),但它允许您对当前可见的片断执行操作(通常是您想要知道当前可见的片段)。
- 确保你尊重片段生命周期,并在适当的时候注册/注销事件总线
- 在您需要知道当前可见的片段并执行一组操作的时候。 用活动巴士拍摄一个活动。
所有在公交车上注册的可见碎片都将执行必要的操作。
有点奇怪,但我看着FragmentManager $ FragmentManagerImpl和下面的工程对我来说:
public static Fragment getActiveFragment(Activity activity, int index) { Bundle bundle = new Bundle(); String key = "i"; bundle.putInt(key,index); Fragment fragment=null; try { fragment = activity.getFragmentManager().getFragment(bundle, key); } catch(Exception e){} return fragment; }
获得第一个活动片段使用0作为索引
public Fragment getVisibleFragment() { FragmentManager fragmentManager = getSupportFragmentManager(); List<Fragment> fragments = fragmentManager.getFragments(); if(fragments != null) { for (Fragment fragment : fragments) { if (fragment != null && fragment.isVisible()) return fragment; } } return null; }
这对我有用。 在迭代片段列表之前,您需要执行空检查。 可能有一个场景,没有碎片加载在堆栈上。
可以将返回的片段与要放入堆栈的片段进行比较。
请尝试这种方法…..
private Fragment getCurrentFragment(){ FragmentManager fragmentManager = getSupportFragmentManager(); String fragmentTag = fragmentManager.getBackStackEntryAt(fragmentManager.getBackStackEntryCount() - 1).getName(); Fragment currentFragment = getSupportFragmentManager() .findFragmentByTag(fragmentTag); return currentFragment; }
您可以使用以下代码获取当前片段
FragmentClass f = (FragmentClass)viewPager.getAdapter().instantiateItem(viewPager, viewPager.getCurrentItem());
您可以添加一个类variablesselectedFragment,并且每次更改片段时都会更新该variables。
public Fragment selectedFragment; public void changeFragment(Fragment newFragment){ FragmentManager fragMgr = getSupportFragmentManager(); FragmentTransaction fragTrans = fragMgr.beginTransaction(); fragTrans.replace(android.R.id.content, newFragment); fragTrans.addToBackStack(null); fragTrans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); fragTrans.commit(); //here you update the variable selectedFragment = newFragment; }
那么你可以在你想要的地方使用selectedFragment
你好,我知道这是一个很老的问题,但我想分享我自己的解决scheme..
为了获得用户浏览的片段列表,我创build了一个辅助类:
public class MyHelperClass{ private static ArrayList<Fragment> listFragment = new ArrayList<>(); public static void addFragment(Fragment f){ if(!existFragment(f)) { listFragment.add(f); } } public static void removeFragment(){ if(listFragment.size()>0) listFragment.remove(listFragment.size()-1); } public static Fragment getCurrentFragment(){ return listFragment.get(listFragment.size()-1); } public static int sizeFragments(){ return listFragment.size(); } private static Boolean existFragment(Fragment f){ Boolean ret = false; for(Fragment fragment : listFragment){ if (fragment.getClass() == f.getClass()){ ret = true; } } return ret; }
并进入主Activity,我重写onAttachFragment方法
@Override public void onAttachFragment(Fragment f) { super.onAttachFragment(f); MyHelperClass.addFragment(f); }
还有,我重写onBackPressed方法:
@Override public void onBackPressed() { General.removeFragment(); if(General.sizeFragments()>0){ Fragment fragment = null; Class fragmentClass = General.getCurrentFragment().getClass(); try { fragment = (Fragment) fragmentClass.newInstance(); fragment.setArguments(General.getCurrentFragment().getArguments()); } catch (Exception e) { e.printStackTrace(); } fragmentManager.beginTransaction().replace(R.id.flContent, fragment).commit(); }else{ super.onBackPressed(); } }
所以通过这种方式你可以随时用MyHelperClass.getCurrentFragment()获得活动片段
我希望这对任何人都有帮助
问候
以及我认为你想看看在哪个片段我猜我有一个溶剂我不认为它是最好的,但它的工作首先在所有
你应该创build它扩展Fragment的父代片段
public class Fragment2 extends Fragment { private static position; public static int getPosition() { return position; } public static void setPosition(int position) { FragmentSecondParent.position = position; } }
第二
你应该扩展它在每个片段,并在每一个onCreateView写入
setPosition(//your fragmentposition here)
第三
在那里你想得到你应该的当前片段
写这个
Fragment2 fragment= (Fragment2) getSupportFragmentManager() .findFragmentById(R.id.fragment_status); int position = fragment.getPosition(); if(//position condition) { //your code here }
这是最好的方法:
android.app.Fragment currentFragment=getFragmentManager().findFragmentById(R.id.main_container); if(currentFragment!=null) { String[] currentFragmentName = currentFragment.toString().split("\\{"); if (currentFragmentName[0].toString().equalsIgnoreCase("HomeSubjectFragment")) { fragment = new HomeStagesFragment(); tx = getSupportFragmentManager().beginTransaction(); tx.replace(R.id.main_container, fragment); tx.addToBackStack(null); tx.commit(); } else if(currentFragmentName[0].toString().equalsIgnoreCase("HomeStagesFragment")) { new AlertDialog.Builder(this) .setMessage("Are you sure you want to exit?") .setCancelable(false) .setPositiveButton("Yes", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { finish(); } }) .setNegativeButton("No", null) .show(); } }
不要忘记在标题中定义这个:
private Fragment fragment; FragmentTransaction tx;
这是获取当前片段的简单方法..
getFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() { @Override public void onBackStackChanged() { currentFragment = fragmentManager.findFragmentById(R.id.content); if (currentFragment != null && (currentFragment instanceof LoginScreenFragment)) { logout.setVisibility(View.GONE); } else { logout.setVisibility(View.VISIBLE); } } });
如果您使用支持库v13,则此问题已解决,您应该简单地覆盖:
@Override public void setUserVisibleHint(boolean isVisibleToUser) { // TODO Auto-generated method stub super.setUserVisibleHint(isVisibleToUser); }
事情是,你不能混合两者,因为这个片段与版本4的片段类不兼容。
如果您不是,而且您正在使用V4支持库,请将setPrimaryItem方法覆盖到您的FragmentStatePagerAdapter。
我用这个来更新大列表中的Actionbat标题。