Download - MobAppDev (Fall 2014): Fragments
![Page 1: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/1.jpg)
MobAppDev
Fragments & ViewGroups, Fragment Management, Fragment Creation,
Activity vs Fragment Lifecycles
Vladimir Kulyukin
www.vkedco.blogspot.com
![Page 2: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/2.jpg)
Outline
● Fragments & ViewGroups● Fragment Management● Fragment Creation● Activity vs. Fragment Lifecycle
![Page 3: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/3.jpg)
Fragments & ViewGroups
![Page 4: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/4.jpg)
Fragment Lifecycle
source image at http://developer.android.com/guide/components/fragments.html
![Page 5: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/5.jpg)
Fragments & ViewGroups
● When a fragment is added to an activity layout, it becomes a component in a ViewGroup (a container that may contain other views called children) inside the activity's view hierarchy
● A fragment may define its own view layout● A fragment can be inserted into the activity's layout file via the
tags <fragment></fragment>
![Page 6: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/6.jpg)
Example: ListFragment Inside LinearLayout<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment class="org.vkedco.mobappdev.rumi_quatrain_fragments.QuatrainNumberListFragment"
android:id="@+id/quatrain_numbers"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
![Page 7: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/7.jpg)
Fragments & ViewGroups● Fragments are not required to be a part of the activity layout; there
may be fragments w/o UIs as background workers for activities● A Fragment should be designed as a modular and reusable activity
component● Why? Since fragments may define their own layouts and have their
own lifecycle callbacks, one fragment may be included in multiple activities
● Direct manipulation of one fragment from another fragment should be avoided: breaks modularity and leads to cycle-related errors
![Page 8: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/8.jpg)
Fragments on Tablets
Here is a useful link to the design and implementation practices of how to design fragments for reuse if you want to develop for multiple screen sizes:
http://developer.android.com/guide/practices/tablets-and-handsets.html
![Page 9: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/9.jpg)
Fragment Management
![Page 10: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/10.jpg)
Managing Fragments● Fragments are managed with the FragmentManager class
● FragmentManager object can be obtained via Activity. getFragmentManager()
● FragmentManager is used to:
Find fragments in an activity either with findFragmentById() (for fragments that have IDs) or findFragmentByTag() (for fragments that do not have UIs)
Pop fragments off the back stack, with popBackStack() (this is the same as the user's pressing Back button)
Register a listener for changes to the back stack, with addOnBackStackChangedListener()
open FragmentTransaction objects to add and remove fragments
![Page 11: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/11.jpg)
Fragment Transactions● FragmentTransactions are used to add, remove, replace, and
perform other actions with them, in response to UI gestures● A transaction is a set of changes that must be committed with respect
to the activity● It is also possible to save each transaction to a back stack managed
by the activity● The user can navigate navigate back through the fragment changes
![Page 12: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/12.jpg)
Beginning & Ending Transactions
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
// some code
// each transaction must be committed to take effect
fragmentTransaction.commit();
![Page 13: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/13.jpg)
A Typical Transaction Sequence
// 1) create new fragment and transaction
Fragment newFrgmnt = new SomeFragment();
FragmentTransaction trans = getFragmentManager().beginTransaction();
// 2) replace the contents of the view container with the newly created fragment,
// 3) add the transaction to the back stack
trans.replace(R.id.view_container, newFrgmnt);
trans.addToBackStack(null);
// 4) commit the transaction
transaction.commit();
![Page 14: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/14.jpg)
Fragment Creation
![Page 15: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/15.jpg)
Fragment Creation
● To create a fragment, the developer must either create a subclass of Fragment or a subclass of an existing subclass of Fragment
● The Fragment class has code that looks a lot like an Activity in that it contains callbacks such as onCreate(), onStart(), onPause(), & onStop()
● In many cases, converting existing activities to fragments is as simple as moving code from the activities' callback methods into the corresponding methods of fragments
![Page 16: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/16.jpg)
Fragment Layouts
● To provide a layout for a fragment, the onCreateView() callback must be implemented
● Android system calls this method when the fragment is ready to draw its layout
● The implementation of this method must return the View root of the fragment's layout
● Fragments typically implement UI parts of the host activity
![Page 17: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/17.jpg)
Programmatic Addition of Fragments
// getFragmentManager() is a method of the Activity class
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
// Create a fragment and use the transaction to add the fragment to the view container
SomeFragment frgmnt = new SomeFragment();
fragmentTransaction.add(R.id.view_container, frgmnt);
fragmentTransaction.commit();
![Page 18: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/18.jpg)
Order of Multiple Fragments
● A call to commit() must be last● When multiple fragments are added to the same container, then the
order in which they are added determines the order they appear in the view hierarchy
● If there is no call to addToBackStack() in a transaction removes a fragment, the removed fragment is destroyed after the transaction is committed and the user cannot navigate back to it
![Page 19: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/19.jpg)
Finding Fragments w/in Activity
FragmentManager fm = getFragmentManager();
SomeFragment fragment =
(SomeFragment) fm.findFragmentById(R.id.some_fragment);
![Page 20: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/20.jpg)
Three Important States
● Resumed: fragment is visible● Paused: another activity is in the foreground and has
focus.● Stopped: fragment is not visible
![Page 21: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/21.jpg)
Activity vs Fragment Lifecycles
source image at http://developer.android.com/guide/components/fragments.html
![Page 22: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/22.jpg)
Rumi's Quatrains with Fragments
source code is at https://github.com/VKEDCO/RumiQuatrainFragments
![Page 23: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/23.jpg)
Application Requirements
● Develop an application that uses fragments to display texts of several fragments by Rumi
● The application should work in two modes: landscape and portrait● In portrait mode, only one quatrain can be displayed● In landscape mode, the user can select the quatrains to display
![Page 24: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/24.jpg)
Sample Screenshots
landscape
portrait
![Page 25: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/25.jpg)
Application Class Contents
● RumiQuatrainMainActivity.java – main activity● QuatrainNumberListFragment.java – ListFragment associated with
main activity● QuatrainTextDisplayActivity.java – host activity for
QuatrainTextDisplayFragment.java● QuatrainTextDisplayFragment.java – fragment to display quatrain
texts● The texts of the quatrains and their numbers are in quatrains.xml
![Page 26: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/26.jpg)
AndroidManifest.xml<application android:icon="@drawable/rumi" android:label="Rumi's Quatrains">
<activity android:name="org.vkedco.mobappdev.rumi_quatrain_fragments.RumiQuatrainMainActivity"
android:label="Rumi's Fragments">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="org.vkedco.mobappdev.rumi_quatrain_fragments.QuatrainTextDisplayActivity"
android:label="Quatrain's Text">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
![Page 27: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/27.jpg)
AndroidManifest.xml<application android:icon="@drawable/rumi" android:label="Rumi's Quatrains">
<activity android:name="org.vkedco.mobappdev.rumi_quatrain_fragments.RumiQuatrainMainActivity"
android:label="Rumi's Fragments">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="org.vkedco.mobappdev.rumi_quatrain_fragments.QuatrainTextDisplayActivity"
android:label="Quatrain's Text">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
![Page 28: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/28.jpg)
XML Layout of the Main Activity: Main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment class="org.vkedco.mobappdev.rumi_quatrain_fragments.QuatrainNumberListFragment"
android:id="@+id/quatrain_numbers"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
![Page 29: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/29.jpg)
XML Layout of the Secondary Activity: quatrain_text_display.xml
<LinearLayout>
<ScrollView android:id="@+id/scvQuatrainText"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tvQuatrainText"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</ScrollView>
</LinearLayout>
![Page 30: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/30.jpg)
RumiQuatrainMainActivity.javapublic class RumiQuatrainMainActivity extends Activity {
static final String LOGTAG = RumiQuatrainMainActivity.class.getSimpleName() + "_TAG";
static Resources mRes = null;
static FragmentManager mFrgmntMngr = null;
static RumiQuatrainMainActivity mThisAct = null;
public void onCreate(Bundle savedInstanceState) {
Log.d(LOGTAG, "onCreate()");
super.onCreate(savedInstanceState);
FragmentManager.enableDebugLogging(true);
setContentView(R.layout.main);
mRes = getResources();
mFrgmntMngr = getFragmentManager();
mThisAct = this;
}
![Page 31: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/31.jpg)
Determining Device's Orientation
static boolean isInLandscapeOrientation() {
return mRes.getConfiguration().orientation
== Configuration.ORIENTATION_LANDSCAPE;
}
![Page 32: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/32.jpg)
RumiQuatrainMainActivity.java
● The real workhorse of is displayQuatrainText(int quatrain_index)● It finds a fragment by id and replaces it with a newly created fragment● It also shows how to check the orientation● If the orientation is landscape, then two fragments are displayed● If the orientation is portrait, then a new activity is launched
![Page 33: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/33.jpg)
Displaying Quatrain's Text in Landscape Orientation if ( isInLandscapeOrientation() ) {
// Check what fragment is shown, replace if needed.
QuatrainTextDisplayFragment qTxtFrgmnt = (QuatrainTextDisplayFragment)
mFrgmntMngr.findFragmentById(R.id.quatrain_text);
if (qTxtFrgmnt == null || qTxtFrgmnt.getDisplayedQuatrainIndex() != quatrain_index) {
// Make new fragment to show this selection.
qTxtFrgmnt = QuatrainTextDisplayFragment.newInstance(quatrain_index);
// Execute a transaction, replacing any existing
// fragment inside the frame with the new one.
FragmentTransaction frag_trans = mFrgmntMngr.beginTransaction();
frag_trans.setCustomAnimations(R.animator.bounce_in_down, R.animator.fade_out);
frag_trans.setCustomAnimations(R.animator.bounce_in_down, R.animator.slide_out_right);
frag_trans.replace(R.id.quatrain_text, qTxtFrgmnt);
frag_trans.commit();
}
![Page 34: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/34.jpg)
Displaying Quatrain's Text in Portrait Orientation
Intent intent = new Intent();
intent.setClass(mThisAct, QuatrainTextDisplayActivity.class);
intent.putExtra(mRes.getString(R.string.quat_index_key), quatrain_index);
this.startActivity(intent);
![Page 35: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/35.jpg)
XML Animations
![Page 36: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/36.jpg)
Animating Bounces
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/bounce"
android:valueFrom="-1200"
android:valueTo="0"
android:valueType="floatType"
android:propertyName="Y"
android:duration="2000" />
![Page 37: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/37.jpg)
Animating Left Slides
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/accelerate_decelerate"
android:valueFrom="-1200"
android:valueTo="0"
android:valueType="floatType"
android:propertyName="X"
android:duration="2000" />
![Page 38: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/38.jpg)
Animating Right Slides
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:interpolator/accelerate_decelerate" android:valueFrom="0" android:valueTo="1280" android:valueType="floatType" android:propertyName="X" android:duration="2000" />
![Page 39: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/39.jpg)
Animating Left Slides
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/accelerate_decelerate"
android:valueFrom="-1280"
android:valueTo="0"
android:valueType="floatType"
android:propertyName="X"
android:duration="2000" />
![Page 40: MobAppDev (Fall 2014): Fragments](https://reader034.vdocuments.mx/reader034/viewer/2022051412/548f9770b4795982638b4e1c/html5/thumbnails/40.jpg)
References● http://developer.android.com/guide/components/fragments.html
● S. Komatineni & D. MaClean. Pro Android 4. APRESS
● R. Meier. Pro Android 4 Application Development. WROX