I am working fragment, I replaced FragmentA by fragment B.it's working perfect,but when I press back button I can't back Fragment A.
I tried to override onKeyDown method,but I can't override this method in fragment
this is a my source
CategoryViewPager fragment1 = new CategoryViewPager();
FragmentTransaction ft = getSupportFragmentManager()
.beginTransaction().addToBackStack("method");
ft.setCustomAnimations(R.anim.trans_left_in, R.anim.trans_left_out);
ft.replace(R.id.content_frame, fragment1, "fragment2");
ft.commit();
when I use CategoryViewPager and click back button I can't go back(fragment wich i replaced this fragment)
how can I solve my problem?
Call addToBackStack() before you commit the transaction:
getSupportFragmentManager().beginTransaction()
// Add this transaction to the back stack
.addToBackStack()
.commit();
No need to use tag in your case. just use like this
/*
* Add this transaction to the back stack.
* This means that the transaction will be remembered after it is
* committed, and will reverse its operation when later popped off
* the stack.
*/
fragmentTransaction.addToBackStack(null);
It is better to handle back button press through your activity unless your actvity host large number of fragments.When you press back button inside your fragment onBackPressed() method of your activity will be called which can be overridden and handled..So handling back button for fragments can be done in this way..
MainActvity
public static boolean isMainActivityShown ;
public static boolean isFragment1Shown=false ;
public static boolean isFragment2Shown=false ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
isMainActivityShown=true //inside onCreate method put isMainActivityShown true
.
.
.
}
.
.
Fragment currentFragment = new Fragment1();
isMainActivityShown=false; //when moving to fragment1
isFragment1Shown=true;
frgManager = getFragmentManager();
frgManager.beginTransaction().replace(R.id.content_frame, currentFragment)
.commit();
#Override
public void onBackPressed() {
if(isMainActivityShown)
{
finish();
}
else if(isFragment1Shown)
{
//write the code to handle back button when you are in Fragment1
}
else if(isFragment2Shown)
{ //When you are in Fragment 2 pressing back button will move to fragment1
Fragment currentFragment = new Fragment1();
isFragment2Shown=false;
isFragment1Shown=true;
FragmentManager frgManager;
frgManager = getFragmentManager();
frgManager.beginTransaction().replace(R.id.content_frame, currentFragment)
.commit();
}
}
Fragment1
Fragment currentFragment = new Fragment2();
MainActivity.isFragment1Shown=false;
MainActivity.isFragment2Shown=true;
frgManager = getFragmentManager();
frgManager.beginTransaction().replace(R.id.content_frame, currentFragment)
.commit();
Check this link
Check the addToBackStack(String name) method. This should solve your problem.
Related
I am having trouble going back to previous fragment on backpress from current fragment.
I have Two fragments and i navigate to second fragment on click and when i try to click back from the second fragment, i want to go back to the previous fragment but instead the app exits on backpress. below is the code i am using..
Fragment1 calling second fragment
UserFragment frag = new UserFragment()
FragmentTransaction transaction = getFragmentManager().beginTransaction();
frag.setArguments(bundle);
transaction.addToBackStack("UserActivity");
transaction.replace(android.R.id.content, frag, "UserActivity").addToBackStack(null);
transaction.commit();
In second Fragment i have implemented an interface OnBackpress and over riding the below method
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() != 0) {
if(getFragmentManager().findFragmentByTag("UserActivity") != null){
Log.e("UserActivity",getFragmentManager().findFragmentByTag("UserActivity").toString());
getFragmentManager().popBackStack();
};
}
}
But on back press the app exits. Instead i want to go back to previous fragment. What mistake am i doing? please help. thanks
You need to add you first fragment to back stack properly, you are doing it wrong in your first part of the code.
Use the following code instead.
UserFragment frag = new UserFragment()
FragmentTransaction transaction = getFragmentManager().beginTransaction();
frag.setArguments(bundle);
transaction.addToBackStack("UserActivity");
transaction.replace(android.R.id.content, frag, "UserActivity");
transaction.commit();
Also there is no need to add any code in your onBackPressed after above change.
First, you need to add your fragments to the backstack:
public static void addFragment(FragmentManager fragmentManager, Fragment fragment, int id){
fragmentManager.beginTransaction().add(id, fragment).addToBackStack(null).commit();
}
Then you need to override the onBackPressed, which is a method gets called whenever a user clicks the back button:
#Override
public void onBackPressed() {
super.onBackPressed();
if(getSupportFragmentManager().getBackStackEntryCount() == 0){
button.setVisibility(View.VISIBLE);
}
}
please change to add() instead of replace() in your code..
UserFragment frag = new UserFragment()
FragmentTransaction transaction = getFragmentManager().beginTransaction();
frag.setArguments(bundle);
transaction.addToBackStack("UserActivity");
transaction.add(android.R.id.content, frag, "UserActivity").addToBackStack(null);
transaction.commit();
This will solve your problem.
I have three fragments A、B、C , my process is A to B to C .
I want that when i change to C and call back to B , B can switch to A immediately.
So i set the switch fragment function on onResume on B .
But the result is that i always land up on A fragment , because when i change to B the function onResume be called
I know i can remove transaction.addToBackStack(null); then i can C to A
, but it will cause some bug in my project , so i try to keep it.
Is any function only start when C call back to B ?
Thanks in advance.
Below is my switch function:
private void switchFragment(Fragment fragment) {
FragmentManager manager = getActivity().getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.mainFrame, fragment, null);
transaction.addToBackStack(null);
transaction.commit();
}
I try to add onResume on fragment B , but it will be A to B , and then B go back to A immediately.
#Override
public void onResume() {
super.onResume();
//go back to fragment A
switchFragment(NewHomepage.newInstance());
}
your fragment transition code should be:
private void switchFragment(Fragment fragment) {
FragmentManager manager = getActivity().getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.mainFrame, fragment, null);
transaction.addToBackStack("fragment_name_tagX");
transaction.commit();
}
above, X is your fragment. After you navigate from fragment A to C using above function, your stack will have every fragment with name 'fragment_name_tag' that you assign.
#Override
public void onBackPressed() {
FragmentManager fm = getActivity().getSupportFragmentManager();
int count = fm.getBackStackEntryCount();
if (count != 0) {
fm.popBackStack ("fragment_name_tagB",FragmentManager.POP_BACK_STACK_INCLUSIVE);
} else {
super.onBackPressed();
}
}
So when you now press back button from fragment C, it will go on fragment A.
I am creating an application with multiple fragments. I have four fragments fragment1, fragment2, fragment3, fragment4. I am moving from different orders like f1 -> f2 -> f4 -> f3 -> f1 or any other order. But when I click the back button from each fragment I need to go to the previous fragment. How to handle this.
Edit 1:
I already tried
FragmentManager fm = ((Activity) context).getFragmentManager();
for (int i = 0; i < fm.getBackStackEntryCount(); i++) {
fm.popBackStack();
}
Which is not help me to solve my issue.
Sample code of Manage Fragment back stack
private Stack<Fragment> stack = new Stack<Fragment>();
public void pushFragments(Fragment fragment, boolean shouldAnimate,
boolean shouldAdd) {
drawerClose = false;
if (shouldAdd)
stack.push(fragment);
this.changeFragment = fragment;
invalidateOptionsMenu();
changeFragment(fragment, shouldAnimate, false);
}
public void popFragments() {
/*
* Select the second last fragment in current tab's stack.. which will
* be shown after the fragment transaction given below
*/
Fragment fragment = stack.elementAt(stack.size() - 2);
// / pop current fragment from stack.. /
stack.pop();
/*
* We have the target fragment in hand.. Just show it.. Show a standard
* navigation animation
*/
this.changeFragment = fragment;
invalidateOptionsMenu();
changeFragment(fragment, false, true);
}
private void changeFragment(Fragment fragment, boolean shouldAnimate, boolean popAnimate) {
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
if (shouldAnimate)
ft.setCustomAnimations(R.anim.slide_in_right,
R.anim.slide_out_left);
if (popAnimate)
ft.setCustomAnimations(R.anim.slide_in_left,
R.anim.slide_out_right);
ft.replace(R.id.content_frame, fragment);
ft.commit();
}
//On BackPress just check this thing
private void backManage() {
if (stack.size() > 1) {
popFragments();
}
}
Use addToBackStack(String tag), while committing the fragment to add the fragment into the stack of your application:
getFragmentManager().beginTransaction().replace(fragmentContainer.getID(), fragment)
.addToBackStack(null).commit();`
on Activity
#Override
public void onBackPressed() {
if(check_if_backstack_is_null)
super.onBackPressed();
else
{
popupFromBackstack();
}
}
You should override onBackPressed method:
#Override
public void onBackPressed() {
if (fragment != null && fragment.getChildFragmentManager().getBackStackEntryCount() > 0){
fragment.getChildFragmentManager().popBackStack();
}else {
super.onBackPressed();
}
}
For this you can set addToBackStack to fragment transation and then call commit.
By calling addToBackStack(), the replace transaction is saved to the back stack so the user can reverse the transaction and bring back the previous fragment by pressing the Back button.
If you add multiple changes to the transaction (such as another add() or remove()) and call addToBackStack(), then all changes applied before you call commit() are added to the back stack as a single transaction and the Back button will reverse them all together.
You just need to add addToBackStack(null) by FragmentTransaction.
when you are calling next Fragment just add this method with null parameter.
Like this.
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(..............);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
Use this lines of code for it:-
#Override
public void onBackPressed() {
if ( getSupportFragmentManager().getBackStackEntryCount() > 0){
fm.popBackStack();
}else {
super.onBackPressed();
}
}
To get the backStack functionality in your fragmentthan you should have use the .addToBackStack(null) , while performing the fragment transaction like below:-
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.YOUR_CONTAINER, YOUR_FRAGMENT,"TAG")
.addToBackStack(null) /// IT IS NECESSARY TO GET THE BACK STACK PROPERTY IN YOUR FRAGMENT
.commitAllowingStateLoss();
I have a MainActivity and two fragments in this activity like SignupFragment and MenuFragment.First i add SignupFragment in MainActivity:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, new SignupFragment());
ft.commit();
Important: i don't need to store this fragment in backstack
Now from SignupFragment i replace MenuFragment
FragmentManager fm = getActivity().getSupportFragmentManager();
fm.beginTransaction()
.replace(R.id.content_frame, new MenuFragment(), FRAGMENT_TAG)
.addToBackStack(null)
.commit();
Important: i need to add this fragment to backstack.For example i have another framgent like AnotherFragment and i replace it in MenuFragment and add that to backstack too and when user in AnotherFragment pressed back button i want to return him to MenuFragment
I override OnBackPressed in MainActivity and also add a listener for OnBackStackChangeListener:
FragmentManager fm = getSupportFragmentManager();
fm.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
if (getSupportFragmentManager().getBackStackEntryCount() == 0)
finish();
}
});
Problem When i'm in MenuFragment and press back button then i go back to SignupFragment andOnCreateView called for a little moment and then finish() called.( when i press back button , SignupFragmen's view shows for a moment and then destroyed )
Questions
1- How can i prevent to returning back to SignupFragment ?
2- Why OncreateView called in SignupFragment when back button pressed?
Thanks in advance.
I found my problem.
when i pressed back button, OnBackPressed called and also MenuFragment is visible yet then onCreateView of SignupFragment called and then onBackStackChanged called , So i check this in OnBackPressed:
if(getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG).isVisible()){
finish();
}
I have a Layout were i keep swapping my two Fragments MainFragment and SecondFragment
I have an Activity Level Button and with its onclick I swap these fragments in the layout.
But I need to keep the same instance of FragA every time I switch back from FragB.
Below is the code that i used but the application crashes with a NullPointerError.
// When journey button menu is clicked [INSIDE THE MAIN ACTIVITY]
OnClickListener journeyBtnClick = new OnClickListener() {
#Override
public void onClick(View arg0) {
if(currentType==0){
InitThisFragment(1);
}else{
InitThisFragment(0);
}
}
};
private int currentType=0;
public void InitThisFragment(int type){
if(type==0){
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
//get the previously added MainFragment from the BackStack
Fragment mainFragment= getSupportFragmentManager().findFragmentByTag("main");
transaction.replace(R.id.abs_fragment_container,mainFragment);
transaction.setTransition(FragmentTransaction.TRANSIT_ENTER_MASK);
transaction.commit();
}else{
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.abs_fragment_container, new SecondFragment());
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
transaction.commit();
}
currentType=type;
}
Before this I initialize the MainFragment in the OnCreate() of my Activity class;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.abs_fragment_container, new MainFragment());
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); //add MainFragment in the BackStack
transaction.addToBackStack("main");
transaction.commit();
}
I the user clicks the Button
Initiate a New Fragment of the SecondFragment [No History of the
Previous Fragment]
Go Back to the MainFragment [In same state as it was while leaving
it]
Please help!
Thanks in advance.
If I have understood what you want to do, you can just call "FragmentManager.popBackStack()" if you are in the secondFragment.
So:
public void InitThisFragment(int type){
if(type==0){
getFragmentManager().popBackStack();
}else{
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.abs_fragment_container, new SecondFragment());
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
transaction.commit();
}
currentType=type;
}
Put "main" tag in replace method.
transaction.replace(R.id.abs_fragment_container, new MainFragment(),"main");
tag parameter would work different for addToBackStack and replace method. According to android for tag parameter :
addToBackStack: An optional name for this back stack state, or null.
replace: Optional tag name for the fragment, to later retrieve the fragment with FragmentManager.findFragmentByTag(String).