Here's my Flow/Structure:
Activity
Fragment
Same Fragment within it.
I have overriden removeCurrentFragment() method which does go back functionality by removing Fragment by ID as follows -
#Override
public void removeCurrentFragment() {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
Fragment currentFrag = getSupportFragmentManager().findFragmentById(R.id.fragment);
if (currentFrag != null)
transaction.remove(currentFrag);
transaction.commit();
}
It seems, when this happens, as ID of both fragment is same, it creates blank view.
If more details are required, please feel free to ask in comments. I will edit question as per required details.
I thought it was related to remove fragment, But I made new fragment with separate XML, still I am having the same issue.
I have parent fragment with pagination (as I need horizontal page scroll) in it have the child fragment, when clicking on child fragment button new fragment is replaced so when it is removed the X and Y of the child fragment is also disturbed.
here is the before and after screenshot of the x and y axis of child fragment.
Before
After
can any one suggest what could be the issue?
You have to use a tag to load the Fragment, and then use that same tag again to remove it.
For example, to add the Fragment:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
fragmentManager.popBackStack(tag, androidx.fragment.app.FragmentManager.POP_BACK_STACK_INCLUSIVE);
ft.setCustomAnimations(R.anim.enter, R.anim.exit);
ft.add(containerId, fragment, tag);
ft.addToBackStack(tag);
ft.commit();
To remove it, again use the same tag:
if (fragmentManager.findFragmentByTag(currentTag) != null) {
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.remove(fragmentManager.findFragmentByTag(currentTag));
ft.commit();
}
Related
I have a Activity where I load 3 fragments one after another
FragmentA
FragmentB
FragmentC
Flow is Like this I have used Adding fragment one above another
Start-Activity -----> Load FragmentA ----> Load FragmentB ----> Load FragmentC
What I am trying to do now is:
Now assuming now FragmentC is the top fragment shown
I want to find the FragmentA from the stack and just show it instead of creating a fragmentA all over again
Code I have used to add fragmentA is for Example:
Fragment fragment = null;
FragmentTransaction fragmentTransaction = null;
fragment = new FragmentA();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.addToBackStack(FragmentA.class.getSimpleName());
fragmentTransaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
fragmentTransaction.add(R.id.container, fragment, FragmentA.class.getSimpleName());
if(fragment!=null && fragmentTransaction!=null){
fragmentTransaction.commitAllowingStateLoss();
}
Look at FragmentManager.getBackStackEntryAt method, from there you can go back to any fragment of your history…
Loop through the back stack entries, meanwhile, if you find any matching Fragment by id or tag, just pop back stack inclusive with fragment A's name/tag so that the fragment A is just displayed rather than adding once again.
The example code to retrieve a fragment by Tag would look like this
FragmentA frA = getSupportFragmentManager().findFragmentByTag(FragmentA.class.getSimpleName());
and if it's not null you can reuse it in your container
if(frA != null) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager.beginTransaction();
fragmentTransaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
//you could add this transactionn to backstack again here if you want to be able to pop it later
fragmentTransaction.add(R.id.container, frA, FragmentA.class.getSimpleName());
} else {
//if your fragment is null as it was destroyed previously you can create a new one here
}
You are giving a tag, fragmentTransaction.addToBackStack(FragmentA.class.getSimpleName()); to the transaction , you can use the same tag to find the fragment in the backstack, before creating a new frgament, check the backstack for the fragment using findFragmentByTag on the fragment manager, if it exist, the method returns the fragment otherwise null
try it!
val fm: FragmentManager? = fragmentManager
for (entry in 0 until fm.getBackStackEntryCount()) {
Log.i(TAG, "Found fragment: " + fm.getBackStackEntryAt(entry).getId())
}
I have two fragments the first fragment contains list of linear layouts and the whole fragment is in scroll view the second fragment is added and the first is hidden on choosing item from the first.
The problem is the second fragment is created scrolled down if the first fragment was scrolled down.
I tried the ways to force second fragment to be scrolled to (0,0) but failed.
the code used to add the second fragment
public void setActionOnClick(String id) {
CommentFragment frag = new CommentFragment();
Bundle bundle = new Bundle();
bundle.putString("id", id);
bundle.putString("TAG", TAG_NEWS_STORY);
((MainActivity) getActivity()).setCurrentTag(TAG_NEWS_STORY);
frag.setArguments(bundle);
android.support.v4.app.FragmentTransaction fragmentTransaction =
getActivity().getSupportFragmentManager().beginTransaction();
fragmentTransaction.setCustomAnimations(android.R.anim.fade_in,
android.R.anim.fade_out);
fragmentTransaction.add(R.id.main_content, frag, TAG_NEWS_STORY);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
on Attach of second fragment the first fragment is hidden.
I don't want to use fragmentTransaction.replace because there are calls to the api which I don't want to reload.
this is an old question but. probably your fragment place_hoder is inside an scrollview.
just check if R.id.main_content is in a scrollview or not.
you should add the ScrollView to the fragment-layout instead of instantiating the fragment inside one
Before this:
android.support.v4.app.FragmentTransaction fragmentTransaction =
getActivity().getSupportFragmentManager().beginTransaction();
Add code to remove old fragment:
getSupportFragmentManager().beginTransaction().remove(yourOldFragment).commitAllowingStateLoss();
Where am i going wrong. I just want to check if the fragment with the given ProductId is already available in the BackStack;
If yes than dont add the new Fragment otherwise add the current fragment to the backstack.
public void showThisFragment(Fragment newFragment,int productId){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.am_fragment_holder, newFragment);
if(fragmentManager.findFragmentByTag(productId+"")==null){
fragmentTransaction.addToBackStack(productId+"");
}else{
//TODO fragment already present
//So dont add to the back stack
}
fragmentTransaction.commit();
}
please help!
There is no tag added to replaced fragment. You should use three argument replace method. I did not test it so tell me if I am right.
fragmentTransaction.replace(R.id.am_fragment_holder, newFragment, String.valueOf(productId));
I have a multiple-dialog-fragment layout. In the large layout, I show them as dialogs and there's no problem:
fragment.show(fragmentManager, "fragment_dialog");
But in normal devices, I am using a fragment transaction and replace fragments as below:
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
transaction.replace(R.id.fragment_container, fragment).addToBackStack(null).commit();
The problem is that in normal devices, when I press the menu button twice (or more), the same fragment will be shown over the previous one. Is there a way to find out which fragment is visible right now and prevent it from opening again?
First of all, add tag to when you replace
transaction.replace(R.id.fragment_container, fragment, "fragment_foo")
.commit(); // etc
then make a control
if (fragmentManager.findFragmentByTag("fragment_foo") == null){
// do something
}
You can find fragment by tag:
if (fragmentManager.findFragmentByTag("fragment_dialog") == null) {
//show dialog here
}
// Replace fragmentCotainer with your container id
Fragment currentFragment = fragmentManager.findFragmentById(R.id.fragmentCotainer);
// Return if the class are the same
if(currentFragment.getClass().equals(fragment.getClass())) return;
How can I reset or reload a fragment container, to make it empty.
I have a master detail view and I want to reset the detail container to empty on a menu item click.This works in some cases and does not in some.
NullFragment fragment = new NullFragment();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
fragmentTransaction.replace(R.id.item_detail_container,
fragment);
int count = fragmentManager.getBackStackEntryCount();
fragmentManager.popBackStackImmediate(count, 0);
fragmentTransaction.commit();
Usually you simply remove the fragment from it.
For example do something like
getFragmentManager().beginTransaction().remove(getFragmentManager().findFragmentById(R.id.your_container)).commit();
this will remove the fragment from the your_container holding it.
This gets the fragment currently present in your_container
getFragmentManager().findFragmentById(R.id.your_container)
and this remove the fragment
getFragmentManager().beginTransaction().remove(fragment).commit();
EDIT
Also sometimes it is useful to ensure all transactions are performed and finished, this can be done by using
getFragmentManager().executePendingTransactions();