So, Fragments
satya - Thursday, February 03, 2011 4:10:29 PM
honeycomb fragments
honeycomb fragments
satya - Thursday, February 03, 2011 4:22:30 PM
FragmentManager
FragmentManager
satya - Friday, February 04, 2011 9:03:59 AM
Fragments
Fragments
Search Android Developers Group for: Fragments
Search Android Beginers Group for: Fragments
satya - Friday, February 04, 2011 9:42:07 AM
How to blog from google on fragments
satya - Friday, February 04, 2011 10:55:37 AM
Fragments: A radical UI readjustment
As quoted from the article above
satya - Friday, February 04, 2011 11:06:58 AM
Save and restore becomes real easy
As you rotate the device an activity gets destroyed and recreated. In the process you are forced to remember the state and recreate it. Fragments can be automatically saved and restored.
satya - Friday, February 04, 2011 1:14:30 PM
Key classes/concepts
Fragment
ListFragment
FragmentManager
FragmentTransaction
<fragment> tag
onActivityCreated
onCreateView
satya - Friday, February 04, 2011 1:22:17 PM
FragmentTransaction
FragmentTransaction
satya - Friday, February 04, 2011 2:05:13 PM
A (brief) nice article that explains a bit of FragmentTransaction
A (brief) nice article that explains a bit of FragmentTransaction
satya - Friday, February 04, 2011 2:13:17 PM
what do i know so far on a fragmenttransaction
Allows you to attach a fragment (which provides a view) to a layout id (place holder for a fragement's view). Or replace.
Provide the way you want to animate that show of the fragment
Allow the "back" affordance :) (hope as heaven I am right)
show/hide a fragment or remove a fragment
Allow breadcrumbs for back
satya - Thursday, February 10, 2011 3:02:11 PM
Android developer news blog
Android developer news blog: androidphoneguides.com
There is not a huge list. A handful of articles on 3.0. Perhaps more to come. wait and see.
satya - Thursday, February 10, 2011 3:07:24 PM
A nice analysis of android sample app in honeycomb
A nice analysis of android sample app in honeycomb
This blog talks about fragments, action bar etc.
satya - Saturday, February 12, 2011 10:04:44 AM
How can I pass arguments to a fragment constructor
A derived fragment needs to have a default constructor with no arguments. Given that the pattern to do this
SomeDerivedFragment sdf = new SomeDerivedFragment();
Bundle args = new Bundle();
args.put("somekey", "somevalue");
args.put("someohterkey","someothervalue");
sdf.setArguments(args);
satya - Saturday, February 12, 2011 10:06:42 AM
The you can use these arguments in the createview method
onCreateView(...)
{
Bundle argBundle = this.getArguments();
somestuff =
argBundle.get("somekey","some_default_value");
}
satya - Saturday, February 12, 2011 10:07:35 AM
Why is that?
Perhaps may be this will allow the fragment's state to be saved through the bundle....
satya - Saturday, February 12, 2011 10:15:50 AM
what is a fragment tag?
An arbitrary name you choose for a fragment. You can use this name later to locate the fragment using the fragment manager. The method to use is
findFragmentByTag(string)
it is interesting. views are located through their resource ids. however the fragments by their tag names.
satya - Saturday, February 12, 2011 10:17:48 AM
where can you place a fragment?
This is done through a container. This container appears specifically to be a view. one can pass the resource id of this view. Looks like you can pass a null or 0 for this indicating it is not to be placed in any container.
Not sure then what you do with it??
satya - Saturday, February 12, 2011 10:36:38 AM
Here is how to juggle construction arguments
public class DetailFragment
extends Fragment
{
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState)
{
View v = inflater.inflate(R.layout.main,null);
TextView tv = (TextView)(v.findViewById(R.id.textViewId));
setPrompt(tv);
return v;
}
public static DetailFragment newInstance(String sometext)
{
DetailFragment df = new DetailFragment();
Bundle args = new Bundle();
args.putString("prompttext", sometext);
df.setArguments(args);
return df;
}
private void setPrompt(TextView tv)
{
String s = getPrompt();
if (s == null)
{
s = "No prompt text avilable";
}
tv.setText(s);
}
public String getPrompt()
{
Bundle b = this.getArguments();
if (b == null) return null;
String ps = b.getString("prompttext");
return ps;
}
}//eof-class
satya - Saturday, February 12, 2011 11:15:13 AM
Tell me about FragmentTransaction again
In an activity a fragment transaction allows you to "batch up" a number of operations on a number of fragments. This batch of operations can be replayed if you add that transaction to the "back" stack.
SO what is a back stack?
Usually the back button moves you from an activity to activity. This facility is extended to fragment. More precisely "fragment transactions". when you add these "series of fragment actions" as a "back" to the activity, the activity's back will not go to the previous activity but instead play back this entire "series of fragment actions". This will occur until no back fragment transactions are available. And then the previous activity is shown.
To make use of this facility all you have to do is
FragmentTrasaction ft;
ft.replace(fragment1);
ft.replace(fragment2);
ft.replace(fragment3);
ft.addToBackStack("tx_name_1");
ft.commit
Then you can repeat this code again
//change something about
//fragment1, 2, and 3. and do
FragmentTrasaction ft;
ft.replace(fragment1);
ft.replace(fragment2);
ft.replace(fragment3);
ft.addToBackStack("tx_name_2");
ft.commit
Now if you hit back, you will tx_name_1 replayed.
This is why it is called a transaction because we are repeating a series of actions with a start and stop point
satya - Monday, February 14, 2011 12:58:52 PM
Another way of initializing a fragment: Dave's Pattern
//Psudeo code only.
//Default constructor for
//Auto instantiation
MyFragment(){}
//Specific client explicit Constructors
public MyFragment(arg1)
{
this(arg1,arg2);
}
public MyFragment(arg1, arg2)
{
Bundle bundle = new Bundle();
bundle.put("arg1key",arg1);
bundle.put("arg2key",arg2);
setArguments(bundle);
}
satya - Friday, February 18, 2011 10:44:21 AM
You can insert a fragment tag to bring that fragment to life
<fragment class="com.androidbook.fragments.MyListFragment"
android:id="@+id/titles"
android:layout_width="match_parent"
android:background="@android:color/white"
android:layout_weight="50"
android:layout_height="wrap_content" />
satya - Friday, February 18, 2011 10:46:27 AM
Here is the list fragment
public class MyListFragment extends ListFragment
{
private static String tag = "MyListFragment";
private Context m_ctx = null;
private IReportBack m_reportBack = null;
public MyListFragment()
{
}
@Override
public void onActivityCreated(Bundle savedState)
{
super.onActivityCreated(savedState);
DebugActivity activity = (DebugActivity)getActivity();
m_ctx = activity;
m_reportBack = activity;
// Populate list with our static array of titles.
setListAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_selectable_list_item,
new String[]{"one","two","three"}));
}
@Override
public void onListItemClick(ListView l, View v, int pos, long id)
{
m_reportBack.reportBack(tag, "Position:" + pos);
FragmentTransaction ft = this.getFragmentManager().beginTransaction();
Fragment detailFragment = DetailFragment.newInstance("Position:" + pos);
ft.replace(R.id.details,detailFragment);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.addToBackStack(null);
ft.commit();
}
}//eof -class
satya - Friday, February 18, 2011 11:04:21 AM
You can find a fragment belonging to this activity bya tag
Finds a fragment that was identified by the given tag either when inflated from XML or as supplied when added in a transaction. This first searches through fragments that are currently added to the manager's activity; if no such fragment is found, then all fragments currently on the back stack are searched.
satya - Friday, February 18, 2011 11:05:09 AM
Or you find it by its id
Finds a fragment that was identified by the given id either when inflated from XML or as the container ID when added in a transaction. This first searches through fragments that are currently added to the manager's activity; if no such fragment is found, then all fragments currently on the back stack associated with this ID are searched.
satya - Friday, February 18, 2011 11:25:18 AM
Activity/Fragment/stack structure
A
F1 (3,2,1)
F2 (1)
F3 (5,4,3,2,1)
Explanation:
Activity A has three fragments
F1, F2, F3
F1 has a stack depth of 3
F2 has a stack depth of 1
F3 has a stack depth of 5
satya - Friday, February 18, 2011 12:42:54 PM
A discussion: Fragment question: inter-fragment communication?
A discussion: Fragment question: inter-fragment communication?
satya - Friday, February 18, 2011 12:44:19 PM
A discussion: Can a fragment hold local variables
satya - Friday, February 18, 2011 4:21:21 PM
Inter-fragment communcation: Short Answer
One isn't needed as one can use their regular pointers ...
satya - Friday, February 18, 2011 4:24:45 PM
Discussion: Direct pointers to fragments
Discussion: Direct pointers to fragments
Yes one can maintain direct pointers. See the posts for a bit more detail
satya - Friday, February 18, 2011 4:36:00 PM
You can use a bundle and fragment manager to get at restored fragments
onSaveInstanceState()
{
fm.putFragment(myfragment,bundle,"myfragment");
}
onRestoreInstanceState()
{
this.myfragment = fm.getFragment(bundle,"myfragment");
}
satya - Friday, February 18, 2011 4:40:42 PM
Demystifying fragments: Untethered or unfastened or floating objects
An activity owns all its fragments
An activity has a variable list of fragments
An activity will save and restore and these fragments as the activity is saved and restored
You can hold pointers to these fragments with in a single life time of an activity
Make sure to restore fragment pointers (if you hold them directly) during rebirth
Fragments are essentially unfastened objects that are placed in a collection for better state management
ofcourse there is the added stack operations on top of this essential facility
Each fragmetn is responsible for saving and restoring its internal state through save/restore methods just like an activity
satya - Monday, February 21, 2011 7:49:19 PM
putfragment will work only if the fragment is already a member of that fragment manager
if the fragment is added to the fragment manager, the fragment manager will save and restore that fragment. So it makes sense to request that pointer to that fragment.
Given that nature of fragment restoration, getFragment and putFragment make sense only if the fragment is added.
So the convenience of get and put fragments, and hence direct pointers to fragments may not always work out if you don't have control of when fragments are automatically removed. An example is dismissing dialog.
satya - 9/19/2013 4:25:32 PM
Indications of a worker fragment: from the google docs
When you add a fragment as a part of your activity layout, it lives in a ViewGroup inside the activity's view hierarchy and the fragment defines its own view layout. You can insert a fragment into your activity layout by declaring the fragment in the activity's layout file, as a
satya - 9/19/2013 4:26:30 PM
The life cycle better explained
satya - 9/19/2013 4:28:58 PM
If a fragment is in a layout where am I providing its child view layouts?
To provide a layout for a fragment, you must implement the onCreateView() callback method, which the Android system calls when it's time for the fragment to draw its layout. Your implementation of this method must return a View that is the root of your fragment's layout.
satya - 9/19/2013 4:33:05 PM
More...,.
The system inserts the View returned by the fragment directly in place of the <fragment> element.
satya - 9/19/2013 4:34:53 PM
Fragment identification
Each fragment requires a unique identifier that the system can use to restore the fragment if the activity is restarted (and which you can use to capture the fragment to perform transactions, such as remove it). There are three ways to provide an ID for a fragment:
Supply the android:id attribute with a unique ID.
Supply the android:tag attribute with a unique string.
If you provide neither of the previous two, the system uses the ID of the container view.
satya - 9/19/2013 4:37:00 PM
When you are adding a fragment, you are always adding it to a view group, not to a view
When you are adding a fragment, you are always adding it to a view group, not to a view
satya - 9/19/2013 4:46:20 PM
You always attach/add a fragment to a view in a transaction....
in other words you want to track all your adds as a single unit....
satya - 9/19/2013 4:49:29 PM
You can add a fragment with out UI
In this case you don't need a viewgroup to add it to! This is then strictly to manage or hold on to pointers when the activity restarts!
satya - 9/20/2013 10:29:51 AM
what does popBackStack() does?
It is same as simulating a back button for fragments
satya - 9/20/2013 10:56:49 AM
Implications of addToBackStack()
If I don't call this then I am merging the current fragments into the current state of the UI. No demarcation. Much like me changing any other view!
if I call add to back stack then, I am saying, This unit of work, is a separate layer from the original UI, and when I want to go back take me to the original state!!
So, if I start with an activity with no fragments at all, the original state is the state of the activity with its UI
Now I add 2 fragments. I don't put them on the back stack. Now If I go back the whole activity will go back to its previous activity as if the fragements are just views. (This is what I am thinking and probably right)
On the other hand
if I were to add the same 2 fragments to the back stack and I go back. Now the original activity stays and redisplayed (I think...)
satya - 9/20/2013 11:43:41 AM
executePendingTransactions to the rescue
if adding fragments is time sensitive, you may want to call this method otherwise the commit will happen on the UI thread loop.
satya - 9/20/2013 11:47:09 AM
Fragments have methods that can contribute menu options to the activity
Fragments have methods that can contribute menu options to the activity
satya - 9/20/2013 3:50:42 PM
Android advises that two fragments should never communicate directly!!
Android advises that two fragments should never communicate directly!!
The link above states the following
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.
satya - 9/20/2013 4:01:48 PM
understanding android fragments
understanding android fragments
Search for: understanding android fragments
Unbelievable how much is written about these fragments by looking at these search results! a boat load
satya - 9/20/2013 4:07:24 PM
It is worth reading some stuff on setRetainInstance
It is worth reading some stuff on setRetainInstance
satya - 9/20/2013 4:07:31 PM
setRetainInstance()
setRetainInstance()
satya - 9/20/2013 4:11:49 PM
Here is what it says
Control whether a fragment instance is retained across Activity re-creation (such as from a configuration change). This can only be used with fragments not in the back stack. If set, the fragment lifecycle will be slightly different when an activity is recreated:
onDestroy() will not be called (but onDetach() still will be, because the fragment is being detached from its current activity).
onCreate(Bundle) will not be called since the fragment is not being re-created.
onAttach(Activity) and onActivityCreated(Bundle) will still be called.
satya - 9/20/2013 4:19:30 PM
whats up with setTargetFragment? here is the API
whats up with setTargetFragment? here is the API
it says...
Optional target for this fragment. This 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. The target set here is retained across instances via FragmentManager.putFragment().
fragment: The fragment that is the target of this one.
requestCode: Optional request code, for convenience if you are going to call back with onActivityResult(int, int, Intent).
satya - 9/20/2013 4:29:55 PM
This might throw some light on this subject
satya - 9/20/2013 4:33:56 PM
It appears....
In something like dialog fragments fired off from non dialog fragments can establish a parent child relationships which are maintained across configuration changes.
Although they could be employed for any two random fragments in that activity, this appears to define a more tight relationship when needed.
The general recommendation may still hold where inter fragment communication is encouraged through the parent activity which may be aware of the fragment context better.
satya - 9/20/2013 4:36:00 PM
So for example....
if your fragment wants to remember pointers to 4 other fragments in that activity and assume that they will all be there when it is rotated you can use put fragment and get fragment in the bundle to reestablish connectivity!
The setTargetFragment appears to be a shortcut when you are focusing on one parent fragment.
satya - 9/20/2013 4:51:16 PM
If you are wondering what the requestCode is, see this article on startActivityForResult
If you are wondering what the requestCode is, see this article on startActivityForResult
Because the caller has only one callback method for any number of activities that may be started, he/she needs to know which activity is it that was started!
Or you have the option in case of target fragments to explicitly name a method and not worry about the request code at all!!
satya - 11/1/2013 2:44:33 PM
Where should I initialize a fragment?
The following methods are called in that order.
1. onAttach
2. onCreate
3. onCreateView
4. onActivityCreated
5. onStart
6. onResume
SO which one is appropriate to put the initialization code?
An activity gets attached in onAttach. Activity has no views at that time. As you move down the onCreate also is not ready to see the finsihed views in an activity. The onCreateView is there to supply the view of this fragment. Also onCreateView may not be called under some valid circumstances.
So only in the onActivityCreated all views are ready to go.
So it depends on why you need the initialization for. If you can wait, then onActivityCreated is your guy/gal. onCreateView is a bad choice as it may not get called.
You may even want to wait until onStart or onResume under some circumstances.
satya - 11/2/2013 9:09:52 AM
What activity callback should I make sure my retained fragments or objects are reestablished?
I have used onStart when I did the ADOs (Activity Dependent Objects). This probably was ok if these objects are purely delegated objects and activity doesnt draw from them for its UI state.
The picture is not true probably if the activity relies on these retained objects for its UI state to be constructed.
So perhaps I should move them to the begining of onCreate right after calling the super.
This will ensure the onCreate can rely on the existence of retained fragments,.
This might prompt me to put a callback on a base class to say
onInitRetainedObjects()
{
//register your root retained objects
//register your retained fragments
}