Trying to remove a fragment from the screen Android - android

I'm within an activity and I launch a fragment from there, and it appears on the screen fine, but I want to use the button to then remove the same fragment. I can't see what's wrong with the code, I know it's going in to the code that should remove it because the toast says "remove fragment". Any ideas? Thanks
public class ButtonClickHandler implements View.OnClickListener {
public void onClick(View view) {
if (showFrag == true){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
MyFragment myFragment = new MyFragment();
fragmentTransaction.add(R.id.myfragment, myFragment);
fragmentTransaction.commit();
showFrag = false;
Toast.makeText(getBaseContext(), "Show Fragment", Toast.LENGTH_SHORT).show();
}
else if (showFrag == false){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
getSupportFragmentManager().popBackStack();
fragmentTransaction.commit();
Toast.makeText(getBaseContext(), "Remove Fragment", Toast.LENGTH_SHORT).show();
showFrag = true;
}
}
}

To pop a fragment of backstack you need to add it to backstack first.
You can do that by calling fragmentTransaction.addToBackStack(null) after you call fragmentTransaction.add(R.id.myfragment, myFragment);
Also including #coelho 's comment - You dont have to start a FragmentTransaction to call popBackStack().

You're not calling addToBackStack before :)
fragmentTransaction.add(R.id.myfragment, myFragment);
fragmentTransaction.addToBackStack(null);
The the remove should simply be:
getSupportFragmentManager().popBackStack();
No need to create a local variable and no need to create a transaction.

Related

Refresh a fragment android

Earlier this code was working but it now it suddenly stopped working. Fragment is not detaching from parent activity.
public void reLoadFragment(Fragment fragment)
{
Log.i(LogGeneratorHelper.INFO_TAG, "reloading fragment");
// Reload current fragment
Fragment frg = null;
frg = getSupportFragmentManager().findFragmentByTag(fragment.getClass().getName());
frg.onDetach();
final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.detach(frg);
ft.attach(frg);
ft.commit();
Log.i(LogGeneratorHelper.INFO_TAG, "reloading fragment finish");
}
ft.detach() not working after support library update 25.1.0. This solution works fine after update:
getSupportFragmentManager().beginTransaction().detach(oldFragment).commitNowAllowingStateLoss();
getSupportFragmentManager().beginTransaction().attach(oldFragment).commitAllowingStateLoss();
Credit:
Refresh or force redraw the fragment
You can simply refresh the current fragment using
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.detach(this).attach(this).commit();
Also, in your case you can do something like this,
public void reLoadFragment(Fragment fragment)
{
Log.i(LogGeneratorHelper.INFO_TAG, "reloading fragment");
Fragment currentFragment = fragment;
if (currentFragment instanceof "FRAGMENT CLASS NAME") {
FragmentTransaction fragTransaction = (getActivity()).getFragmentManager().beginTransaction();
fragTransaction.detach(currentFragment);
fragTransaction.attach(currentFragment);
fragTransaction.commit();
Log.i(LogGeneratorHelper.INFO_TAG, "reloading fragment finish");
}
else Log.i(LogGeneratorHelper.INFO_TAG, "fragment reloading failed");
}
Use this in yout Main Activity:
frag_name frag_name = new frag_name();
FragmentManager manager = this.getSupportFragmentManager();
manager.beginTransaction().replace(R.id.youtframelayout, frag_name, frag_name.getTag()).commit();
It inicializes the fragment and replaces it in your FrameLayout
Like this your replacing again the fragment :)
Hope it works! :)
This will refresh current fragment :
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.detach(this).attach(this).commit();
For kotlin use below code.
fragmentManager!!.beginTransaction().detach(this).attach(this).commit()
For kotlin:
supportFragmentManager.beginTransaction().detach(fragment).attach(fragment).commit()

Android Fragment Back Stack

I have used multiple Fragments in my Project. I want to save a Fragment's state and restore this state when I come back to this. In this Fragment I show multiple images which change on button click. I use the following code for this:
String backStateName = fragment.getClass().getName();
FragmentManager fragmentManager = getSupportFragmentManager();
boolean fragmentPopped = fragmentManager.popBackStackImmediate(backStateName, 0);
if (!fragmentPopped) {
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container_body, fragment);
fragmentTransaction.addToBackStack(backStateName);
fragmentTransaction.commit();
}
It works fine & it saves state, but it does not show previous image's.
Any help, suggestion or tutorials would be highly appreciated. Thank you.
I am trying with the fragment list ....
Initilize the framents list
static List<String> fragments = new ArrayList<String>();
Code to fragment change and take in back stack
String backStateName = fragment.getClass().getName();
FragmentManager manager = getSupportFragmentManager();
//fragment not in back stack, create it.
FragmentTransaction ft = manager.beginTransaction();
if(!fragments.contains(backStateName)) {
// ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
// ft.setCustomAnimations(R.anim.fade_in, R.anim.fade_out);
ft.replace(R.id.frame, fragment);
ft.addToBackStack(backStateName);
ft.commit();
fragments.add(backStateName);
System.out.println("backStateName" + fragments);
}
else
{
ft.replace(R.id.frame, fragment);
ft.commit();
}
onBackpressed
#Override
public void onBackPressed() {
if(fragments.size()>0)
{
fragments.remove(fragments.size()-1);
}
super.onBackPressed();
}
for back remove stack
final android.app.FragmentManager fm = getFragmentManager();
fm.addOnBackStackChangedListener(new android.app.FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
if (getSupportFragmentManager().getBackStackEntryCount() ==0) {
// dLayout.closeDrawers();
finish();
}
else
{
// dLayout.closeDrawers();
}
}
});
You can use the following code.
It will not reload the fragment when you come back from previous fragment:
if (!fragmentPopped) {
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.hide(getFragmentManager().findFragmentById(R.id.container_body));
fragmentTransaction.add(R.id.container_body, fragment);
fragmentTransaction.addToBackStack(backStateName);
fragmentTransaction.commit();
}
You can use
fragmentTransaction.hide(getFragmentManager().findFragmentById(R.id.frame_container));
fragmentTransaction.add(R.id.frame_container, fragment);
fragmentTransaction.addToBackStack(null);
Instead of
fragmentTransaction.replace(R.id.container_body, fragment);
fragmentTransaction.addToBackStack(backStateName);
If you can save the images in the android disk cache when you open the fragment and display the images by reading from the disk cache it might resolve your problem. Follow the below link from google on how to save images in disk cache.
https://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
Below are the steps i think you should follow.
Store your images in the disk cache.
onAttaching your ImagesFragment to the Activity read the images from the disk cache and show them
when the fragment is popped from the backstack your code will automatically read the images from the disk cache.
Hope this helps.
I used multiple fragments with this code.Put this code in your MainActivity where's your framelayout or fragment.
#Override
public void onBackPressed() {
/* Fragment fragment = new SettingActivity();
String title = getString(R.string.app_name);
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container_body, fragment);
fragmentTransaction.commit();
// set the toolbar title
getSupportActionBar().setTitle(title);*/
//Log.e("title:", getTitle().toString());
getSupportActionBar().setTitle("Home");
//Log.e("title:", getTitle().toString());
if (!getTitle().toString().equals("Home")) {
Fragment fragment = new Activity_category();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container_body, fragment).commit();
this.setTitle("Home");
} else {
super.onBackPressed();
}
}
May this will help you.
You taking your fragment in back stack so its didn't fault of your fragment you need to check in your image library. May i know which library are you using. I recommended to use picasso library. I am also using this and getting state saved image in my fragment.
http://square.github.io/picasso/
You can do circular navigation by using below code. You can visit even two fragments as vice-versa by endless.
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
hideLastFragment(fragmentTransaction);
fragmentTransaction.add(R.id.profile_fragmentContainer, youfFragment, fragmentTagName).addToBackStack(fragmentTagName);
fragmentTransaction.commitAllowingStateLoss();
/**
* To hide the last fragment
*
* #param fragmentTransaction FragmentTransaction
*/
public void hideLastFragment(FragmentTransaction fragmentTransaction) {
final int backStackCount = getSupportFragmentManager().getBackStackEntryCount() - 1;
if (backStackCount >= 0) {
String fragmentName = getSupportFragmentManager().getBackStackEntryAt(backStackCount).getName();
Fragment lastFragment = getSupportFragmentManager().findFragmentByTag(fragmentName);
fragmentTransaction.hide(lastFragment);
}
}

Redirect the fragment when click on button

I am using this code for replacing the fragment but there is a problem, it's not replacing the old fragment it just override on old fragment so please tell me what is the problem here.
public void selectFrag1(View rootView) {
Fragment frag;
if (rootView == findViewById(R.id.startup1)) {
frag = new S_SignupFragment();
} else {
frag = new F_SignupFragment();
}
FragmentManager fragManager = getSupportFragmentManager();
FragmentTransaction fragTransaction = fragManager.beginTransaction();
fragTransaction.replace(R.id.fragment_signup,frag);
fragTransaction.commit();
}
Are you sure that you pass the parent view, that is going to hold your fragment on the line fragTransaction.replace(R.id.fragment_signup,frag); ?
For fragmentTransaction.replace(...,...) you need to specify a container for your fragment and the fragment itself. Check where does your R.id.fragment_signup directs. More information you could find in this SO question: Unable to replace fragment on button click
fr = new FragmentOne();
fm = getSupportFragmentManager();
fragmentTransaction = fm.beginTransaction();
fragmentTransaction.add(R.id.fragment_place,fr);
fragmentTransaction.commit();
if you use same code then add this before call first button setonclicklistner

Adding fragments to backStack while moving forward and on clicking back navigating in hierarchy

I am new to Android programming.
I am working on a app in which I use Fragments, and I swap the fragments with
fragmentManager.beginTransaction().replace(R.id.frame_container,fragment)
.addToBackStack(null).commit();
I want to navigate back by clicking the device back button.
How can I do it?
Try doing this,I hope this will help
FragmentManager fm = getSupportFragmentManager();
String tag = f.getFragmentTag(); // instance method of a to get a tag
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.container, f, tag);
ft.addToBackStack(tag);
ft.commit();
}
#Override
public void onBackPressed() {
FragmentManager fm = getSupportFragmentManager();
if (fm.getBackStackEntryCount() > 0)
{
fm.popBackStack();
} else
{
super.onBackPressed();
}
use some id instead of null in addToBackStack method.

Compare fragments

I've got the next code to switch between 4 fragments in a container [Main, A, B, C].
I need back button to go back to [Main] no matter how the user has navigated through fragments. For example, if I go [Main] >> [A] >> [C] when pressing back should go to [Main].
But I'm not getting the desired result. I think that I'm not doing well the coparisson between fragments.
Launcher MainFragment = new Launcher();
public void switchFragment(Fragment pFragment) {
FragmentManager fm = getSupportFragmentManager();
Fragment currentFragment = fm.findFragmentById(R.id.fragment_container);
if (pFragment == MainFragment){
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, pFragment).commit();
}
else if (currentFragment == MainFragment && pFragment != MainFragment){
//Fragment fr = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_container, pFragment).addToBackStack(null).commit();
}
else {
//Fragment fr = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_container, pFragment).commit();
}
currentFragment = pFragment;
}
UPDATE--
I've seen this way is working better, but still makes issue. If I navigate through some fragments without returning back to the Main fragment, when I press back it doesn't go back. It's like if there was some issue with the popbackstack().
public void switchFragment(Fragment pFragment) {
FragmentManager fm = getSupportFragmentManager();
Fragment currentFragment = fm.findFragmentById(R.id.fragment_container);
if (pFragment.equals(MainFragment)){
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, pFragment).commit();
}
else if (currentFragment.equals(MainFragment) && !pFragment.equals(MainFragment)){
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_container, pFragment).addToBackStack(null).commit();
}
else {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_container, pFragment).commit();
}
}
This functionality can be achieved by removing .addToBackStack from your fragment transactions.
Here is the Android reference for back stack functionality within fragments: http://developer.android.com/training/implementing-navigation/temporal.html#back-fragments
I finally get the dessired result just replacing the fragment I want on the back_key onClickListener:
final OnClickListener goBack = new OnClickListener() {
#Override
public void onClick(View v) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container, MainFragment).commit();
}
};
This way, if In the future I need to go back to another fragment instead of the Main, I'll just add a condition to compare fragment tags and do something depending the tag.

Categories

Resources