My question is not easy to describe, but I will do my best:
On my tablet-app I have one activity with a listFragment A on left side and a detailFragment B on right side. So when I click an item on the list, the detailFragment shows the proper details of the chosen (list) item.
Now when I click a button on my detailFragment B. the fragment gets swapped with a new Fragment from type infoFragment. The listFragment on left side stays as it is.
So now, when I click another item on the List, I want the infoFragment to vanish and get a detailFragment once again.
My problem is, that i need some kind of check if currently there is an infoFragment or a detailFragment displayed. So that I can either just refresh the detailFragment OR stop the infoFragment and build a new detailFragment.
idea:
if ( //detailFragment is active ) {
updateContent();
}
else {
FragmentManager.buildDetailFragment();
}
have been fiddling for hours now, any help is appreciated!!
How can i figure it out whether there is a detailFragment or listFragment displayed?
edit:
i change my detailFragment with the infoFragment here:
FragmentManager fm = getFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.details_fragment);
fragment = new InfoFragment();
fm.beginTransaction()
.replace(R.id.details_fragment, fragment)
.commit();
When you add a Fragment to your fragment manager with a FragmentTransaction you can specify a key value. You can then findFragmentByTag which will determine if the Fragment with that key value has been added to the fragment manager.
So long as you are not using a ViewPager or some other structure where multple fragments are added at once, searching for whether your fragment manager contains a fragment by tag will let you know which is currently displayed. You can then use the results of that search to update the fragment since the result is a reference to the fragment itself.
This means you can pass data from the FragmentActivity to the fragment directly by calling any publicly accessable fragment methods. For example
Fragment displayedFragment = fragmentManager.findFragmentByTag(TAG);
if(displayedFragment != null){ //null if no fragment with tag value
displayedFragment.updateList() //public method within fragment
}
MyFragment myFragment = (MyFragment)getFragmentManager().findFragmentByTag("MY_FRAGMENT");
if (myFragment.isVisible()) {
// add your code here
}
From Here
FragmentManager fm = getFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.content_id);
now we can get the fragment name by getClass
fragment.getClass().getSimpleName()
You can get class of fragment and check which one it exactly is by calling getClass().
Related
I am using navigation drawer and it is simple to use. I am not providing the complete code but providing you detail which could be easy for you to understand my problem. I am using fragments these are about 8 in numbers and I am replacing them with one an other. But here comes a problem
I am replacing them on click event of the navigation drawer. but there are two main problems
After replacement , I can see the previous fragment in the background. does replace method just call the new fragment over it ? if yes then what should I do to old fragment not be visible in the background of my new fragment.
When I click navigation drawer Item , it loads the specific fragment successfully. but keeping in that fragment when I click to that specific item again it loads this fragment again and again. For example if drawer item num 3 opens fragment MyBook , then by clicking item num three 2 or many times would open fragment that much time.
So please some one answer me how to cure my app for such kind of actions which I described above.
I tried like this. Its working fine me
FragmentManager frgmanager = getFragmentManager();
frgmanager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
FragmentTransaction frgTransaction = frgmanager.beginTransaction();
if(subitem.equalsIgnoreCase("subitem")){
Frag1 frg1 =new Frag1(mCtx);
frgTransaction.replace(R.id.inflate_layout, frg1);
}else if(subitem1.equalsIgnoreCase("subitem1")){
Frag2 frg2 =new Frag2(mCtx);
frgTransaction.replace(R.id.inflate_layout, frg2);
}else{
Frag2 frg3 =new Frag3(mCtx);
frgTransaction.replace(R.id.inflate_layout, frg3);
}
frgTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
frgTransaction.commit();
you can use addtobackstack in fragmentstranstion object.like
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.bodyfragment, new AnotherFragment());
transaction.addtoBackStack(null).commit();
Use replace-method of FragmentTransaction instead of add (http://developer.android.com/guide/components/fragments.html#Transactions)
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.bodyfragment, new AnotherFragment());
transaction.commit();
To avoid re-instantiating the fragment, keep track of the current open fragment and only do a fragment transaction, if we next-to-be-opened fragment is a different one than the current.
This may achieved like the following:
class MyActivity ... {
private String currentFragment;
private void openNewFragment(Fragment fragment) {
String newFragment = fragment.getClass().getSimpleName();
if (newFragment.equals(currentFragment)){
// new fragment already shown
return;
}
// Fragment transaction etc here:
}
}
Note that this only compares fragments based in their class name. Sometimes this might not be unique, e.g. if there is a DetailFragment class which displays information about an entity. Which entities details to show may depend on intent arguments.
The above code however will then prevent opening DetailFragment for Entity=1 if currently details for Entity=2 are shown. For these scenarios the information about the fragment kept needs to be extended (e.g. storing a Reference or WeakReference to the fragment instance itself).
I have a passed data from FragmentActivity to multiple fragments like this
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("userid", logindata);
firstfragment.setArguments(bundle);
From fragment Activity to secong fragment i have pass data like this.
secondfragment.setArguments(bundle);
when i click first fragment it's working next click second fragment it's also working fine but again click first fragment the illegal state exception Fragment already active exception will be occur. How to reslove this problem please help me. Thanks in advance.
illegal state exception Fragment already active
setArguments only called before the fragment has been attached to its activity otherwise through Fragment already active Exception. so call setArguments to should need to remove fragment is already present and use replace to add fragment again.
Remove fragment before adding new :
Fragment fragment =
getSupportFragmentManager().findFragmentByTag("firstfragment");
if(fragment != null)
getSupportFragmentManager().beginTransaction()
.remove(fragment).commit();
Now add new fragment :
firstfragment.setArguments(bundle);
transactn = mngr.beginTransaction();
transactn.replace(R.id.content_frag,firstfragment).
addToBackStack("firstfragment").commit();
Try this:
createFragment(new YourFragment());
private void createFragment(Fragment fragment) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.container_app, fragment).commit();
}
I have an Activity with ListView, when clicking on a list item opens a new fragment.
Do I need to create a new fragment every time like this?
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.root_layout,new MyFragment());
Or will be enough to create a fragment once and then use it?
in activity:
MyFragment myFragment = new MyFragment();
......
in onItemClickListener:
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.root_layout,myFragment);
It depends on your case. In most cases every list item opens a different fragment (with different data). Then you have to make a static newInstance(Data mySerializableData) method in your fragment, use default constructor inside of it, pass data over Fragment arguments See DetailFragment and use fragmentTransaction.replace() in your activity to add this fragment.
When you dont want your fragment to be changed you can create it only once as you say but there is no need of adding it on every item click. So one creation and only one add.
No, you don't need to create it every time. First, instead of using "add", use "replace". If there is no fragment in fragment manager, your fragment will be added, instead it will be replaced. If you use "add", then you could accidentally add more than one fragment.
You should check for the fragment in the fragment manager and call methods for content updates.
Example:
myFragment = (MyFragment) fragmentManager.findFragmentById(R.id.my_fragment);
if (myFragment == null) {
myFragment = MyFragment.getInstance(someDataIfNeeded);
fragmentManager.beginTransaction().replace(R.id.my_fragment, myFragment).commit();
} else {
myFragment.updateFragmentContent(someData);
}
check instance of that fragment everytime like this-
In your fragment class -
public static final MyFragment newInstance()
{
MyFragment f = new MyFragment();
return f;
}
and in your activity when you want to create fragment -
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.root_layout,MyFragment.newInstance());
this is well n good manner...
I have A Navigation Drawer with list of items , and on click on a list item opens
another list of events(with A custom list adapter)[1 st fragment].
And a click on any of any of that list item i want to open a fragment which displays its details[2 st fragment] .
So i want to transfer position of item click from 1st frag to 2 nd frag ,
i have static data in 2 nd frag , how do i transfer that position ?
I tried with interface ,
but with every time i do anything i get error in logcat as 1st fragment is not attached to Main activity .
And i have created layout(and referred them as fragment) and there is NO so no Id to get in mainactivity in 'getFragmentById' ? Thanks .
Pass data in constructor of fragment
FragmentManager fm = SliderActivity.this
.getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
HomeFragment fragment = new HomeFragment(your_data);
ft.replace(R.id.content_fragment, fragment, getResources()
.getString(R.string.homeText));
ft.commit();
in HomeFragment set the value from constructor
HomeFragment(String value){
this.value=value;
}
You can use getActivity() from a fragment to find the FragmentActivity in which the fragment resides.
Then you can use FragmentActivity.findFragmentByTag() to find the other fragment in this Actvity. `
I have a class derived from FragmentPagerAdapter and user swiping works fine (4 tabs), but I would like to show a page/tab/fragment from code. For example, when user taps a textview, I would like to switch to a specific fragment.
I've tried the following without success:
public void onClockClick(View v)
{
FragmentManager fm = getFragmentManager();
if (fm != null) {
fm.beginTransaction()
.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out)
.show(mainFragment)
.commit();
}
}
Am I barking up the wrong tree?
Well, if you know the position of the fragment you want to show then you can simply do: pager.setCurrentItem(pos)
This will automatically animate to the fragment at the desired position. Simple.
If you want to add another fragment to the existing FragmentPagerAdapter, then you'll need to first add the fragment's instance to that adapter and then call notifiyDataSetChanged on it.