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.
Related
how to make button to open another fragment. being within a fragment. kotlin
I'm starting in kotlin and I'm having a hard time trying to open a fragment with a button, how do I?
You need to use FragmentManager and FragmentTransaction to add your fragment on the fly. you can call a function similar to this in your button's onClick method. But it is recommended for the parent activity to handle each fragment's lifecycle and the fragments
are not supposed to interact each other. The following is taken from the developer docs, that can be found here.
"Often you will want one Fragment to communicate with another, for example to change the content based on a user event. All Fragment-to-Fragment communication is done either through a shared ViewModel or through the associated Activity. Two Fragments should never communicate directly."
fun createFragmentonTheFly(){
var mFragmentTransaction: FragmentTransaction = getSupportFragmentManager().beginTransaction()
mFragmentTransaction.add(R.id.fr_container,new ProductListFragment())
mFragmentTransaction.commit()
}
The best way to do it would be to add an interface let say onFragmentDetachedLisetner and add one method replaceFragment() or something and make your Activity implement this interaface and had it replace as soon as the fragment is detached and make your fragment that contains your button finish itself when user clicks the button, then your activity will replace it with the one you wanted to start. And also consider reusing fragments, as that is the main purpose of fragments at the first place.
So I currently have an app that has 4 tabs (fragments). They are fragments A,B,C,D, in that order.
Fragment A is the first view opened (along with B because viewPager loads the view before and after the current view).
When I click a button in Fragment A, it sends Data back to MainActivity and then sends that data out to Fragments B and C.
However, this is where the issue comes into play. Since Fragment B was already called, the View isn't updated once I click the button and send the data over, but Fragment C is because the view wasn't called before.
Is there any way that I can remedy this?
You can do it a few ways right.
Just set the data to the fragment and have it update its views
Have all the fragments like B and C register themselves to recieve data from the MainActivity and when MainActivity gets it's data set you tell all the registered receivers of the new data
Recreate the fragment
Use an event bus and tell all subsribers of the new data and MainActivity, Fragment B would get notified of new data. Fragment C would get its data when created by MainActivity
I think this list is pretty endless tbh
The key here is the fragments need to fetch the data from the actvitiy aswell as be updated by the activity. In which case you need to break your UI update behaviour out of onCreateView and into its own updateUI() function. updateUI(MyData) can then be called from onCreateView and also called in a setMyData() on the fragment. Just make sure you check the isAdded flag in setMyData.
This pretty much says it all:
http://developer.android.com/training/basics/fragments/communicating.html
I used a simple fragment communicator that allows the activity to call the fragment, and the same for a fragment to talk to the activity.
You can change the views with the new data based on calling the method from within the activity. The way I do it is set the fragments in the activity then pass them into the page adapter this way I can call the methods within the fragment and implement the fragmentcommunicator interface on the fragments.
You can honestly even avoid the interface if you want, but if you are going to include the same method in all the fragments to talk to them it is easiest.
If you show code, I can show you a quick example.
Just a general question about working with Fragments and Activitys for android development: where does the business end of the functional code go for Fragments loaded into an Activity dynamically? (i.e. a fragment's OnClickListeners, OnCheckedChangedListeners, button logic methods...)
Do they go in the Fragment class, or the Activity class?
All the GUI logic for views attached to a fragment should be contained inside the fragment itself.
Thus a fragment should be as self contained as possible.
You can, though, if necessary do callbacks to your activity based on fragment GUI interaction. This can easily be done like this inside the fragment:
#Override
public void onAttach(Activity activity) {
if (!(activity instanceof SherlockFragmentActivity)) {
throw new IllegalStateException(getClass().getSimpleName()
+ " must be attached to a SherlockFragmentActivity.");
}
mActivity = (SherlockFragmentActivity) activity;
super.onAttach(activity);
}
In this specific case the reason for gaining a reference to SherlockFragmentActivity is to gain access to the support menu inflater mActivity.getSupportMenuInflater(), hence the construction can of course also serve to gain information from the underlying activity.
This probably depends on how much the Fragment's functionalities have in common, and how many, let's say Buttons, have to be handled.
I personally (and it's probably most common practice) handle onClick(...) events separately for each Fragment, meaning that I let each Fragment implement it's own OnClickListener.
Furthermore, when handling everything through the Activity, probably not all the components that react to click-events are in memory at all times and can be reached via findViewById(...), depending on which Fragment is currently displayed and how your user-interface is built up in general.
they always in fragment class because fragment is one type of component in android which we can reuse it. if we put onclick and oncheckchanged in activity then what meaning of reusing that component??
for more information about please go through following step:
Link 1 for basic level of information about fragment and how to handle them
Link 2 for dealing with multi pane fragment
Standard site for fragment
It depends:
If fragment can handle logic which is self sufficient(complete) then that code can be handled by fragment. e.g. on click call phone number.
If fragment have UI whose action is activity specific, then you want to add listener in activity.
e.g. master detail view like email client, on tablet user click on title fragment1 which have list of email titles, then handler on click in activity can show detail fragment2 in activity.
In all you want to keep fragment reusable.
I have 4 tabs in an Activity.
Each of them is a Fragment. And every Fragment has a ListView.
So, if i change the ListView in Fragment, it must change the ListView in all other Fragments ie.., Tabs.
The problem i face is while creating the interface instance.
It takes it's own onClick() method.
In case i want a callback to the parent activity i could have done that by overriding onAttach. But how to make a callback to a Fragment?
From Developers site:
Often you will want one Fragment to communicate with another, for example to change the content based on a user event. All Fragment-to-Fragment communication is done through the associated Activity. Two Fragments should never communicate directly.
So, make a callback to the Activity which in turn makes a callback to other fragments??
Thank You
It's pretty simple,all You need is steps below:
1) From onClick method in your first fragment make a function call of activity:
((IYourActivityInterface) getActivty()).activityMethod();
2) In your activity find fragment by tag or id and run it's method:
public void activityMethod(){
Fragment tabFragment = getFragmentManager().findFragmentByTag("second_fragment");
// or Fragment tabFragment = getFragmentManager().findFragmentById(R.id.frag);
if (tabFragment!=null){
((IFragmentInterface) tabFragment).fragmentMethod();
}
}
Hope this is what you are looking for.)
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.