Detecting when a fragment is on top again (has focus) - android

In my app, my activity has a container with a fragment. When a button in that fragment is clicked, I add a new fragment to the container and add the previous fragment to the backstack.
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.primary_fragment_container, homeFragmentHandler);
fragmentTransaction.addToBackStack(folderId.toString());
fragmentTransaction.commit();
The result is that pressing back closes the top fragment and returns me to the previous fragment, which is exactly how I want it. HOWEVER there are certain elements on the fragment that should be refreshed at this point. When the user clicks back and is returned to the previous fragment, how do I know to refresh the data within that fragment? is there a method such as onResume() for this scenario?

You have to proper add fragments to backstack:
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
MyFragment fragment = new MyFragment ();
transaction.replace(R.id.primary_fragment_container, fragment).addToBackStack(null).commit();

Fragment homeFragmentHandler= new Fragment();
Bundle bundle = new Bundle();
//replace this line below wth something convinient
bundle.putInt("key", value);
fragment.setArguments(bundle);
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.primary_fragment_container, homeFragmentHandler);
fragmentTransaction.addToBackStack(folderId.toString());
fragmentTransaction.commit();
This will send data regarding which fragment/ activity caused the previous fragment to load. Now in its onCreate add this code to check the data in the bundle
//In the onCreate of the original fragment
Bundle bundle = this.getArguments();
if(bundle.getInt(key, defaultValue)!=null{
int myInt = bundle.getInt(key, defaultValue);
// Load the data that needs to be refreshed when original fragment is loaded from the second one
}
No else statement is needed. If the fragment is made from any other activity/ fragment then the bundle.getInt will return null and hence that code inside the statement wont be executed.

Related

Fragment Save State

I've read a lot about save states and fragments, but I can't wrap my head around it.
I have a fragment that is loaded when the user signs in. The user can then choose from a variety of categories, which will replace the current fragment with a new one. In this new fragment, the user can click items in a GridView which will cause a check to appear.
When I press the back button, how would I go about saving the clicked items? onSavedInstanceState is never called, and it seems like my fragment is being created all over again when I try to navigate back.
Some code:
When the user first enters the app
// creates the home fragment
Fragment homeFragment = new HomeFragment();
FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.content_frame, homeFragment);
fragmentTransaction.commit();
When the user clicks on a category
Bundle bundle = new Bundle();
bundle.putSerializable("subCategory", subCategory);
Fragment ingredientsFragment = new IngredientsFragment();
ingredientsFragment.setArguments(bundle);
FragmentTransaction fragmentTransaction =
getActivity().getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, ingredientsFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
When you move From HomeFragment To IngredientsFragment you are replacing 1 fragment by another (HomeFragment By IngredientsFragment) so when you press back from IngredientsFragment then It will remove IngredientsFragment from stack also and HomeFragment is already removed and this is expected behavior.
What you can do is When you invoke IngredientsFragment Fragment then "add" it not replace and when user press back then remove IngredientsFragment from stack.

fragment transaction - pop backstack and then add fragment

I am trying to do the following use case in Android Fragments. I have 2 fragments.
Fragment A -> Fragment B
When a user does something in Fragment B, I want to have the back stack as follows
Fragment A -> Fragment C. So, when the user presses back I want the user to go back to Fragment A.
I have tried the following
mFragmentManager.popBackStackImmediate();
FragmentTransaction fragmentTransaction = fMgr.beginTransaction()
.replace(R.id.base, Fragment_C, "1")
.addToBackStack(null)
.commitAllowingStateLoss();
The problem here is that I can see Fragment A for a short period of time before Fragment C is shown
If I do the following
mFragmentManager.popBackStackImmediate();
FragmentTransaction fragmentTransaction = fMgr.beginTransaction()
.replace(R.id.base, Fragment_C, "1")
.addToBackStack(null)
.commitNowAllowingStateLoss();
I get the error
This transaction is already being added to the back stack
I can get Fragment C to show up if I do this BUT
mFragmentManager.popBackStackImmediate();
FragmentTransaction fragmentTransaction = fMgr.beginTransaction()
.replace(R.id.base, Fragment_C, "1")
.commitNowAllowingStateLoss();
This works and I don't see Fragment A and see Fragment C but the back button takes the user out of the application. So, is it possible that we can pop the back stack of the fragment and then add another fragment to the back stack w/o showing Fragment A AND the back button takes the user back to Fragment A
Here is an easy method to add fragments to fragments or to adapters within fragments...
from your base activity, make your fragment manager static. assume this activity is called dashboard.
static FragmentManager support;
Don't forget to initialize this in onCreate.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_dashboard);
support = getSupportFragmentManager();
define your new fragment inside your adapter or fragment.
users_item_fragment dialog = new users_item_fragment();
//also, let's add some data...
Bundle args = new Bundle();
args.putString("device", devicesList.get(position));
use the following method to add the fragment easily wherever you would like
//pick an easily remembered tag
public void replace(Fragment fragment, String tag){
FragmentManager man = dashboard.support;
FragmentTransaction fragt = man.beginTransaction();
if(!fragment.isAdded()) {
dashboard.lastTag = dashboard.fragtag;//not needed, but helpful w/ backpresses
fragt.add(R.id.fragment_container, fragment, tag)
.hide(man.findFragmentByTag(fragtag)).commit();
dashboard.fragtag = dashboard.tag;//not needed, but helpful w/ backpresses
}
if(fragment.isAdded() && fragment.isHidden()) {
dashboard.lastTag = dashboard.fragtag;//not needed, but helpful w/ backpresses
fragt.show(fragment);
fragt.hide(man.findFragmentByTag(fragtag)).commit();
dashboard.fragtag = dashboard.tag;//not needed, but helpful w/ backpresses
}
}
To implement this with backpresses working correctly, add this in you onBackPress method of your main activity:
#Override
public void onBackPressed() {
FragmentManager man = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = man.beginTransaction();
fragmentTransaction.hide(getSupportFragmentManager().findFragmentByTag(fragtag))
.show(getSupportFragmentManager().findFragmentByTag(lastTag)).commit();
fragtag = lastTag;// holds the last fragment
}
}
It's easy to see the logic here and easy to manipulate back press events using this.

Fragment not showing previous data when coming from another fragment

In my android activity I am using multiple fragments, I am successfully switching these fragments according to my requirement but problem is that when I am switching Fragment 1 to Fragment 2 and back from Fragment 2 to Fragment 1, Fragment 1 not showing previous data Fragment 1 start from stretch, but I want to show previous data same as I was selected.
Here is my code for go Fragment 1 (fragment_search_customerProfile) to Fragment 2 (fragment_CustomerInfo):
FragmentManager manager = getActivity().getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.filterFram, new fragment_Search());
FrameLayout layout = (FrameLayout) rootView.findViewById(R.id.cpFrame);
layout.removeAllViewsInLayout();
transaction.remove(new fragment_search_customerProfile()).commit();
Here is my code for back Fragment 1 (fragment_search_customerProfile) fromFragment 2 (fragment_CustomerInfo):
FragmentManager manager = getActivity().getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
Log.d("fragment_Search", fromSearch + "");
transaction.replace(R.id.custIndoFram, new fragment_search_customerProfile());
FrameLayout layout = (FrameLayout) rootView.findViewById(R.id.custIndoFram);
layout.removeAllViewsInLayout();
transaction.remove(new fragment_CustomerInfo()).commit();
Can anyone explain me how can I stay save my fragment data?
Instead of transaction.replace(R.id.filterFram, new fragment_Search());
you can use transaction.add to add fragment while having the data of first one
transaction.add(R.id.filterFram, new fragment_Search());
transaction.addToBackStack(null);
From fragment two you can use .show instead of replace to show the first fragment
and hide fragment two from the first one. transaction.show(getSupportFragmentManager().findFragmentByTag("firstFragmentTag")).commit();
You can simple keep the instances of the fragments, so in your Activity you would have fields like that.
private Fragment fragment1;
private Fragment fragment2;
And now you can use the sexy replace() option,
To add Fragment1
if (fragment1 == null) {
fragment1 = new fragment_Search();
}
FragmentManager manager = getActivity().getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.filterFram, fragment1);
and same for Fragment2
And you can hold the state of the fragment (data it retrieves) in the Fragment itself, and in your onViewCreated() you check, if the state is not null, you update the view immediately.
class Fragment1 extends Fragment {
private State state;
public void onViewCreated(View v) {
if (state != null) {
// Update UI here
}
}
}
UPDATE
Using your own code
private Fragment fragment1; // This is a field outside of below method
if (fragment1 == null) {
fragment1 = new fragment_Search();
}
FragmentManager manager = getChildFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.filterFram, fragment1).commit();
FrameLayout layout = (FrameLayout) rootView.findViewById(R.id.cpFrame);
layout.removeAllViewsInLayout();
Going to fragment2 should be the same, and this code is used to go to Fragment1 and Fragment2, doesn't matter if you are going back or first time.
You have to add fragment instead of remove or replace

Pass data between two fragments in same activity and update WebView

Hello I'm trying to pass a String value from a fragment to another one. I have a single Activity.
The thing that I'm trying to do is when a listview item is pressed send the value to the another fragment, load the fragment (This I had made with this code):
Fragment cambiarFragment = new FragmentInterurbanos();
Bundle args = new Bundle();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction
.replace(R.id.container, cambiarFragment)
.addToBackStack(null)
.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);
// Commit the transaction
transaction.commit();
And then retrieve the String and update a WebView placed in the new fragment (This method cannot be launched when the user select in NavigationDrawer this section (Fragment).
Thanks for your help in advance!
There are many ways you can achieve this... you could pass the string to the new Fragment through a Bundle like this:
Bundle bundle = new Bundle();
bundle.putString(key, value);
fragment.setArguments(bundle);
or maybe have a DataController class where you store the string and the new fragment retrieves it.

How to get Data from current fragment to other fragment?

I am using Fragment for my current application. Here I have one Fragment FA and I am navigating to the other Fragment FB and I have added FA to the backstack as I want to come to FA fragment on some event to be done in FB fragment. I have a done button in the fragment FB. On Click of that button I need to do two things in the fragment FB which are as follows :-
(a). I need to finish the current fragment FB.
(b). Secondly, I need to pass some data from FB to already existing Fragment FA as I have added it to backstack.
I have just started using Fragments and don't know much about them and I want to sort out this problem.Can anyone suggest something for this, any Help would be appreciable.
Thanks in Advance.
You can pass data from one fragment to another something like below.
Fragment fragment;
fragment = new SingleImage();
Bundle bundle = new Bundle();
bundle.putString("img",actorsList.get(position).getImage());
bundle.putString("desc",actorsList.get(position).getDesc());
fragment.setArguments(bundle);
getActivity().getFragmentManager().beginTransaction().replace(R.id.content_frame, fragment).addToBackStack( "tag" ).commit();
means you can add arguments with fragment to pass to another.
and you can get that data in another fragment using below code
Bundle bundle = this.getArguments();
if(bundle != null)
{
tvdesc.setText(bundle.getString("desc"));
img_url= bundle.getString("img");
}
Since you want only one back stack entry per Fragment, make the back state name the Fragment's class name (via getClass().getName()). Then when replacing a Fragment, use the popBackStackImmediate() method. If it returns true, it means there is an instance of the Fragment in the back stack. If not, actually execute the Fragment replacement logic.
private void replaceFragment (Fragment fragment){
String backStateName = fragment.getClass().getName();
FragmentManager manager = getSupportFragmentManager();
boolean fragmentPopped = manager.popBackStackImmediate (backStateName, 0);
if (!fragmentPopped){ //fragment not in back stack, create it.
FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.content_frame, fragment);
ft.addToBackStack(backStateName);
ft.commit();
}
}

Categories

Resources