I am working with fragments in navigation drawer layout. I want to return to HomeFragment on pressing back button each time when any other fragment is visible in frame_container. and if home fragment is already visible i want to finish MainActivity (navigation_drawer_activity). Help me correct this code of OnBackPressed in main activity.
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
}
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_home);
if(fragment!=null && fragment.isVisible()){
clearBackStack();
finish();
}else {
clearBackStack();
getSupportFragmentManager().beginTransaction().replace(R.id.frame_container,new HomeFragment()).commit();
}
}
Here is the solution. I found the fragment from frame_container.
and then checked in if statement. if(fragment!=null && fragment instanceof HomeFragment && fragment.isVisible()). this returned home_fragment.
Thanks for your answers.
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
}
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.frame_container);
if(fragment!=null && fragment instanceof HomeFragment && fragment.isVisible()){
clearBackStack();
finish();
}else {
clearBackStack();
getSupportFragmentManager().beginTransaction().replace(R.id.frame_container,new HomeFragment()).commit();
}
}
try this
#Override
public void onBackPressed() {
FragmentManager fm = getSupportFragmentManager();
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
drawerLayout.closeDrawer(GravityCompat.START);
} else if (fm.getBackStackEntryCount() > 0) {
Log.i("MainActivity", "popping backstack");
getSupportFragmentManager().popBackStackImmediate();
} else {
Log.i("MainActivity", "nothing on backstack, calling super");
super.onBackPressed();
}
}
Related
I am developing an android app using fragments. I have five fragments. Those are A,B,C,D,E . My first fragment A is the main fragment. First I traverse from A to B then from B to C. In C when I press back button I want it to go back to A. I have used the below code for calling B fragment from A. This same method is used for calling another fragments.
FragmentB fragment = new FragmentB();
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction().addToBackStack("tag");
transaction.replace(R.id.content_frame, fragment);
transaction.commit();
The back button code in the activity is as following
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
How to solve this issue please help me.
You can try this:
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} FragmentManager fragmentManager = getSupportFragmentManager();
int backCount = fragmentManager.getBackStackEntryCount();
System.out.println("back count " + backCount);
if(backCount==0)
{
actionBar.setTitle("Home");
//Here you can show alert dialog for exit the app?
}
/* else if(backCount==1)
{
}*/
else if(backCount==1)
{
fragmentManager.popBackStack();
// setTitle("Home");
navigationView.getMenu().getItem(0).setChecked(true);
actionBar.setTitle("Home");
}
else if(backCount>1)
{
for(int i=fragmentManager.getBackStackEntryCount();i>=1;i--)
{
fragmentManager.popBackStack();
System.out.println("back count loop" + fragmentManager.getBackStackEntryCount());
}
actionBar.setTitle("Home");
}
}
Try this:
#Override
public void onBackPressed() {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawers();
return;
}
// This code loads home fragment when back key is pressed
// when user is in other fragment than home
if (shouldLoadHomeFragOnBackPress) {
// checking if user is on other navigation menu
// rather than home
if (navItemIndex != 0) {
navItemIndex = 0;
CURRENT_TAG = TAG_HOME;
loadHomeFragment();
return;
}
}
super.onBackPressed();
}
Refer this reference : https://www.androidhive.info/2013/11/android-sliding-menu-using-navigation-drawer/
I am trying to close the fragment and wants to resume the main activity by using the addToBackStack in my fragment implimentation but it is not working. Back button is closing the application.
The fragment implimentation method that I am using is,
private void dispaySelectedScreen(int id) {
Fragment fragment = null;
switch (id) {
case R.id.facebook_login:
fragment = new FacebookLogin();
break;
case R.id.memes:
fragment = new Memes();
break;
case R.id.submit_image:
fragment = new SubmitImage();
break;
case R.id.discussion:
fragment = new Discussions();
break;
case R.id.invite:
fragment = new Invite();
break;
case R.id.connect_fb:
fragment = new FacebookConnect();
break;
case R.id.connect_twitter:
fragment = new TwitterConnect();
break;
case R.id.connect_instagram:
fragment = new InstaConnect();
break;
}
if (fragment != null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_main, fragment);
ft.addToBackStack(null);
ft.commit();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
I have also declared one onBackPressed method for the drawer,
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
Please suggest..
fragment.addToBackStack(null) is enough to open the previous activity but if you want to handle some action on back pressed apart from removing the fragment then we override onBackPressed(), so this is my tested approach, kindly have a look:-
Below is my implementation:-
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_holder, new MyFragment(), "MY_FRAG")
.addToBackStack(null).commit();
}
#Override
public void onBackPressed() {
MyFragment fragment = (MyFragment) getSupportFragmentManager().findFragmentByTag("MY_FRAG");
if (fragment != null) {
if (fragment.isVisible()) {
//todo perform any action if you want when fragment is removed
}
} else {
super.onBackPressed();
}
}
I see you are using replace on transaction in that way your fragment will pop up from stack but it will reload i.e onCreateView() of that fragment will be called . Just replace
ft.replace(R.id.content_main, fragment);
to
ft.add(R.id.content_main, fragment);
For handling back button use following code .
public void onBackPressed() {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
//that means your stack is empty and you want to close activity
finish();
} else {
// pop the backstack here
getSupportFragmentManager().popBackStackImmediate();
}
}
}
Hi I have created fragments in app drawer and now when I am pressing the back button on a fragment, it is closing the application.
There is already one existing onKeyDown in the webView of Main activity.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
if (myWebView.canGoBack()) {
myWebView.goBack();
} else {
finish();
}
return true;
}
}
return super.onKeyDown(keyCode, event);
For the onBackPressed method
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
Fragment Impementation method,
if (fragment != null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_main, fragment);
ft.addToBackStack("close");
ft.commit();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
When you add a fragment to some container or inflate it using xml, it is not added to the backstack and so, when 'onBackPressed' occurs it throws the last activity from the backstack- which is the activity hosting the fragment and thus exiting the application.
I think this post:
Android: Fragments backStack
can help you, it explains how to add the fragment transaction to the backstack:
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(..............);
fragmentTransaction.addToBackStack("fragment transaction name, not required");
fragmentTransaction.commit();
You need to do this in following way
#Override
public void onBackPressed() {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
//that means your stack is empty and you want to close activity
finish();
} else {
// pop the backstack here
getSupportFragmentManager().popBackStackImmediate();
}
}
}
I think you dont add the fragments to the backstack.
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
//your code
fragmentTransaction.addToBackStack("your_tag");
When you evoke a fragment add it to stack like this
fragmentTransaction.addToBackStack("fragment");
and then in onBackPress pop it from stack like this
FragmentManager fm = getActivity()
.getSupportFragmentManager();
fm.popBackStack ("fragment", FragmentManager.POP_BACK_STACK_INCLUSIVE);
My onBackPressed() sends me out of my app. How can I avoid this? Either it should send me back to last shown fragment or just send me to a specific fragment.
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
}
else{
super.onBackPressed();
}
}
Try this,If you are using Fragment android.support.v4.app.Fragment.
private boolean allowExit = false;
Then
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
}
else if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
// handling fragment backbutton navigation
getSupportFragmentManager().popBackStack();
} else {
if (allowExit) {
super.onBackPressed();
} else {
Toast.makeText(this, getString(R.string.app_exit_message), Toast.LENGTH_SHORT).show();
allowExit = true;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
allowExit = false;
}
}, 3000);
}
}
}
If you are using not support fragment you have to replace
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
}
else if (getFragmentManager().getBackStackEntryCount() > 0) {
// handling fragment backbutton navigation
getFragmentManager().popBackStack();
} else {
if (allowExit) {
super.onBackPressed();
} else {
Toast.makeText(this, getString(R.string.app_exit_message), Toast.LENGTH_SHORT).show();
allowExit = true;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
allowExit = false;
}
}, 3000);
}
}
}
And add message to the string.xml
<string name="app_exit_message">Press again to exit</string>
Try the below code.
1. If your drawer is opened it will close the drawer.
2. If Any fragment is in backstack, it will navigate you to the previous fragment.
3. If No Fragment is in backstack, it will close the application.
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
oneStepBack();
}
}
/**
* function to go back to previous fragment
*/
private void oneStepBack() {
FragmentTransaction fts = getSupportFragmentManager().beginTransaction();
FragmentManager fragmentManager = getSupportFragmentManager();
showOutput("Back Stack Count>>>>>>>>>>" + fragmentManager.getBackStackEntryCount());
if (fragmentManager.getBackStackEntryCount() >= 2) {
fragmentManager.popBackStackImmediate();
fts.commit();
} else {
finish();
}
}
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
}
else{
write your code here what activity you want to open on back press and remove below line
//super.onBackPressed();
}
}
DrawerLayout should be initialised in onCreate() method ,so you are facing the problem.
For your reference check this , it may help you.
http://www.androidhive.info/2013/11/android-sliding-menu-using-navigation-drawer/
Navigation drawer with fragments. I have placed one fragment on main activity. But if i back press the same fragment comes again. How can I handle this??
and secondly how to implement onBackpressed in fragments??
Can anybody help me out?
in onCreate of main activity I have
FragmentTransaction tx = getFragmentManager().beginTransaction();
tx.replace(R.id.mainFrame, new PlaceOrderFragment());
tx.commit();
and in back press of it I have
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
First you need to add the fragmnet to back stack so we could retrieve it later in onBackPressed()
Replace your fragmnet transaction with this
FragmentTransaction tx = getFragmentManager().beginTransaction();
tx.replace(R.id.mainFrame, new PlaceOrderFragment());
// HERE WE WILL ADD FRAGMENT TO BACKSTACK SO WE COULD GET BACK TO IT
tx.addToBackStack(null);
tx.commit();
Replace your onBackPressed with this
#Override
public void onBackPressed() {
// CHECKS HOW MANY FRAGMENTS ARE IN THE BACKSTACK
int count = getFragmentManager().getBackStackEntryCount();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
if (count == 0) {
// IF NO FRAGMENT IN THE BACKSTACK CALL
super.onBackPressed();
} else {
// GET THE LAST OPENED FRAGMENT
getFragmentManager().popBackStack();
}
}
}
You can do this using Interface. That interface will implemented in each fragment. Here is a simple example:
public interface OnBackPressedListener {
void onBackPressed();
}
Here, if you implement this interface in your fragment then you will found this method:
#Override
public void onBackPressed() {
getActivity().finish(); // Or Do your specific task
}
Now your Activity that holds that fragment , that should use onBackPressed() callback. Write bellow code in that method
#Override
public void onBackPressed() {
if (YOUR_DRAWER.isDrawerOpen(GravityCompat.START)) {
YOUR_DRAWER.closeDrawer(Gravity.LEFT); //CLOSE Nav Drawer!
return;
}
Fragment fragment=getYourVisibleFragment();
if(fragment!=null){
((OnBackPressedListener)fragment).onBackPressed();
}else{
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
If you want to get Visible fragment then just use this method
public <F extends Fragment> F getVisibleFragment() {
List<Fragment> fragments = getSupportFragmentManager().getFragments();
if (fragments != null) {
for (Fragment fragment : fragments) {
if (fragment != null && fragment.isVisible()) {
return (F) fragment;
}
}
}
return null;
}
That's it :)
FragmentTransaction tx = getFragmentManager().beginTransaction();
tx.replace(R.id.mainFrame, new PlaceOrderFragment()).addToBackStack("your tag");
tx.commit();
Override onBackPress() and try following code.
#Override
public void onBackPressed() {
int count = getFragmentManager().getBackStackEntryCount();
if (count == 0) {
super.onBackPressed();
//your other utility code if needed
} else {
getFragmentManager().popBackStack();
}
}
Hope this will work for you.
Replace ypu fragment in onCreate with fragment id , and then implement onBackpressed on the same activity and find that fragment with id and check is it visible or null and then perform operations based on it.
hope you got this.