I am trying to retain the state of Fragment. I have MotherActivity in which I have FragmentOne,FragmentTwo,FragmentThree and inside from FragmentTwo I am calling another activity ChildActivity. Problem is that When I am pressing back button in ChildActivity it is refreshing MotherActivity and not keeping the state of my FragmentTwo instead it is showing me FragmentOne which come first time.
I only want when I am pressing BackButton from ChildActivity, on container FragmentTwo should be there:
MainAcitivity:
public class MotherActivity extends FragmentActivity {
AHBottomNavigation bottomNavigation;
Fragment selectedFragment = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bottomNavigation = (AHBottomNavigation) findViewById(R.id.navigation);
bottomNavigation.addItem(item1);
bottomNavigation.addItem(item2);
bottomNavigation.addItem(item3);
bottomNavigation.setOnTabSelectedListener(new AHBottomNavigation.OnTabSelectedListener() {
#Override
public boolean onTabSelected(int position, boolean wasSelected) {
if (position == 0) {
selectedFragment = FragmentOne.newInstance(bottomNavigation);
} else if (position == 1) {
selectedFragment = FragmentTwo.newInstance(bottomNavigation);
} else if (position == 2) {
selectedFragment = FragmentThree.newInstance(bottomNavigation);
}
android.app.FragmentManager fragmentManager = getFragmentManager();
android.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame_layout,selectedFragment);
fragmentTransaction.commit();
return true;
}
});
}
#Override
protected void onStart() {
super.onStart();
android.app.FragmentManager fragmentManager = getFragmentManager();
android.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame_layout, FragmentOne.newInstance(bottomNavigation));
fragmentTransaction.commit();
}
public void setNotification(){
bottomNavigation.setNotification("1", 1);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
//No call for super().
}
#Override
public void onBackPressed() {
Intent intent = new Intent();
setResult(113, intent);
finish();
return;
}
}
FragmentTwo from where I am calling childActivity:
public class FragmentTwo extends Fragment {
public static AHBottomNavigation bottomNavigation1;
Card_detail_Adapter_Footer searchabledapter;
public static boolean showAddress = false;
Fragment selectedFragment;
public static FragmentTwo newInstance(AHBottomNavigation bottomNavigation) {
FragmentTwo fragment = new FragmentTwo();
bottomNavigation1 = bottomNavigation;
showNotificationCounter(3);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_cart, container, false);
if(showAddress == true){
showAddress = false;
// From here I am calling ChildActivity
Intent intent = new Intent(getActivity(), ChildActivity.class);
startActivity(intent);
}
return view;
}
}
In ChildActivity simply calling onBackPressed()
The problem is with the onStart() method of your MotherActivity.java because when you open another activity from FragmentTwo, your MotherActivity onStop() gets called. When you press back button from ChildActivity onStart() of MotherActivity called which is replacing FragmentTwo from FragmentOne by committing transaction.
Please have a look at https://developer.android.com/guide/components/activities/activity-lifecycle.html
Put code from onStart() method into onCreate() method and check if configuration been changed:
if (savedInstanceState == null) {
android.app.FragmentManager fragmentManager = getFragmentManager();
android.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.frame_layout, FragmentOne.newInstance(bottomNavigation));
fragmentTransaction.commit();
}
Related
I'm using HashMap of fragment's backstack. To save backstack and current fragment I use the code below:
public class MainActivity extends AppCompatActivity {
private HashMap<String, Stack<Fragment>> mStacks;
public static final String TAB_PROFILE = "tab_profile";
public static final String TAB_DASHBOARD = "tab_dashboard";
public static final String TAB_CHATS = "tab_chats";
public static final String TAB_SETTINGS = "tab_settings";
private String mCurrentTab;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupViews();
if (savedInstanceState != null) {
mCurrentTab = savedInstanceState.getString("currentTab");
mStacks = (HashMap<String, Stack<Fragment>>) savedInstanceState.getSerializable("stacks");
} else
selectedTab(TAB_DASHBOARD);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable("stacks", mStacks);
outState.putString("currentTab", mCurrentTab);
}
private void setupViews() {
mStacks = new HashMap<>();
mStacks.put(TAB_PROFILE, new Stack<>());
mStacks.put(TAB_DASHBOARD, new Stack<>());
mStacks.put(TAB_CHATS, new Stack<>());
mStacks.put(TAB_SETTINGS, new Stack<>());
BottomNavigationView bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottom_navigation);
bottomNavigationView.setSelectedItemId(R.id.action_dashboard);
BottomNavigationViewHelper.removeShiftMode(bottomNavigationView);
bottomNavigationView.setOnNavigationItemSelectedListener(item -> {
switch (item.getItemId()) {
case R.id.action_profile:
selectedTab(TAB_PROFILE);
return true;
case R.id.action_dashboard:
selectedTab(TAB_DASHBOARD);
return true;
case R.id.action_chats:
selectedTab(TAB_CHATS);
return true;
case R.id.action_settings:
selectedTab(TAB_SETTINGS);
return true;
}
return true;
});
bottomNavigationView.setOnNavigationItemReselectedListener(item -> {
if (mStacks.get(mCurrentTab).size() != 1) {
mStacks.get(mCurrentTab).clear();
switch (item.getItemId()) {
case R.id.action_profile:
selectedTab(TAB_PROFILE);
break;
case R.id.action_dashboard:
selectedTab(TAB_DASHBOARD);
break;
case R.id.action_chats:
selectedTab(TAB_CHATS);
break;
case R.id.action_settings:
selectedTab(TAB_SETTINGS);
break;
}
}
});
}
private void selectedTab(String tabId) {
mCurrentTab = tabId;
if(mStacks.get(tabId).size() == 0){
if(tabId.equals(TAB_PROFILE)){
Fragment fragment = new ProfileFragment();
Bundle args = new Bundle();
args.putSerializable("user", Globals.getCurrentUser());
fragment.setArguments(args);
pushFragments(tabId, fragment,true);
} else if(tabId.equals(TAB_DASHBOARD)){
pushFragments(tabId, new DashboardFragment(),true);
}else if(tabId.equals(TAB_CHATS)){
pushFragments(tabId, new GroupsFragment(),true);
}else if(tabId.equals(TAB_SETTINGS)){
pushFragments(tabId, new SettingsFragment(),true);
}
}else {
pushFragments(tabId, mStacks.get(tabId).lastElement(),false);
}
}
public void pushFragments(String tag, Fragment fragment, boolean shouldAdd){
if(shouldAdd)
mStacks.get(tag).push(fragment);
FragmentManager manager = getFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.content, fragment);
ft.commit();
}
public void popFragments(){
Fragment fragment = mStacks.get(mCurrentTab).elementAt(mStacks.get(mCurrentTab).size() - 2);
mStacks.get(mCurrentTab).pop();
FragmentManager manager = getFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.content, fragment);
ft.commit();
}
#Override
public void onBackPressed() {
if(mStacks.get(mCurrentTab).size() == 1){
finish();
return;
}
popFragments();
}
}
Set new fragments using
((MainActivity)context).pushFragments(MainActivity.TAB_CHATS, fragment,true);
Layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:background="#color/background_material_light"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#id/bottom_navigation"/>
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:itemBackground="#color/waPrimary"
app:itemIconTint="#color/white"
app:itemTextColor="#color/white"
app:menu="#menu/menu_bottom_navigation" />
Everything works fine on screen rotation, but application crashes with exception on application hide.
java.lang.RuntimeException: Parcel: unable to marshal value %FragmentName%{c985244 #2 id=0x7f090051}
As I read, it happens when one of the objects I'm trying to pass is not Parceable, but have no idea how to fix this. Any thoughts?
UPD
After I made all of my fragments Serializable, new exception throws
java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = %FragmentName%)
...
Caused by: java.io.NotSerializableException: android.support.v7.widget.RecyclerView
UPD2
Seems like a found a solution - transient property. Now I'm trying to make all non-serializeable objects transient.
UPD3
It helped, but I don't know is it efficient enough.
Here's my suggestion:
Your activity maintains a reference to the four fragments it wants for the bottom navigation toggling.
On toggling bottom navigation, you replace the current fragment in the activity fragment manager.
While on a given fragment, as you interact with the UI, you push things on to the fragment child fragment manager.
This way, each fragment maintains its own backstack automatically, you don't have to save any state, and it all Just Works™.
Some sample code that might help.
public class MainActivity extends AppCompatActivity {
private Fragment mProfileFragment;
private Fragment mDashboardFragment;
private Fragment mChatsFragment;
private Fragment mSettingsFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
// Init fragments
}
else {
// Find last active fragments in fragment manager
}
setupViews();
}
private void setupViews() {
BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_navigation);
bottomNavigationView.setSelectedItemId(R.id.action_dashboard);
BottomNavigationViewHelper.removeShiftMode(bottomNavigationView);
bottomNavigationView.setOnNavigationItemSelectedListener(item -> {
Fragment fragment;
switch (item.getItemId()) {
case R.id.action_profile:
fragment = mProfileFragment;
break;
case R.id.action_dashboard:
fragment = mDashboardFragment;
break;
case R.id.action_chats:
fragment = mChatsFragment;
break;
case R.id.action_settings:
fragment = mSettingsFragment;
break;
}
// Replace the currently active fragment which will be
// managing its own backstack
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.frament_container, fragment)
.commit();
});
}
}
And one of your fragments would push stuff on its own stack like this:
public class ProfileFragment extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.id.fragment_layout, container, false);
Button button = view.findViewById(R.id.some_button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Fragment someFragmentToPush = new SomeFragmentToPush();
// Use the child fragment manager to keep UI
// local to this fragment instance, adding to backstack
// for automatic popping on pressing back
getChildFragmentManager().beginTransaction()
.add(R.id.fragment_layout, someFragmentToPush)
.addToBackStack(null)
.commit();
}
});
return view;
}
}
Hope that helps!
I am using tabs to switch between different lists in my app. When a user touches an item in a list, the following is the code to show and hide the detail. I am wondering how to add a back-button that goes back to the correct list it came from. I am replacing fragments so I don't know if the standard back button works in my case?
public class MainActivity extends AppCompatActivity implements
NavigationView.OnNavigationItemSelectedListener,
TabLayout.OnTabSelectedListener,
CustomerFragment.CustomerListListener,
CustomerDetailListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
actionBar.setHomeButtonEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowHomeEnabled(true);
}
public void onShowCustomerDetail(Customer customer){
HostFragment hostFragment = (HostFragment) customPagerAdapter.getItem(viewPager.getCurrentItem());
CustomerDetailFragment fragment = CustomerDetailFragment.newInstance(customer);
hostFragment.replaceFragment(fragment, true);
}
public void onCloseCustomerDetail() {
HostFragment hostFragment = (HostFragment) customPagerAdapter.getItem(viewPager.getCurrentItem());
CustomerFragment fragment = new CustomerFragment();
hostFragment.replaceFragment(fragment, true);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// just for testing. will do switch case here
onBackPressed();
}
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 0) {
getFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
}
CustomPagerAdapter:
public class CustomPagerAdapter extends FragmentStatePagerAdapter {
private final List<String> tabTitles = new ArrayList<String>() {{
add("Messages");
add("Customers");
add("Jobs");
add("Maps");
}};
private List<Fragment> tabs = new ArrayList<>();
public CustomPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
initializeTabs();
}
private void initializeTabs() {
tabs.add(HostFragment.newInstance(new MessageFragment()));
tabs.add(HostFragment.newInstance(new CustomerFragment()));
tabs.add(HostFragment.newInstance(new JobFragment()));
tabs.add(HostFragment.newInstance(new MapFragment()));
}
#Override
public Fragment getItem(int position) {
return tabs.get(position);
}
#Override
public int getCount() {
return tabs.size();
}
#Override
public CharSequence getPageTitle(int position) {
return tabTitles.get(position);
}
}
HostFragment:
public class HostFragment extends BackStackFragment {
private Fragment fragment;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.fragment_host, container, false);
if (fragment != null) {
replaceFragment(fragment, false);
}
return view;
}
public void replaceFragment(Fragment fragment, boolean addToBackstack) {
if (addToBackstack) {
getChildFragmentManager().beginTransaction().replace(R.id.hosted_fragment, fragment).addToBackStack(null).commit();
} else {
getChildFragmentManager().beginTransaction().replace(R.id.hosted_fragment, fragment).commit();
}
}
public static HostFragment newInstance(Fragment fragment) {
HostFragment hostFragment = new HostFragment();
hostFragment.fragment = fragment;
return hostFragment;
}
}
Because of the way I set up my fragments inside tabs using Child Fragment Manager, I had to do this in my onBackPressed to make it work:
#Override
public void onBackPressed() {
HostFragment hostFragment = (HostFragment) customPagerAdapter.getItem(viewPager.getCurrentItem());
FragmentManager fm = hostFragment.getChildFragmentManager();
if (fm.getBackStackEntryCount() > 0) {
fm.popBackStack();
} else {
super.onBackPressed();
}
}
First of all you need to add fragments in backstack while using it
see below code for creating a fragment and adding inside it to backstack
public final static String TAG_FRAGMENT = "HostFragment"; // used inside every fragment
final HostFragment fragment = new HostFragment();
final FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment, fragment, TAG_FRAGMENT);
transaction.addToBackStack(TAG_FRAGMENT);
transaction.commit();
After that inside activity onBackPressed() you need to pop fragment every backpressed that you want.
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 0) {
getFragmentManager().popBackStack(); // pop fragment here
} else {
super.onBackPressed(); // after nothing is there default behavior of android works.
}
}
All you need to do is add the fragment to the back stack when you create your fragment. It would look something like this:
CustomerDetailFragment fragment=CustomerDetailFragment.newInstance(customer);
getFragmentManager().beginTransaction()
.addToBackStack("Fragment Tag")
.replace(R.id.yourContainer, fragment, "Fragment Tag")
.commit();
Once you have this, you can just use the home back button to pop the fragments off the stack. If you want to use a custom button to go back, you would have to implement your own popping of the stack, which would call getFragmentManager().popBackStack();
Write a fuction onBackpress()
#Override
public void onBackPressed() {
new AlertDialog.Builder(this)
.setTitle("Exit?")
.setMessage("Do you really want to exit?")
.setNegativeButton("No")
.setPositiveButton("Yes", new OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
YourActivityname.super.onBackPressed();
}
}).create().show();
}
i have an activity like WelcomeActivity and a fragment like GuideFragment.
i have a button in WelcomeActivity which cause a navigation to GuideFragment. Also i have a button in GuideFragment which navigates back to the WelcomeActivity.
For first time it goes to GuideFragment by clicking on the button and cames back to WelcomeActivity by pressing btn_back. Hwever after coming back to activity, the button does not work any more.
whats wrong with my code?
activity clas:
public class WelcomeActivity extends FragmentActivity
{
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
GuideFragment guideFragment = new GuideFragment();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
guideFragment = new GuideFragment();
}
public void onGuideClick(View view)
{
fragmentTransaction.replace(android.R.id.content, guideFragment);
fragmentTransaction.addToBackStack(null);
fragmentManager.popBackStack();
fragmentTransaction.commit();
}
}
and fragment class:
public class GuideFragment extends Fragment
{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// create ContextThemeWrapper from the original Activity Context with the custom theme
Context contextThemeWrapper = new ContextThemeWrapper(getActivity(), R.style.guideFrag);
// clone the inflater using the ContextThemeWrapper
LayoutInflater localInflater = inflater.cloneInContext(contextThemeWrapper);
// inflate the layout using the cloned inflater, not default inflater
View view = inflater.inflate(R.layout.fragment_guide, container, false);
Button button = (Button) view.findViewById(R.id.btn_back);
button.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
getActivity().getFragmentManager ().popBackStack();
}
});
return view;
}
}
Thanks
Remove fragmentManager.popBackStack(); from onGuideClick(View view). Also the transaction should not be a member field.
public void onGuideClick(View view) {
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(android.R.id.content, guideFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
You also initiate the GuideFragment twice, once is enough.
I changed WelcomeActivity like this:
public class WelcomeActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
}
public void onGuideClick(View view)
{
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
GuideFragment guideFragment = new GuideFragment();
fragmentTransaction.replace(android.R.id.content, guideFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
}
I have a problem related to fragment life cycle.
Before doing this, I will set DONT KEEP ACTIVITY mode(Setting -> Developer options).
In my project have 2 activity:
Activity 1: keep and control Fragment A and Fragment B
Activity 2: do not have fragment.
Activity 1 will be called first, then Fragment A and Fragment B will be called to visible.
Start Activity 2 from Activity 1, this cause Activity 1 will be destroyed and Fragment A & Fragment B will be destroyed too (Because of dont keep activity mode).
Press back key from Activity 2 to back Activity 1
Problem occurs here: Fragment A and Fragment B will be automatically called onCreateView() after back from activity 2 -> I want to avoid this. Can you give me some tips to resolve it?
Update Code
Activity 1
public class MainActivity extends Activity implements OnClickListener {
private Button mBtnShowFragmentA;
private Button mBtnShowFragmentB;
private Button mBtnGoAcitivity2;
protected String mCurrentFragmentTag;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_activity_1);
mBtnShowFragmentA = (Button) findViewById(R.id.btn_show_fragmentA);
mBtnShowFragmentB = (Button) findViewById(R.id.btn_show_fragmentB);
mBtnGoAcitivity2 = (Button) findViewById(R.id.btn_go_activity2);
mBtnShowFragmentA.setOnClickListener(this);
mBtnShowFragmentB.setOnClickListener(this);
mBtnGoAcitivity2.setOnClickListener(this);
}
#Override
protected void onDestroy() {
super.onDestroy();
}
protected void addFragment(int contentId, Fragment fragment, boolean isAddStack,
String stackName) {
FragmentManager fm = getFragmentManager();
String newFragment = fragment.getClass().getName();
FragmentTransaction ft = fm.beginTransaction();
Fragment currentFragment = fm.findFragmentByTag(mCurrentFragmentTag);
if (currentFragment != null && !TextUtils.equals(currentFragment.getTag(), newFragment)) {
ft.hide(currentFragment);
}
if (fm.findFragmentByTag(newFragment) != null) {
fragment = (Fragment) fm.findFragmentByTag(newFragment);
}
if (!fragment.isAdded()) {
ft.add(contentId, fragment, newFragment);
} else {
ft.show(fragment);
}
if (isAddStack) {
ft.addToBackStack(stackName);
}
try {
ft.commitAllowingStateLoss();
} catch (Exception e) {
}
mCurrentFragmentTag = newFragment;
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_show_fragmentA:
FragmentA fragmentA = new FragmentA();
addFragment(R.id.activity_main_content, fragmentA, false, null);
break;
case R.id.btn_show_fragmentB:
FragmentB fragmentB = new FragmentB();
addFragment(R.id.activity_main_content, fragmentB, false, null);
break;
case R.id.btn_go_activity2:
Intent intent = new Intent(getApplicationContext(), SettingActivity.class);
startActivity(intent);
break;
default:
break;
}
}
}
Fragment A
public class FragmentA extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.layout_fragment_a, container, false);
return view;
}
}
Fragment B
public class FragmentB extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.layout_fragment_b, container, false);
return view;
}
}
Activity 2
public class SettingActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_activity_2);
}
#Override
protected void onDestroy() {
super.onDestroy();
}
#Override
public void onBackPressed() {
super.onBackPressed();
}
}
...................
Use below code to remove activity from stack.
FragmentManager fragmentManager = getSupportFragmentManager();
if (fragmentManager .getBackStackEntryCount() > 0) {
fragmentManager .popBackStack();
}
I'm building a simple app and I want to go back from fragment to activity with physical button. How do I do that? I have tried to kill the fragment but it isn't working.
You can get a reference to the FragmentActivity by calling getActivity() on your current Fragment and then call from the Activity retrieved onBackPressed() method.
getActivity().onBackPressed();
I do it like this and it's working very fine.
Start fragment:
public void showMyFragment(View V){
Fragment fragment = null;
fragment = new MyFragment();
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.frame_container, fragment).addToBackStack(null).commit();
}
}
This is how to end fragment with back button:
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() == 0) {
this.finish();
} else {
getFragmentManager().popBackStack();
}
}
Your Fragment:
public class MyFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v=inflater.inflate(R.layout.activity_info, null);
return v;
}
}
Show fragment with this:
getSupportFragmentManager().beginTransaction()
.setReorderingAllowed(true)
.replace(R.id.frame_container,fragment.class,null).addToBackStack("desc_fragment")
.commit();
and then override onBackPressed in your activity:
#Override
public void onBackPressed() {
if(getSupportFragmentManager().getBackStackEntryCount() > 0)
getSupportFragmentManager().popBackStack();
else
super.onBackPressed();
}