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.
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.
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.
In the latest versions of eclipse (ADT v22.6.2) the create android application now generates an activity_main.xml and a fragment_main.xml. It generates only a single activity class
but this now has an embedded inner static fragment class that is created by the activity in its onCreate method
#Override
protected void onCreate(Bundle savedInstanceState) {
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
....
public static class PlaceholderFragment extends Fragment
My confusion is how to port old code/examples where there was only 1 activity and the main application
logic is usually put in the Activity onCreate method i.e. stuff like findViewById. Listeners
etc
The way I have approached it is that I put all my user created views as members of the static PlaceHolderFragment class. Then I call this in the fragment onCreateView. I still have some logic in the activity and it stores a pointer to the fragment. It updates the views members by calling getters on the fragment. Is this correct or should all logic be moved to the fragment now ?
All the tutorials/examples use the old approach where logic is placed in the activity
so there is no reference documentation for how to use the new files that Eclipse generates for an Android application. Any help appreciated ?
Don't worry about the files that Eclipse generate automatically: You can do whatever that you want!!!
Fragment is a element between an Activity and a container.That's mean that you can put the logic of your code inside of one fragment with not problems.
In theory, fragments are used when you want to manage screens using different modules, containers. It's a fragment, a module, part of one screen (but also can be used in a full screen looking as an activity and with the same behaviour than one activity.) For example, imagine that you have for mobile phone screens, one list of news in one screen, and when you click, your app go to the next screen for show the content of the news, right? Ok, so you can use for these 2 screens: 2 activities for each one or one parent activity with 2 fragments...whatever that you want...
Imagine the same case, for a tablet version of your app, now the left part of the screen you should show the list of news and in the right part of the screen, the contain of each news clicked, right? In that case, would be completly necessary to use one activity parent with two fragments...in that case, we could reuse almost the same case for the mobile phones or tablet.
And now, focus in your question: if you don't want complicate the life (not too much, because work with fragment is easy too) I will recomend you to use only activities for your app.
But, like your question, you want to port, there isn't any problem. Now imagine that your activity is going to be only the class where you are going to manage the fragments. The logic for each screen has to be in each fragment. Use the activity only for replace fragments, or share information between fragments, etc. The activity will be like the orchestra director.
From each fragment, you can access to methods or public variables of your activity using ((NameOfActivity)getActivity()).
Is it clear for you?
One more stuff, in fragment, normally the method that we used for initialize stuffs is onCreateView (and not onCreate like activities).
I am new in android. I often use Activity to change from one screen to another screen with other function. Example from Home Page to Popular page. After that, i know about fragment but i never use it before. So, if i have a application with multi tab on a screen, not use TabHost here. Function of every tab very diffrent, ex : tab Home, tab Popular, tab News, tab Profile ... like Instagram App. I must use that
Activity to change Screen to another Screen, it means: i have Home Activity, Popular Activity, ... and change Activity when change Sreen. Each Activity have each layout.
Use fragment within one Activity. We have multi fragment, example HomeFragment, Popular Fragment... chang replace Fragment when change Screen.
What way is better ?
I want to ask when use only phone screen. ( small size screen, not for tablet).
It's important to think of Android devices as more of a spectrum, than clear "phone" vs. "tablet" buckets. There are many instances where you might want to show more information on screen on medium and large screens. Sometimes, this translates to showing two "Activities" at once.
Using Fragments requires little overhead, but adds measurable flexibility, especially when considered early in the development process. If you use Fragments properly, adapting to larger screens is extremely simple. However, there are a few "gotchas" that may make Fragments appear to be more daunting that they actually are:
Fragment classes must always be declared public (if it's a nested class, it must be static).
In the parent Activity (or FragmentActivity), only add the root Fragment if savedInstanceState == null. If you are managing the state of your Fragment properly, everything is handled for you (scroll position, EditText values, etc).
The parent Activity must call through to onSavedInstanceState in order for the Fragment to properly restore it's state.
setRetainInstance(true) should only be used for "headless" Fragments. This is when you use a Fragment that has no UI, and isn't added to the back stack, which is typically used to do life-cycle dependent work.
Fragments declared in XML cannot be used in a FragmentTransaction (and vice-versa).
Think of a Fragment as a modular view, that provides hooks (callbacks) to it's Activity when something important happens. The Activity decides, based on the available space, whether to launch a new Activity, or show a new Fragment.
You can use either way. If you decide to use the Activity solution, create a base activity class that contains all the Tab functionality. You don't want to implement that in every Activity over and over again.
public class BaseActivity extends Activity {
#Override
public void onCreate(...) {
// Init tabs
}
// Methods for tab handling
}
Every Activity (Popular, Profile, Home, ...) extends BaseActivity
public class PopularActivity extends BaseActivity {
#Override
public void onCreate(...) {
super.onCreate(...);
// Init only the popular activity elements here
}
}
This way you implement the tab functionality only once and get it in every activity.
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.)