So, Fragments

satya - Thursday, February 03, 2011 4:10:29 PM

honeycomb fragments

honeycomb fragments

Search for: honeycomb fragments

satya - Thursday, February 03, 2011 4:22:30 PM

FragmentManager

FragmentManager

Search for: FragmentManager

satya - Friday, February 04, 2011 9:03:59 AM

Fragments

Fragments

Search Google for: Fragments

Search Android Developers Group for: Fragments

Search Android Beginers Group for: Fragments

Search Google Code for: Fragments

Search Android Issues Database for: Fragments

satya - Friday, February 04, 2011 9:42:07 AM

How to blog from google on fragments

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

Search for: 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

Who is Dave?


//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-frag​ment communicat​ion?

A discussion: Fragment question: inter-frag​ment communicat​ion?

satya - Friday, February 18, 2011 12:44:19 PM

A discussion: Can a fragment hold local variables

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 element, or from your application code by adding it to an existing ViewGroup. However, a fragment is not required to be a part of the activity layout; you may also use a fragment without its own UI as an invisible worker for the activity.

satya - 9/19/2013 4:26:30 PM

The life cycle better explained

satya - 9/19/2013 4:27:28 PM

Handling the fragment lifecycle

Handling the fragment lifecycle

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()

Search for: setRetainInstance()

satya - 9/20/2013 4:07:50 PM

Here is its discussion on sof

Here is its discussion on sof

satya - 9/20/2013 4:10:02 PM

Here is the api doc on this method

Here is the api doc on this method

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:24:59 PM

setTargetFragment

setTargetFragment

Search for: setTargetFragment

satya - 9/20/2013 4:29:55 PM

This might throw some light on this subject

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
}