Get the current fragment object
AndroidAndroid FragmentsAndroid Problem Overview
In my main.xml
I have
<FrameLayout
android:id="@+id/frameTitle"
android:padding="5dp"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:background="@drawable/title_bg">
<fragment
android:name="com.fragment.TitleFragment"
android:id="@+id/fragmentTag"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</FrameLayout>
And I'm setting fragment object like this
FragmentManager fragmentManager = activity.getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Fragment newFragment = new FragmentType1();
fragmentTransaction.replace(R.id.frameTitle, casinodetailFragment, "fragmentTag");
// fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
It is setting different types of Fragment objects (FragmentType2,FragmentType3,...
) at different time. Now at some point of time I need to identify which object is currently there.
In short I need to do something like this:
Fragment currentFragment = //what is the way to get current fragment object in FrameLayout R.id.frameTitle
I tried the following
TitleFragment titleFragmentById = (TitleFragment) fragmentManager.findFragmentById(R.id.frameTitle);
and
TitleFragment titleFragmentByTag = (TitleFragment) fragmentManager.findFragmentByTag("fragmentTag");
But both the objects (titleFragmentById and titleFragmentByTag ) are null
Did I miss something?
I'm using Compatibility Package, r3
and developing for API level 7
.
findFragmentById()
and findFragmentByTag()
will work if we have set fragment using fragmentTransaction.replace
or fragmentTransaction.add
, but will return null
if we have set the object at xml (like what I have done in my main.xml
). I think I'm missing something in my XML files.
Android Solutions
Solution 1 - Android
> Now at some point of time I need to identify which object is currently there
Call findFragmentById()
on FragmentManager
and determine which fragment is in your R.id.frameTitle
container.
If you are using the androidx
edition of Fragment
— as you should in modern apps — , use getSupportFragmentManager()
on your FragmentActivity
/AppCompatActivity
instead of getFragmentManager()
Solution 2 - Android
Try this,
Fragment currentFragment = getActivity().getFragmentManager().findFragmentById(R.id.fragment_container);
this will give u the current fragment, then you may compare it to the fragment class and do your stuffs.
if (currentFragment instanceof NameOfYourFragmentClass) {
Log.v(TAG, "find the current fragment");
}
Solution 3 - Android
I think you can use onAttachFragment event may be useful to catch which fragment is active.
@Override
public void onAttachFragment(Fragment fragment) {
// TODO Auto-generated method stub
super.onAttachFragment(fragment);
Toast.makeText(getApplicationContext(), String.valueOf(fragment.getId()), Toast.LENGTH_SHORT).show();
}
Solution 4 - Android
I think you should do:
Fragment currentFragment = fragmentManager.findFragmentByTag("fragmentTag");
The reason is because you set the tag "fragmentTag" to the last fragment you have added (when you called replace).
Solution 5 - Android
You can get the list of the fragments and look to the last one.
FragmentManager fm = getSupportFragmentManager();
List<Fragment> fragments = fm.getFragments();
Fragment lastFragment = fragments.get(fragments.size() - 1);
But sometimes (when you navigate back) list size remains same but some of the last elements are null. So in the list I iterated to the last not null fragment and used it.
FragmentManager fm = getSupportFragmentManager();
if (fm != null) {
List<Fragment> fragments = fm.getFragments();
if (fragments != null) {
for(int i = fragments.size() - 1; i >= 0; i--){
Fragment fragment = fragments.get(i);
if(fragment != null) {
// found the current fragment
// if you want to check for specific fragment class
if(fragment instanceof YourFragmentClass) {
// do something
}
break;
}
}
}
}
Solution 6 - Android
This is the simplest solution and work for me.
1.) you add your fragment
ft.replace(R.id.container_layout, fragment_name, "fragment_tag").commit();
2.)
FragmentManager fragmentManager = getSupportFragmentManager();
Fragment currentFragment = fragmentManager.findFragmentById(R.id.container_layout);
if(currentFragment.getTag().equals("fragment_tag"))
{
//Do something
}
else
{
//Do something
}
Solution 7 - Android
It might be late but I hope it helps someone else, also @CommonsWare has posted the correct answer.
FragmentManager fm = getSupportFragmentManager();
Fragment fragment_byID = fm.findFragmentById(R.id.fragment_id);
//OR
Fragment fragment_byTag = fm.findFragmentByTag("fragment_tag");
Solution 8 - Android
Maybe the simplest way is:
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;
}
It worked for me
Solution 9 - Android
You can create field in your parent Activity Class:
public class MainActivity extends AppCompatActivity {
public Fragment fr;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
And then inside each fragment class:
public class SomeFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
((MainActivity) getActivity()).fr = this;
}
Your 'fr' field is current fragment Object
It's working also with popBackStack()
Solution 10 - Android
I know it's been a while, but I'll this here in case it helps someone out.
The right answer by far is (and the selected one) the one from CommonsWare. I was having the same problem as posted, the following
MyFragmentClass fragmentList =
(MyFragmentClass) getSupportFragmentManager().findFragmentById(R.id.fragementID);
kept on returning null. My mistake was really silly, in my xml file:
<fragment
android:tag="@+id/fragementID"
android:name="com.sf.lidgit_android.content.MyFragmentClass"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
The mistake was that I had android:tag INSTEAD OF android:id.
Solution 11 - Android
-
Do a check (which fragment in the activity container) in the onStart method;
@Override protected void onStart() { super.onStart(); Fragment fragmentCurrent = getSupportFragmentManager.findFragmentById(R.id.constraintLayout___activity_main___container); }
-
Some check:
if (fragmentCurrent instanceof MenuFragment)
Solution 12 - Android
@Hammer response worked for me, im using to control a floating action button
final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View view) {
android.app.Fragment currentFragment = getFragmentManager().findFragmentById(R.id.content_frame);
Log.d("VIE",String.valueOf(currentFragment));
if (currentFragment instanceof PerfilFragment) {
PerfilEdit(view, fab);
}
}
});
Solution 13 - Android
If you are extending from AbstractActivity, you could use the getFragments() method:
for (Fragment f : getFragments()) {
if (f instanceof YourClass) {
// do stuff here
}
}
Solution 14 - Android
If you are defining the fragment in the activity's XML layour then in the Activity
make sure you call setContentView()
before calling findFragmentById()
.
Solution 15 - Android
If you are using the BackStack...and ONLY if you are using the back stack, then try this:
rivate Fragment returnToPreviousFragment() {
FragmentManager fm = getSupportFragmentManager();
Fragment topFrag = null;
int idx = fm.getBackStackEntryCount();
if (idx > 1) {
BackStackEntry entry = fm.getBackStackEntryAt(idx - 2);
topFrag = fm.findFragmentByTag(entry.getName());
}
fm.popBackStack();
return topFrag;
}
Solution 16 - Android
This will give you the current fragment class name -->
String fr_name = getSupportFragmentManager().findFragmentById(R.id.fragment_container).getClass().getSimpleName();
Solution 17 - Android
you can check which fragment is currently loaded by this
supportFragmentManager.addOnBackStackChangedListener {
val myFragment = supportFragmentManager.fragments.last()
if (null != myFragment && myFragment is HomeFragment) {
//HomeFragment is visible or currently loaded
} else {
//your code
}
}
Solution 18 - Android
I use the following function in Kotlin:
supportFragmentManager.fragments.run {
getOrNull(size - 1)?.let { currentFragment ->
...
}
}
Solution 19 - Android
I recently worked on an activity involving multiple fragments so thought to share the method I used here:
Firstly, I declared a function getCurrentFragment() which returned me, yeah you guessed it, the current fragment, lol.
private fun getCurrentFragment(): Fragment? {
return supportFragmentManager.findFragmentById(R.id.fragmentContainerView)
}
Then I override the onBackPressed function in the activity to define the navigation within fragments. Suppose, I wanted to show fragment 2 if user is in fragment 3 and presses back so I did something like this to achieve this
override fun onBackPressed() {
if (getCurrentFragment() is Fragment3) {
showFragment2()
} else {
super.onBackPressed()
}
}
And in showFragment2() I did something like this:
private fun showFragment2() {
val fragment = Fragment2.newInstance()
supportFragmentManager.commit {
replace(R.id.FragmentContainerView, fragment, "Add a tag here")
}
}
I think this should give better idea to people looking on how to navigate through fragments within an activity.