Should the android back button be overriden - android

I want to go back to the last fragment in the back stack, so I want to make the back button popback the stack. Should I do this? and if so, should I override onBackPressed() or onKeyDown()?
#Override
public void onBackPressed()
{
Intent intent = new Intent(this,ABC.class);
startActivity(intent);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK ) {
// do something on back.
return true;
}
return super.onKeyDown(keyCode, event);
}
My fragments aren't being added to the back stack properly for some reason
I am using this to try to go back to the previous fragment, but the order is acting strange. What exactly should I do to make the order proper?
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft){
if(teamsFrag !=null)
{
if(manage.getBackStackEntryCount() > 0)
manage.popBackStack(manage.getBackStackEntryAt(manage.getBackStackEntryCount()-1).getName(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
//ft.detach(dataFrag);
}

Short answer? No.
Long answer? If you have to ask, No.
You should set your fragments up using the fragment manager so that the back button does what you want. You shouldn't override the back button instead of implementing your stack correctly.

I want to go back to the last fragment in the back stack, so I want to make the back button popback the stack.
This is the default behavior when you use FragmentTransaction#addToBackStack() while adding new Fragments with the FragmentManager.

Related

fragment back to the end , the screen is white [duplicate]

This question already has answers here:
White screen after going back through Fragments
(2 answers)
Closed 6 years ago.
I have a MainActivity, it has a lots of Fragment under it.
I set the return mechanism transaction.addToBackStack(null);
The function like this:
public void switchFragment(Fragment fragment) {
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.mainFrame, fragment, null);
transaction.addToBackStack(null);
transaction.commit();
}
My issue is when I click the back button to the end, the FrameLayout is white
I tried to add
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (mainFrame==null)
return super.onKeyDown(keyCode, event);
}
}
It's not working. How do I avoid this white screen when I call back the Fragment to the end ? Any help would be great!
I took #ReazMushed's suggestion and changed like this:
#Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() ==1) {
finish();
}else{
super.onBackPressed()
}
}
And the white screen problem is gone!
From your question what I've understood is, you have a set of Fragment which is launched one after one and when you press the back button, they disappears one after one. When the first Fragment reaches and you click the back button again, it shows a white screen.
If I'm correct, you might have to track if the first Fragment is reached and then finish the Activity.
Implement the onBackPressed function in your MainActivity. You might consider doing something like this.
#Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() > 0)
getSupportFragmentManager().popBackStack();
else
finish(); // Finish the activity
}

Backing out of an full-screen dialog

if I launch a full-screen dialog like such
FragmentManager fragmentManager = getActivity().getFragmentManager();
DialogStyleCreator editor = new DialogStyleCreator();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
transaction.add(android.R.id.content, editor).commit();
How can I make it so that if I hit the android back arrow (in the top left of the menu) or the back button it closes the dialog instead of going back to the previous activity like in alert dialogs?
You may simply put your transaction in stack of fragment manager and override the function of back button
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (Integer.parseInt(android.os.Build.VERSION.SDK) > 5
&& keyCode == KeyEvent.KEYCODE_BACK
&& event.getRepeatCount() == 0) {
// Simply pop back your fragment stack here
return true;
}
return super.onKeyDown(keyCode, event);
}
#Override
public void onBackPressed() {
// Simply pop back your fragment stack here
}
Since you have added the DialogFragment as transaction.add(android.R.id.content, editor).commit(); you may not have option to listen the dismiss call back.
I suggest you to create the DialogFragment instance and start it like
fm.beginTransaction().add(sampleDialog, "Dialog").commit();
and set the call back interface for Activity Back Button Click and call dismiss();

Fragments, How to Navigate back to the previous Fragment, from the current Fragment?

I am using Fragment A,Fragment B .. and so on. i want to navigate back to the previous Fragment, from the current Fragment.
I want to use Back Button in Mobile to get back navigation.
How can i do this ? OR i have to make Back button in layout xml.
i tried below code,
fTransaction.add(R.id.container, nF).addToBackStack(null).commit();
when i pressed Back Button in Mobile , it restarts the App.
To go back to previous fragment using phone's back button you should override onKeyDown() mehtod.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if(keyCode == KeyEvent.KEYCODE_BACK)
{
getFragmentManager().popBackStack();
return true;
}
return false;
}
When replacing a fragment use replace instead of add and then addToBackStack:
fTransaction.replace(R.id.container, nF).addToBackStack(null).commit();
Try this:
fTransaction.addToBackStack(null).add(R.id.container, nF).commit();

how to go back to previous fragment on pressing manually back button of individual fragment?

I have only one activity and multiple fragments in my application.
Two main fragment A(left) and B(right).
Fragment A1 called from A
B1 called from B
B2 called from B1
All fragments have individual back buttons.
So when I press back button of fragment A1, it should go back to A, similarly when Back button from B2 is pressed, B1 appears and from B1 to B and so on.
How to implement this type of functionality?
public void onBackPressed()
{
FragmentManager fm = getActivity().getSupportFragmentManager();
fm.popBackStack();
}
I have implemented the similar Scenario just now.
Activity 'A' -> Calls a Fragment 'A1' and clicking on the menu item, it calls the Fragment 'A2' and if the user presses back button from 'A2', this goes back to 'A1' and if the user presses back from 'A1' after that, it finishes the Activity 'A' and goes back.
See the Following Code:
Activity 'A' - OnCreate() Method:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activityA);
if (savedInstanceState == null) {
Fragment fragInstance;
//Calling the Fragment newInstance Static method
fragInstance = FragmentA1.newInstance();
getFragmentManager().beginTransaction()
.add(R.id.container, fragInstance)
.commit();
}
}
Fragment : 'A1'
I am replacing the existing fragment with the new Fragment when the menu item click action happens:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_edit_columns) {
//Open the Fragment A2 and add this to backstack
Fragment fragment = FragmentA2.newInstance();
this.getFragmentManager().beginTransaction()
.replace(R.id.container, fragment)
.addToBackStack(null)
.commit();
return true;
}
return super.onOptionsItemSelected(item);
}
Activity 'A' - onBackPressed() Method:
Since all the fragments have one parent Activity (which is 'A'), the onBackPressed() method lets you to pop fragments if any are there or just return to previous Activity.
#Override
public void onBackPressed() {
if(getFragmentManager().getBackStackEntryCount() == 0) {
super.onBackPressed();
}
else {
getFragmentManager().popBackStack();
}
}
If you are looking for Embedding Fragments inside Fragments, please refer the link: http://developer.android.com/about/versions/android-4.2.html#NestedFragments
#trueblue's answer got me going with one minor but annoying issue. When there is only one fragment on the backstack and you press back button, that frame is removed and the app remains active with a blank screen. User needed to press back button one more time to exit the app. I modified the original code to the following in order to handle this situation
#Override
public void onBackPressed() {
if(getFragmentManager().getBackStackEntryCount() == 0) {
super.onBackPressed();
}
else if(getFragmentManager().getBackStackEntryCount() == 1) {
moveTaskToBack(false);
}
else {
getFragmentManager().popBackStack();
}
}
When there is only 1 fragment in the backstack, we are basically telling android to move the whole app to back.
Update (and probably a better answer)
So after doing some more reading around this, I found out that you can add fragment manager transactions to back stack and then android handles back presses automatically and in a desired way. The below code snippet shows how to do that
Fragment fragment; //Create and instance of your fragment class here
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment).addToBackStack(null);
fragmentTransaction.commit();
fragmentTransaction.addToBackStack(null);
The last line shows how you add a transaction to back stack. This solves back press issue for fragments in most situations except for one. If you go on pressing back button, then eventually you will reach a point when there is only one fragment in the back stack. At this point, you will want to do one of the two things
Remove the activity housing the fragment from the back stack of the task in which activity is running. This is because you do not want to end up with a blank activity
If the activity is the only activity in the back stack of the task, then push the task in background.
In my case, it was the later, so I modified the overridden onBackPressed method from my previous answer to look like below
#Override
public void onBackPressed() {
if(getFragmentManager().getBackStackEntryCount() == 1) {
moveTaskToBack(false);
}
else {
super.onBackPressed();
}
}
This code is simpler because it has less logic and it relies on framework than on our custom code. Unfortunately I did not manage to implement code for first situation as I did not need to.
You have to implement your own backstack implementation as explained here.
You can call the popFragments() whenever you click the back button in a fragment and call pushFragments() whenever you navigate from one Fragment to other.
Just Do
getActivity().getFragmentManager().popBackStack();
Try this, Its Work for me.
public void onBackPressed() {
if (mainLayout.isMenuShown()) {
mainLayout.toggleMenu();
} else {
FragmentManager fm = getSupportFragmentManager();
Log.print("back stack entry", fm.getBackStackEntryCount() + "");
if (fm.getBackStackEntryCount() > 1) {
fm.popBackStack();
// super.onBackPressed();
// return;
} else {
if (doubleBackToExitPressedOnce) {
fm.popBackStack();
super.onBackPressed();
return;
}
this.doubleBackToExitPressedOnce = true;
Toast.makeText(this, "Press one more time to exit",
Toast.LENGTH_SHORT).show();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
doubleBackToExitPressedOnce = false;
}
}, 3000);
}
}
}
Back button will traverse in the order, in which Fragments were added to backstack. This is provided as a navigation function by default. Now if you want to go to specific Fragment, you can show it from backstack.
You can handle it by adding tag in the backStack. Check my answer here :
https://stackoverflow.com/a/19477957/1572408
hope it helps
#Override
public void onResume() {
super.onResume();
getView().setFocusableInTouchMode(true);
getView().requestFocus();
getView().setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK){
// replace your fragment here
return true;
}
return false;
}
});
}
// Happy Coding
If you press back image you have to create method first like this
private void Backpresses() {
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.contant_main, new Home()).commit();
}
then you have to call like this when you press back image..
back.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Backpresses();
}
});
It work fine for me.

How to handle back button using view pager?

I am having two fragments Frag A and Frag B which are rendered using view pager .
If user has swiped from A to B then presses back button(when in B) then user should go to A instead of coming out of view pager . How can we achieve this ?
Adding transaction to backstack does not seem to help .
Thanks
You have to override the onKeyDown() method in the Activity.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
myViewPager.setCurrentItem(0, true);
return true;
} else {
return super.onKeyDown(keyCode, event);
}
}
This will capture the "back" button press event and send the user to the first item in the ViewPager.
There is also ViewPager#getCurrentItem() which can be used to go back only if the user swiped. An implementation like this:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && myViewPager.getCurrentItem() == 1) {
myViewPager.setCurrentItem(0, true);
return true;
} else {
return super.onKeyDown(keyCode, event);
}
}
would send the user back to the previous page only if the user was on the next page. Else, it will register the "back" normally and the user will exit as expected.
You may want the case in which the user goes back to the previous page (assuming you have more than two pages). In which case, you want to implement the ViewPager.OnPageChangeListener() and save the position every time onPageSelected(int position) is called. If you implement them in a stack, then you can pop them off every time the user presses "back". Once the stack is empty, exit the app.
EDIT
As correctly stated in the comments by Jade Byfield, a slightly easier way to do this would be to use onBackPressed() in the Activity. This will only work in API levels 5+.
#Override
public void onBackPressed() {
if(i_dont_want_to_leave) {
myViewPager.setCurrentItem(0, true);
} else {
super.onBackPressed(); // This will pop the Activity from the stack.
}
}
On the Android Docs page
https://developer.android.com/training/animation/screen-slide.html#viewpager
I found an example of handling ViewPager sliding and there's a method
#Override
public void onBackPressed() {
if (mPager.getCurrentItem() == 0) {
super.onBackPressed();
}
else {
mPager.setCurrentItem(mPager.getCurrentItem() - 1);
}
}
This selects a previous page or exits the current activity.
I think a better approach would be to delegate the back key handling to the respective fragments. I have used a CustomFragment which supports a method to handle the back key. All the Fragments will be extending from this CustomFragment.
public abstract class BackKeyHandlingFragment extends Fragment {
public abstract boolean handleBackKey();
}
Activity can delegate the backKey processing to current Fragment. Fragments can perform required actions in their respective implementation of handleBackKey method. The method can return true to tell activity not to process the back key. To go ahead with default back key action at Activity level, the method can return false.
public void onBackPressed() {
BackKeyHandlingFragment fragment = (BackKeyHandlingFragment) mSectionsPagerAdapter.getItem(mViewPager.getCurrentItem());
// Fragment should return boolean according to app requirements after processing back key
if (!fragment.handleBackKey()) {
super.onBackPressed();
}
}

Categories

Resources