Android : Get previous fragment name to do nothing in onCreate - android

I have a detected a bug in my app today : When a user clic on an item in my listview, it launch a new fragment with details about this item. But when the user is in this fragment, if he change orientation of the device, the onCreate method of my first class (which fetch my listview) is called, and the app crashed.
I would like to know if it's possible to get the name of the previous fragment, in order to add a test like the following in my onCreate method :
if (!fragmentName.equals("common")){
Log.d("INFO", "Do nothing in this case, because user was in detail fragment before !"),
} else {
super.onCreate(savedInstanceState);
refreshList(true);
}

I don't think it is possible to get the name of the previous fragment as its creating a new instance of your Fragment object.
If I am right in what you are trying to do you need to somehow store the object for which you are displaying data so that when the Fragment is recreated you can then retrieve the required object. One way is you keep the ID or a unique property of the object in SharedPreferences and then reacquire its data when it reloads from a singleton somewhere.
Basically you may need to change the way you retrieve your data or pass it from the original opening Fragment so that you can retrieve it again if the second Fragment is destroyed.

Related

EditText doesn't update

There are 2 fragments there. One of them contains an EditText (fragmentA).
If I update the EditText by calling EditText.setText() from another Fragment it doesn't display the newly set text although it has been set as I've set a breakpoint and saw it. It still shows the old text.
The following code is executed in the fragment without EditText if user clicks a button:
fragmentA.getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
editTextInFragmentA.setText(text, TextView.BufferType.EDITABLE);
}
}
// Close the fragment
getActivity().getSupportFragmentManager().popBackStack();
What's wrong with this approach? May it be caused by the fact that fragmentA is hidden by another fragment when EditText.setText is called?
I can realize from the popBackStack that your probably using replace when placing fragments into their containers. When a replace transaction is made, the old fragment gets it's state saved and all of the UI components (EditText, TextView, Button) get their state saved as well. Once the state is saved, the UI components gets destroyed such that trying to reference them after the old fragment has been removed from view will not work (usually causing NPEs if you try to set or change something in them but I'm not sure what's happening in your case). Upon going back to the old fragment using popBackStack, the UI is re-inflated within the fragment onCreateView, hence you'll have newly created UI component. In case there's an available saved state, it will be used to revert the UI back to when it was before it got replaced with another fragment. Since the text in the EditText got saved with the saved state, it was reverted back when you went back to the old fragment, hence setting it from the new fragment doesn't help. This technique is for efficiently using memory hence preventing the app from causing OutOfMemory exceptions.
To correct this, the old fragment should contain a callback which the new fragment could call to update the EditText value when UI is re-created. The callback would be passed from the old fragment to the new one, and then the new fragment would call this callback and pass it the new string. This new string should be stored first using a global variable inside the old fragment. When the old fragment is re-creating the UI in it's onCreateView, check if the global string variable is not null and not empty and hence update the EditText using setText().

Realm object is not updated immediately?

I have a fragment A which implements RealmChangeListener, you can go from fragment A to fragment B. On fragment B you can change some data, and then on popBackStack() / backPressed i want fragment A to reflect changes which has been made on fragment B. Is it clear?
The scenario
Fragment A (displays customer info)
Fragment B (user change eg customer name)
Back pressed
Fragment A - show new customer name
But in the last step I see only old customer name. When I go again to Fragment B finally I can see the new name, then on another backpressed to fragment A I also see the new name.
Question: Why I am not able to display new name immediately after FIRST returning from fragment B to fragment A?
If you want to see some code, please feel free to ask me.
EDIT
No, it's not because I'm not updating the UI... After navigating back to fragment A, realm is queried again to gain new data.
This is the problem you are having by the sounds of it.
Fragment A is being created and the UI is being populated with the data from your Realm object X.
You then navigate to Fragment B and updated the Realm object X data
You then navigate back to Fragment A and the UI has not reflected the changes you made to Realm object X on Fragment B.
The solution is you need to update the UI to reflect the changes you had made to Realm object X. You can do this in this in the onResume() method for Fragment A. Here you want to read the new data from Realm object X and update the UI accordingly.
In short, your data object has been updated it's just you have not displayed this new data as you have most likely populated the UI in the onCreate() method for Fragment A. This won't be called again when you navigate back to Fragment A from Fragment B.
You need to register the RealmChangeListener in onCreateView() and detach it in onDestroyView(), but the problem is that when you add the new fragment on top of the other, onDestroyView() will be called.
So your RealmChangeListener will not be called. You should reinitialize the query in onCreateView() before you add the RealmChangeListener to it.
Also, make sure you retain a field reference to your results.

how to save my fragment content? how to refresh my fragment?

I have 2 fragments which are called from the action bar of an activity. Both are gridviews, the first one displays applications with a dedicated adapter, and the second one displays a file list with another adapter. My problem is that when I launch a file then when I back to my activity I switch from one fragment to another, when I come back to the previous one, its content disappears. And when I rotate tablet I have the some problem, because my Fragment restart so for this I think that removing fragment give the possibility to create a new Fragment up to date. How can I save and reload data in my fragment.
How can I manage to update the content of the first fragment while coming back from the second one ? And how to remove fragment after the rotation in order to recreate the Action with new Fragment? I asked this questions but I don't have any responses. the code is given below
If your data is just strings or integers, you can make use of shared preferences to store and retrieve data.
Solution to your first problem -how to save fragment state
Use setRetainInstance(true) in you fragments onCreate() *it prevents your fragment from destroying and hence recreating.
Add your fragment to back stack
declare your adapter globally in fragment and resuse it when you get back.
when, you get back to fragment its onCreateView() method will be called directly. hence initialize your adapter in onCreate() method and use it in onCreateView().
Solution to your second problem -how to update fragment content
For this you can use interface. create interface in your second fragment and implement it in your first fragment. prefer this doc for this,
http://www.vogella.com/tutorials/AndroidFragments/article.html#fragments_activitycommunication

Getting fragment instance in my activity

Is there some way I get already created currently displayed same instance of fragment in my activity. I DON'T to use
findFragmentById(int id), simply I never created that
findFragmentByTag(String tag), because I am not adding tag in every fragment .offcourse due to some requirement.
getFragment(Bundle bundle, String key), because I never am putting in bundle.
Although I may look like fool to mention that, but I want something like this. Is activity keep some fragment instance somewhere.??
What can be the best approach I can take to achieve this requirement.
UPDATE
Okay, so let me tell you why I can't use above methods. If I am adding various fragment in one activity, where I always want to come back to one fragment when back is clicked. (As we have in navigation drawer, u know). And unless there are inner fragment. so for that I don't want to add in the back stack.
Now even if I have the tag associated with my fragments, I cant say for 8 fragment if- else-if-else for getting the tag. That I know is not correct. So first two ways goes out of my option. Now third one. I exactly don't know where to keep it. And even if I keep it where will I get the bundle and key every time I just want my fragment.
You can get from fragment Manager
List<Fragment> fragList=fManager.getFragments();
for(Fragment fr: fragList){
String fragClassName = fr.getClass().getName();
if(fragClassName.equals(Abc.class.getName())){
Log.i("Fragment:","Abc");
}else if (fragClassName.equals(Xyz.class.getName())) {
Log.i("Fragment:","Xyz");
}
}

How to prevent calling onCreateView when back button pressed in fragment in android

In my application, I have tabbar functionality. In one tab i am displaying server data in lisview, and on clicking on that detail page for that list item will be open in new fragment.
But when I press back button from that detail page, every time oncreateview called of previous page, so every time listview created and new fetches new server data. So how to prevent such and just display previous state when back button press?
I know it has been too long to give this answer but what i am guessing is you are replacing your fragment with other one. I mean to say is you are using
ft.replace(R.id.realTabContent, fragment);
to move to other fragment which is you are using in your onItemClick so simple solution is use
ft.add(R.id.realTabContent, fragment);
instead of replacing your fragment.
Understand the difference between replace and add. This will solve your problem.
Replace : it will replace the original fragment and re-create the view when you come back
Add : it will just add a new fragment to stack.
Hope this will help someone who is facing the same problem...
I don't think prevent calling onCreateView is a good idea, beside if the function is not called, there will be exception, so NO, you shouldn't. Instead of doing that, I suggest you move your "listview created and new fetches new server data" into another place where you can call explicitly (when you want, where you want, onCreate() is a good place), don't put it in onCreateView(). Hope this helps.
You should cache your data objects apart from view variables as their references needs to be updated if you are fetching any data from server and don't want to make a call again then use branching to branch out that code.
Create an init() method where you do all initialization and server calls and logically branch out call to init() method whenever you don't want to call init().

Categories

Resources