I need to do a Fragment that works for all activities (like a banner or something).
I have a HomeActivity, IncidentActivity, ScheludeActivity, etc. but I need to do a fragment or something that could be accessed from all those activities but it need to be instantiate once because it will have a, webview that I don't want to be reloading everytime I change of activity.
Can you give me some advise?
You can create a BaseActivity which these three activities extend from this. The instance of fragment should be single. Your fragment should be retainable(setRetainInstance(true)). Do not forget, you should use the same instance of your Fragment! So, you can control fragment instance in your BaseActivity.
Related
I want to separate logic fragment from activity but the problem is I make api call and save data in fragment. And when user click a item in fragment. I need to send parcelable data to other fragment to show detail info about item.
Is launching fragment in fragment anti pattern for android ?
I would like to hear some opinion about this matter.
Yes, is totally an anti-pattern, remember that you need to see the Activity as a container and fragments as independent sub-screens, so is the Activity responsibility to manage the fragments. I.e.: If you have a Post activity you can have a PostText fragment, a PostImage fragment and all of that is manage by the activity, every fragment is attached to an Activity.
It is not a common practice to have a nested fragment inside a fragment even it can be done. However, it would be better to have an activity as the centric container for all your fragments. You can use EventBus (GreenRobot / Otto) to separate the concerns and do all the API calls in another class and send the results by subscribing to this event.
Based on the example from http://developer.android.com/training/basics/fragments/communicating.html I tried to reproduce the communication between two fragments which are sub fragments of a larger fragment.
In the example, AB activity contains A fragment and B fragment. But I am trying to achieve the same but in my case AB Fragment contains A fragment and B fragment.
The problem is the overridden method in the AB Fragment never gets called. Does this not work because the containing component is a Fragment and not a Activity like in the example? Am I missing out something here?
If you are referring to onClick() or some other onSomething() handler, then these always get called in the Activity class, not the fragment. So in the example you linked, the onArticleSelected() must remain in the Activity, even if you have nested fragments.
To pass info on to the fragment, you have a few options. One, you can keep a reference to the fragment within the activity. This might be lost if your activity recreates (settings event for example).
The second and better way would be to tag your fragments, and then use findFragmentByTag.
When you add your fragment (notice the parameter "my_fragment" which is the tag I gave to the fragment):
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, myFragment, "my_fragment").commit();
Or when you replace one fragment with another:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, myFragment, "my_fragment").comit();
Then, when you want to do something in the fragment from within your onArticleSelected of the activity:
Fragment fragment = getSupportFragmentManger().findFragmentByTag("my_fragment");
if (fragment != null) {
fragment.articleSelected(articleId);
}
You can always use an Interface to communicate between fragments. It is the safest way to do so.
I have 2 Tabs and 2 Corresponding Fragments. On calling the LAUNCH Activity both Tabs were added and then the first one added will be shown. Thus the first Fragments onCreateView is called the second Fragments ones not.
In my case this is an issue because the first Fragment has to call methods on the second Fragment. Inside the second Fragment there is an Objectreference which will be set by calling the onCreateView in the second Fragment.
Therefore I used following code snippet to solve this
actionBar.setSelectedNavigationItem(1);
actionBar.setSelectedNavigationItem(0);
It works but in my opinion there must be another possibility to solve this issue. Like calling the onCreateView of the second Fragment?
Here is the relevant code snippet. The listener is implemented as in android-dev Sample only with small changes not affecting my issue.
simplexFragment corresponds to the first Fragment
graphicFragment corresponds to the second Fragment
// adds two tabs
actionBar.addTab(actionBar.newTab().setText("Input").setTabListener(new TabListener(null, "input_fragment")));
graphicFragment = new GraphicFragment();
actionBar.addTab(actionBar.newTab().setText("Graphic").setTabListener(new TabListener(graphicFragment, "graphic_fragment")));
simplexFragment.setGraphics(graphicFragment); // sets the internal reference!
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// selects the Tab so the GraphicFragments onCreateView will be called
actionBar.setSelectedNavigationItem(1);
actionBar.setSelectedNavigationItem(0);
Thanks for support.
In my case this is an issue because the first Fragment has to call methods on the second Fragment.
This is not how Fragments are meant to work. The idea is a Fragment should be self-contained and re-usable and one Fragment shouldn't know that another exists (or at least shouldn't rely the existence any other Fragment).
For example, suppose you have 3 Fragments and ActivityA uses FragmentA and FragmentB but you have another Activity (ActivityB) which uses FragmentA and FragmentC. In that case, FragmentA doesn't know what the other Fragment is (B or C) and shouldn't even expect there to be another Fragment at all.
The way to achieve what you want is to use callback methods on the Activity and have it perform the actions on any other Fragments (if they exist). It can do this by either calling public methods on the other Fragments or by passing data in the 'arguments' Bundle when it creates the other Fragments.
In my existing app I am porting two activities to fragments. The case is the classic dual panel mode with a list on the left and the content on the right.
The doc says that I should avoid to manipulate fragments within fragments, passing instead through the host activity. Said that I am using callbacks to the activity.
The first doubt (maybe banal) I have is:
How to avoid to duplicate the same code in the activity that hosts the
2 fragments and into the activity that wraps the fragment when not in
dual mode?
I'll try to explain. So I have:
ListFragment and ListFragmentActivity
ContentFragment and ContentFragmentActivity
because both fragments can live independently from each other, then:
HostActivity
that implements a listener invoked from ListFragment for adding/replacing the ContentFragment
My question is: when ListFragment is instead hosted from ListFragmentActivity, how to avoid to duplicate the code present in the HostActivity into ListFragmentActivity.
Guess I am missing something, thanks in advance.
Get rid of ListFragmentActivity. Have HostActivity handle the case where there is either one or both fragments. Then, by definition, there is no code duplication. See: https://github.com/commonsguy/cw-omnibus/tree/master/LargeScreen/EU4You
So, I got the event in my fragment to pass to the activity, so how do I make it so the activity in turns, notifies fragment B to do something. I want to fragment B to populate a custom list when fragment A has a list item clicked on. So, it sends the event to the activity, now how do I get the activity to call events in fragment B?
One way to do it would be like this in your activity:
FragmentB fragmentB = (FragmentB)getFragmentManager().findFragmentById(R.id.fragmentBId);
fragmentB.performSomeTask();
This is of course assuming that you have a publicly accessibly method in FragmentB called performSomeTask();
Hope that helps!
The best practice is probably to create interfaces for both fragments and then have the activity implement the interfaces. You want to have good decoupling between fragments so that you can reuse them in other places.