I have a MainActivity in my application, from where all the fragments are called using Navigation Drawer. And default fragment of the activity is 'A'. So everytime i open the application, 'A' fragment is called. when I hit 'back' from another fragment B, I want to get to default fragment 'A', as what happens in gmail - from any fragment if we hit back, it returns to default fragment "Primary mails".
I tried calling the 'A' fragment by adding the following code to the onPause() of fragment 'B'.
#Override
public void onPause() {
super.onPause();
fragment = new A();
FragmentTransaction fragTransaction = getFragmentManager().beginTransaction();
fragTransaction.replace(R.id.a,fragment ).commit();
}
But when I hit back, fragment 'A' is called for a moment, but then the application closes unexpectedly.
Logcat :
01-14 12:44:42.264: E/WindowManager(4655): android.view.WindowLeaked: Activity com.litchi.iguardian.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{41da6348 V.E..... R.....ID 0,0-513,243} that was originally added here
Whats the correct way of doing this ?
to back to previous fragment see below code :
fragmentManager.popBackStack(...);
put this in onBack event
to call popBackStack method you first need to call addToBackStack method while calling fragment
Use this code
android.support.v4.app.Fragment detail = new CurrentClass();
detail.setArguments(bundle);
android.support.v4.app.FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.add(R.id.content_frame, detail).addToBackStack("back")
.commit();
You should customize the behavior when you press the back button, because by default it will destroy launched activity and you see your fragment while callbacks goes from onPause() until onStop() and activity is not visible for you anymore. Just override this method, it must solve the problem:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
// your code
return true;
}
return super.onKeyDown(keyCode, event);
}
But yeah, it is for global control, for switching fragments you may also call addToBackStack(); when you want return previous fragment by pressing back button.
instead of writing that code in onPause() you can write that code in onBackPressed() of your main activity .
Related
I have an activity where the user enters some data and submits it via a submit button, that same activity also has some more buttons which lead to fragments.
When I click on the fragments, the submit button of the activity overlaps the UI of the fragment, so in the calling code of fragments I set the visibility of that submit button as invisible but when back pressed from fragment then also that submit button is invisible.
I want the submit button to be visible when activity is being displayed and invisible when the fragments are being displayed.
Add your fragment on button click,
loginSubmit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
loginSubmit.setVisibility(View.GONE);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.addToBackStack("LayoutFragment");
ft.add(R.id.framelayoutfaqs, new LayoutFragment());
ft.commit();
}
});
#Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
getSupportFragmentManager().popBackStackImmediate();
loginSubmit.setVisibility(View.VISIBLE);
} else
super.onBackPressed();
}
NOTE : make sure you import same Fragment class which you used to create YourFragment. Also choose getSupportFragmentManager() or getFragmentManager() accordingly.
You can handle it in 0nBackPressed() method of Activity class .
Make the button invisible in either of onCreate, onActivityCreated or onAttach methods of your fragment and make it visible in onDetach method of your fragment.
How to check fragment is visible in Activity OnBackpressed
I want to check when user click back button in Searchfragment I want to set OnBackpressed is running ,but if user click back button in OtherFragment I want to set OnBackpressed is not running.
and I try this in Activity is not work
btn_back.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SearchFragment searchFragment = new SearchFragment();
if (searchFragment.isVisible()){
onBackPressed();
}
}
});
thanks for your help!
First of all, when you declare something like this:
SearchFragment searchFragment = new SearchFragment();
And then call
searchFragment.isVisible()
This will obviously return false since you didnt even add it to the container. What you need to do is to retrieve the fragment instance that you already added and check it's state.
I have once tried to use the method isVisible() but it is not entirely accurate, at least not for my case. What I came up with is to check the top fragment in the container as follow:
Fragment fragment = getActivity().getSupportFragmentManager().findFragmentById(R.id.fragment_container);
if(fragment instance of SearchFragment) //means your visible fragment is the SearchFragment
onBackPressed();
I have an activity (MainActivity) which has a navigation drawer and can show 2 fragments (Fragments A and B), one at a time. (This activity is the default activity with navigation drawer created by android studio)
When I choose fragment B on the drawer the action bar menu is updated to show a button specific for fragment B (Button P).
Button P open an independent activity (IndependentActivity) with an explicit intent, on this activity I perform a database operation and after it I finish this activity to go back to MainActivity.
The problem is: When IndependentActivity is finished, MainActivity is shown but it shows fragment A instead of fragment B which was the one that called the intent to go to IndependentActivity.
How do I fix this by showing the fragment that initiated the action to go to another activity? Is there any way to save the fragment that was appearing?
Basically what you have to do is:
Save the state of the MainActivity when you enter IndependentActivity
Reload the state of MainActivity when you exit IndependentActivity
A simple implementation of this could be:
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save which fragment that is in the view when entering another activity
savedInstanceState.putString("fragment", "fragmentB");
super.onSaveInstanceState(savedInstanceState);
}
Fragment B can be replaced with a string that tells the application which is the current fragment.
Once you come back to the activity you want to:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if( savedInstanceState != null ) {
// Get which fragment that was active when you left the activity
savedInstanceState.getString("fragment");
// Programatically select the fragment here
}
}
You can read more about saving instance state here:
http://developer.android.com/training/basics/activity-lifecycle/recreating.html
I will leave it to you to programmatically select the fragment. I hope it helps!
I found out that I was having the same problem as this: https://stackoverflow.com/a/29464116/2325672
The back arrow to return did not work and reset the activity's fragments and the emulator back triangle worked perfectly.
Adding this code to IndependentActivity worked for me:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId()== android.R.id.home) {
Intent intent = NavUtils.getParentActivityIntent(this);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
NavUtils.navigateUpTo(this, intent);
return true;
}
return super.onOptionsItemSelected(item);
}
I have a HomeFragment that has a button, which when clicked calls the following:
Fragment frag = new CustFragment();
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.home_container, frag).commit();
Then in my FragmentActivity which is the fragments mentioned above, I have:
#Override
public void onBackPressed() {
getFragmentManager().popBackStack();
super.onBackPressed();
}
That's what I've tried, but if I'm on the frag fragment and I press the back button, it doesn't go back to the last fragment (the HomeFragment). Instead, it attempts to go back to the last Activity, but since there is none (i.e. the previous activity had finish() invoked on it), it just goes to the Android Home Screen.
What am I doing wrong?
PS: If I'm being unclear, just comment below and i'll try to clarify.
Change
#Override
public void onBackPressed()
{
getFragmentManager().popBackStack();
super.onBackPressed();
}
to
#Override
public void onBackPressed()
{
if(getSupportFragmentManager().getBackStackEntryCount() > 0)
getSupportFragmentManager().popBackStack();
else
super.onBackPressed();
}
and
fragmentManager.beginTransaction().replace(R.id.home_container, frag).commit();
to
fragmentManager.beginTransaction().replace(R.id.home_container, frag).addToBackStack(null).commit();
Add your fragment to back stack using addToBackStack(null) like..
fragmentManager.beginTransaction().replace(R.id.home_container, frag).addToBackStack(null).commit();
beginTransaction creates a new FragmentTransaction. It has a method addToBackstack. If you call it before you commit your transaction you can remove your overridden onBackPressed completely. Reference
You can use:
fragmentTransaction.addToBackStack(null);
and no need to take care of onBackPressed().
BTW in your onBackPressed() super.onBackPressed() means you are actually changing nothing.
It should have been something like:
if(currentFragmentIsCustFragment){
getSupportFragmentManager().popBackStack();
}else{
super.onBackPressed();
}
When my MainActivity is launched my ActionBar shows the app title. Once you navigate to a fragment through the nav drawer, the title is changed to match the fragment... however, once you navigate back using the back button, the title is left untouched and still has the title of the fragment. I am looking to change it back to the application Title.
I have tried to use the onResume() method in the MainActivity.java but it appears that does not get called once you leave a fragment.
#Override
public void onResume() {
super.onResume();
// Set title
getActionBar().setTitle("FuelR");
invalidateOptionsMenu();
}
Does anyone know what the best way would be to change the title back to the app_name ?
Thanks
Indeed destroying a Fragment within an Activity doesn't mean the activity will call onResume, first you have to notice that the Fragment lives within the Activity life context, and the Fragment do not alter it's life cycle, is just part of it, what you could do is within the fragment get a reference to the activity and set the title back to previous state, as shown below:
//In Fragment
#Override
public void onDestroyView() {
super.onDestroyView();
((Cast If Necessary)getActivity()).getActionBar().setTitle("Previous Title");
}
Or a more OOP approach would be, creating an interface that declares a method setTitlePreviousText, you implement that interface in your Activity class and from the fragment you could do this:
//In Fragment
#Override
public void onDestroyView() {
super.onDestroyView();
Activity act = getActivity()
if(act instanceof SetPreviousTextInterface){
//setTitlePreviousText will be called giving you the chance to just change it back...
((SetPreviousTextInterface)act).setTitlePreviousText();
}
}
This would be the interface file:
public interface SetPreviousTextInterface{
public void setTitlePreviousText();
}
Regards!