Fragments, Activities, FragmentActivity - android

I've read many posts on stackoverflow about fragments vs activities, but I'm not sure I understand. Am posting a problem I'm working on -- hopefully some of you could help me clarify what they mean in this context.
I want to build an app with two tabs: "take photo" and "browse photo". In take photo, the user can take a photo. In browse photo, the user can browse photos already taken.
So I've made two tabs so far in MainActivity, which extends FragmentActivity and implements ActionBar.TabListener. onCreate of MainActivity creates a SectionsPagerAdapter, which extends from FragmentPagerAdapter. The main purpose of my SectionsPagerAdapter is to create new Fragments. It creates a TakePhotoFragment and a BrowsePhotosFragment.
Question: in TakePhotoFragment, should I create a new activity that takes the photo? I do know how to create an activity that allows the user to take a photo, but not sure if this is right in this case. I did read that fragments are primarily for UI reasons and sit within activities, so it seems kind of weird to create an activity in a fragment (and also I don't know how this could be done).
I guess the main problem I'm facing is that I'm really confused about how activities and fragments can be used, despite all the reading I've done about them. Perhaps someone can help elucidate in the context of what I'm trying to do?
Thanks!

Well just some clarification, a fragment is a content that be put into an activity, not an activity. You will always have one Activity which can host fragments but not the other way.
For the camera thing, it's like using any other feature, you will call an external activity or service, you can do that inside the fragment, just like voice recognition or barcode scan.
Here is a simple example you can try, and adapt it for a fragment.
http://developer.android.com/training/camera/photobasics.html
Hope it helps, good luck with your research .

First of all, you CAN'T create an Activity inside a Fragment.
If you have a code which works within an activity it should also work within a fragment. Just use the fragment's onCreateView instead of Activity's onCreate.
If you use some kind of SurfaceView for taking photos it works within any context. If you call an outer camera intent it has nothing to do with your layout, it just calls the device's photo app, so you can't put it inside your fragment.

Related

Using a no-fragment activity instead of a one-fragment activity

While peer reviewing a colleague's code I noticed she created a new Activity and all functionality is just there without a Fragment.
In the old days of Android, this is what we did, but the last few years I and my peers always took the approach that every Activity should have at least one Fragment and no actual code should be written in the Activity apart from loading the Fragment of-course and maybe some higher end procedures.
I want to argue for always using at least one Fragment in every Activity, but I couldn't find compelling arguments about why it is better than a no-fragment Activity.
The out of the box argument I can think of is that it will be easier adding new fragments if needed, but if we know this will never be a necessity, why bother with a single fragment Activity?
Fragment is easier to extend and test, if you are writing another new feature, it is helpful for separating code. And you can also move your fragment code to another place easy.
Of cource, if you are sure that your code is very simple and stable, like demo or temp test code, you can also use Activity without fragment.

I'm a noob and I'm used to writing reusable code with methods. How do I write the same kind of code with Activities?

I'm writing my first android app, and it's going very well so far, but my code is getting obtuse and I'd like to reorganize it in a way that allows me to reuse portions, and add things more easily.
Based on my previous experience writing simple command line programs that call methods, this is how I THINK I should organize my code:
(some code in MainActivity)
Call a void method of the object DoStuff:
Launch Activity1 and write some values to SharedPreferences file, THEN
Launch Activity2 and write some values to SharedPreferences file, THEN
continue running code from MainActivity
Right now Activity1 and Activity2 both launch at the same time. Is there a different way I should be writing/organizing my code? I guess I'm trying to do thing with Activities that I'm used to doing with methods. But I'm aware that my thinking might be wrong on this. I hope this makes sense.
Thank you for your help!
Your understanding of Activities is wrong. Activities do have methods that you can very well use.
An Activity is basically one screen that you see in your app. It can be started, stopped, resumed, etc. You can have different screens shown in one Activity (e. g. with Fragments).
If for example you have a list of notes in one Activity, you could have the detail of one note shown in another DetailActivity.
Only in rare cases, for example if you want to check on startup what Activity to show you could have another activity that does not have a layout but only does some checks and launches another one.
In each of your activities you can have methods to execute what you want on user interaction. Of course this can also go into other classes.
I would recommend you to start with a basic Android tutorial to gain a better understanding of the concepts.

When (& where) are my fragments created

I'm using the viewpagerindicator library (http://viewpagerindicator.com/) to create some sort of wizard for my android app. It works fine and does exactly what I want.
I would like to "extend" the functionality a bit by having "previous"/"next" buttons in my ActionBar - pretty much as in Android's "Done Bar" tutorial - to step through the wizard. Works like a charm, too.
HOWEVER:
I would like to display information about the "next" & "previous" fragment in the ActionBar's buttons. Information I pass to the fragments that live in the ViewPager at the time of their "creation" (actually at the time of their object instantiation - using the classical "newInstance(...)" approach to create the instance of my fragment, store the parameters in a Bundle and extract them in the fragment's "onCreate" method). The same way the template does it, when you create a new fragment for your project.
So, this information is the thing I actually want to display in my wizards button to know what fragment is next and which was last.
The type of this information is not important for my problem. It could be a String or an icon or an int or ... anything else you want.
However, wherever I've tried to access my fragments data, the fragment has not yet been fully initialized (meaning its "onCreate" method has not been called yet).
I've tried it in the host fragment's "onViewCreated" method, because I thought that's where all its subviews should be initialized already (at least their "onCreate" method should have been called, I thought), but it seems that this is handled differently for ViewPager to retain only the number of fragments in memory that was set by setOffscreenPageLimit.
So, what I'm looking for (and probably just missing) is the correct callback method here. One that is called when the ViewPager's next Fragments have been loaded and initialized. If such a callback exists, I could place my little piece of code there to update the text in my "previous"/"next" buttons within the ActionBar.
Any help, comments, ideas are highly appreciated. If needed, I can also try to attach some code sample to better explain my setup, but I think it should be easy enough to understand what my problem is.
Thanks in advance!
P.S.: I also tried to do this by using EventBus to send "onFragmentInitialized" messages from my fragments within in the ViewPager and the hosting fragment. It actually worked, but it does not seems the proper way to do this.
When a Fragment's onCreate Method is called, its already preparing to be displayed, and practically its past the point where its considered a Next or Previous fragment instead its considered current.
A fragment's onCreateViews method is called after committing a transaction in the FragmentManager. which takes less than 1 sec to bring it in front of the user (depending on the device and runtime environment)
But in your case, your data should be initalized outside the Fragment that uses it, and displayed where ever you want by passing the data itself then displaying whatever you want form it.
decouple your data from android objects (Fragment, Activity ...) and you should be able to load, maintain, access it cleanly and without worrying about their callbacks.
The Fragment's arguments can be read and loaded in its onAttach callback rather than onCreate, the Activity will then (after onAttach is complete) get a onAttachFragment callback with the Fragment as a parameter. However, I doubt onAttachFragment will be called when switching between already loaded pages in the view pager.
If not, you could have the fragment notify the activity (through an interface) that it is now active during its onActivityCreated, onViewCreated or similar method.
But it sounds more like the activity should register as a page changed listener to the ViewPager itself, and update its state depending on the page rather than which fragment is active.
As a side note, ViewPagerIndicator is quite old now (hasn't been updated in 3 years), a more modern approach is the SlidingTabs example from Google, which has been built into a library available here: https://github.com/nispok/slidingtabs

How to make a core of activity on android?

I am new to Android development. After learning from many tutorials I got many Activities and many Fragments. How can I make a core engine to check what Activity is running and what Fragment is showing on a container?
Assume that I have:
Acivity01, Activity02, ... , Activity10
Fragment01, Fragment02, ... , Fragment10
I want to make a class that filters the Activity where Activity is on runtime and what Fragment is embeded to that activity.
How can I do this?
If I understand you correctly, you may want to store some references within your Application class to an Activity and to Fragment instance(-s), which are currently in foreground (by this I mean that user can instantly interact with Activity/Fragment).
As for Activity
Create some Activity field in your Application class and getter/setter methods for it (e.g., setCurrentActivity(), getCurrentActivity()). Then call setCurrentActivity() from onResume() method for each of your Activity instances. Don't forget to call setCurrentActivity, supplying null reference to ir in order to properly handle a case, when there are no foreground activities, but application is stll working.
As for Fragment
The general idea is similar to the first item, but there can be more than one Fragment instance in foreground state at time. So you need to store something like List, where you add your resumed fragments and remove paused.
You may also want to implement something similar for dialogs, for example. Then use the same strategy. Hope it will help.

How to call activity from another fragment.?

I already know how to make a fragment in Android. I want to open another activity in the same fragment on a button click event. The button is inside a fragment class.
How do I do that?
There are two possibilities depending on what you need:
Fragment Receive Result that demonstrates starting a new Activity from a Fragment, and receiving a result back from it.
setTargetFragment may be used, for example, if this fragment is being started by another, and when done wants to give a result back to the first. An example is available here
All Fragment-to-Fragment communication is done through the associated Activity. Two Fragments should never communicate directly.
Here are some tutorials with example
http://mobile.tutsplus.com/tutorials/android/android-sdk-using-fragments/
http://developer.android.com/training/basics/fragments/communicating.html
EDIT: April 2013
I like #AlexLockwood's comment.
In the case that one fragment starts another fragment, it's fine to just use setTargetFragment(Fragment, int) and communicate with it directly by calling getTargetFragment(). Communicating with Fragments through the activity is usually a good idea because it keeps your fragments loosely coupled from one another.

Categories

Resources