Why fragments, and when to use fragments instead of activities?
#1 & #2 what are the purposes of using a fragment & what are the
advantages and disadvantages of using fragments compared to using
activities/views/layouts?
Fragments are Android's solution to creating reusable user interfaces. You can achieve some of the same things using activities and layouts (for example by using includes). However; fragments are wired in to the Android API, from HoneyComb, and up. Let me elaborate;
The
ActionBar
. If you want tabs up there to navigate your app, you quickly see thatActionBar.TabListener
interface gives you aFragmentTransaction
as an input argument to theonTabSelected
method. You could probably ignore this, and do something else and clever, but you'd be working against the API, not with it.The
FragmentManager
handles «back» for you in a very clever way. Back does not mean back to the last activity, like for regular activities. It means back to the previous fragment state.You can use the cool
ViewPager
with aFragmentPagerAdapter
to create swipe interfaces. TheFragmentPagerAdapter
code is much cleaner than a regular adapter, and it controls instantiations of the individual fragments.Your life will be a lot easier if you use Fragments when you try to create applications for both phones and tablets. Since the fragments are so tied in with the Honeycomb+ APIs, you will want to use them on phones as well to reuse code. That's where the compatibility library comes in handy.
You even could and should use fragments for apps meant for phones only. If you have portability in mind. I use
ActionBarSherlock
and the compatibility libraries to create "ICS looking" apps, that look the same all the way back to version 1.6. You get the latest features like theActionBar
, with tabs, overflow, split action bar, viewpager etc.
Bonus 2
The best way to communicate between fragments are intents. When you press something in a Fragment you would typically call StartActivity()
with data on it. The intent is passed on to all fragments of the activity you launch.
Should I use fragments or activities for my app?
For me, all decisions about Activity or Fragment are related to (1) UX (2) Manageability (3) Communication cost across components, etc.
Let me introduce some decisions by examples.
- Is the screen required to launch from outside (Share intent)?
Activity
is better as it can be opened directly from what AndroidManifest gives.
- Does the screen require page-by-page views (recipe pages)?
Fragment
is better as Fragment+ViewPager give flexible paging fuctionality. Moreover, some Android devices or theme editors override Activity opening effects so page-turning animation does not run as expected if we implements it in Activity-by-Activity manner.
- Does the screen execute Camera or Photo intent with
StartActivity
?Activity
is better asOnActivityResult
is hard to manage inner fragments when the app restores back from the Camera apps. For this reason, "writing a post" screen could be a good example to be a single Activity.
- Does the screen have to run regardless of screen on/off (Timers)?
Activity
is better as it can show up faster and lighter without Activity-Fragment dancing.
- Does the screen have a kind of master-detail hierarchy?
Fragment
is better because we could prepare tablet layout.
- Does the screen consume memory a lot?
Activity
is better because we can focus on the activity solely not inner fragments memory usage.
- Does the screen has nested fragments more than 3-depth?
Fragment
, reluctantly. Communication between fragment is unstable and Activity-Fragment bridging/dancing is always headache 1 2. We can make complexity lower but Activity-inside-Fragment-inside-ViewPager-inside-fragment-... is hard to acheive manageability.
Using multiple Fragment
with single Activity
is recommended by professional Android developers but we could decide to create more Activities for easier management and faster understanding.
In your case, I would like to implement components as below.
- MainActivity with Fragments: Ingredients, Categories, Recipe.
- ResultActivity with Fragments: Search and its Results are a kind of master-detail view.
- TimerActivity: It should be good to run in single Activity.
- RecipeActivity: If each recipe has its own id and can be shared as permalink, your app could open directly the recipe page by RecipeActivity. And, it could be better to show recipe even if your app is restored from turned-off or switched back from another app situation.
Should I use fragments or activities?
Hie,
As per my concern, using a view pager with fragments will be more feasible and useful compared to activities or activity transitions. Fragments have their own life cycle and the best part is you can reuse a fragment multiple time in your activity/parent activity class. ViewPager with PagerSlidingTabStrip would be a good one to use for your project and go further. It requires a minimum API level 14 (Android 4.0 and higher), through which you will be able to reach/target more than 70% of today's devices.
This link can help you up.
https://guides.codepath.com/android/Sliding-Tabs-with-PagerSlidingTabStrip
What are the differences between activity and fragment?
Those are two completely different things:
An Activity is an application component that provides a screen, with which users can interact in order to do something. More details:
https://developer.android.com/guide/components/activities/intro-activities
Whereas a Fragment represents a behavior or a portion of user interface in an Activity.
https://developer.android.com/guide/fragments
Are Fragments and Fragment Activities inherently faster than Activities?
I became a believer in Fragments in my last application. Whether or not they are computationally faster, they feel faster because you can swap them in and out basically instantaneously, including full support for the back stack if you do it right (call addToBackStack() on the transaction, or something very similar).
I now use Fragments / Fragment activity for all navigation I want to feel very quick, like clicking on a row to get more details. I only launch new activities for when I want to do a fundamentally different thing and have a clean slate to work with. For instance, I usually have a LoginActivity that deals exclusively with logins/registrations, and at least one more that is the core of the app.
But the fundamental benefit of Fragments still remains their flexibility. I can show fragments on top of other fragments, re-arrange them on different screen sizes, etc. But there are loads of other benefits. It just takes a while to feel natural (just like Activities did at first).
One caveat, I always regret embedding fragments in my layouts. I can't give exact reasons here off the top of my head, but essentially you just lose some flexibility. Instead, I build a normal layout for each fragment, and add a placeholder view in the activity layout, create the fragment programmatically, and use transaction.replace() to add it to the layout. Perhaps because this is the main way I swap fragments in and out of that placeholder view, and prefer to just have a single way of doing things where possible.
Should my logic be on Fragments or on Activities?
Why don't you do this (I don't want to go into design patterns).
- If the operations (which manipulates the UI of the Activity and not the Fragment) you want to perform is going to be accessed by many Fragments then better to do that in activity.
- If the operations (which manipulates the UI only the Fragment) you want to perform is going to affect only one Fragment then its better to do that in that Fragment itself.
- If you want to do the manipulation type of operation on the data fetched from Database then why don't you do that in DB helper class only and pass on the result.
- If the operation you want to perform is neither UI related nor on the data fetched from Database then you can use a Utils class.
Warning: Opinion based answer!
Some questions on when to use fragments and activities
An Activity
should be the host for a collection of related Fragments
. For instance, you might have something like:
Base Activity extends FragmentActivity
LoginActivity extends BaseActivity
-- LoginFragment
-- LoginErrorFragment
-- LoginSignUpFragment
SettingsActivity extends BaseActivity
-- SettingsGeneralFragment
-- SettingsAdvancedFragment
If you try to move all of your logic into a single Activity
, it's going to get unmaintainable very quickly. Another good practice is to have a base Activity
which all of your Activities
extend; since if you suddenly find that there's some functionality you want to provide to all activities, you can just add it to the base class.
Activities vs Fragments for apps
Theoretically, you could have your entire application run on a single Activity and use Fragments for all of the pages.
Each fragment has its own lifecycle within the activity.
MainActivity can look like this
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
loadFragment(2)
}
public fun loadFragment(page: Int){
if(page == 1){
// load login
val manager = supportFragmentManager.beginTransaction()
manager.replace(R.id.fragment_holder, LoginFragment()).commit()
}else{
// load register
val manager = supportFragmentManager.beginTransaction()
manager.replace(R.id.fragment_holder, LoginFragment()).commit()
}
}
}
LoginFragment can look like this
class LoginFragment : Fragment() {
lateinit var myButton: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_login, container, false)
myButton = view.findViewById(R.id.my_button)
myButton.apply {
setOnClickListener { toRegister() }
}
return view;
}
fun toRegister(){
// replace the fragment in main activity with register fragment
(requireActivity() as MainActivity).loadFragment(1)
}
}
RegisterFragment can look like this
class RegisterFragment : Fragment() {
lateinit var mButton: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_register, container, false)
mButton = view.findViewById(R.id.my_button)
mButton.apply {
setOnClickListener { toLogin() }
}
return view;
}
fun toLogin(){
// replacing the fragment in the main activity with the login fragment
(requireActivity() as MainActivity).loadFragment(1)
}
}
Basically, we replace the fragment displayed in the activity by calling loadfragment.
This logic can be applied to as many fragments as is necessary.
Related Topics
How to Refresh Android Listview
Android Imageview Scaling and Translating Issue
How to Pick an Image from Gallery (Sd Card) For My App
This Activity Already Has an Action Bar Supplied by the Window Decor
How to Implement a Viewpager With Different Fragments/Layouts
Focusable Edittext Inside Listview
Example: Communication Between Activity and Service Using Messaging
How to Define Dimens.Xml For Every Different Screen Size in Android
How to Connect to My Http://Localhost Web Server from Android Emulator
How to Set the Part of the Text View Is Clickable
Get/Pick an Image from Android'S Built-In Gallery App Programmatically
Passing Android Bitmap Data Within Activity Using Intent in Android
How to Start a Service When .Apk Is Installed For the First Time
Building and Running App Via Gradle and Android Studio Is Slower Than Via Eclipse
Android Left to Right Slide Animation