-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathfragments.html
693 lines (651 loc) · 78 KB
/
fragments.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Android Development: Lecture Notes</title>
<meta name="description" content="Lecture Notes for INFO 448: Android Development.">
<meta name="generator" content="bookdown 0.5 and GitBook 2.6.7">
<meta property="og:title" content="Android Development: Lecture Notes" />
<meta property="og:type" content="book" />
<meta property="og:url" content="https://info448.github.io/" />
<meta property="og:image" content="https://info448.github.io/img/android_icon_transparent.png" />
<meta property="og:description" content="Lecture Notes for INFO 448: Android Development." />
<meta name="github-repo" content="info448/book" />
<meta name="twitter:card" content="summary" />
<meta name="twitter:title" content="Android Development: Lecture Notes" />
<meta name="twitter:description" content="Lecture Notes for INFO 448: Android Development." />
<meta name="twitter:image" content="https://info448.github.io/img/android_icon_transparent.png" />
<meta name="author" content="Joel Ross">
<meta name="date" content="2018-11-19">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<link rel="shortcut icon" href="img/android_icon_transparent.png" type="image/x-icon">
<link rel="prev" href="material-design.html">
<link rel="next" href="intents.html">
<script src="libs/jquery-2.2.3/jquery.min.js"></script>
<link href="libs/gitbook-2.6.7/css/style.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-bookdown.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-highlight.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-search.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-fontsettings.css" rel="stylesheet" />
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-98444716-1', 'auto');
ga('send', 'pageview');
</script>
<style type="text/css">
div.sourceCode { overflow-x: auto; }
table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
margin: 0; padding: 0; vertical-align: baseline; border: none; }
table.sourceCode { width: 100%; line-height: 100%; }
td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
td.sourceCode { padding-left: 5px; }
code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
code > span.dt { color: #902000; } /* DataType */
code > span.dv { color: #40a070; } /* DecVal */
code > span.bn { color: #40a070; } /* BaseN */
code > span.fl { color: #40a070; } /* Float */
code > span.ch { color: #4070a0; } /* Char */
code > span.st { color: #4070a0; } /* String */
code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
code > span.ot { color: #007020; } /* Other */
code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
code > span.fu { color: #06287e; } /* Function */
code > span.er { color: #ff0000; font-weight: bold; } /* Error */
code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
code > span.cn { color: #880000; } /* Constant */
code > span.sc { color: #4070a0; } /* SpecialChar */
code > span.vs { color: #4070a0; } /* VerbatimString */
code > span.ss { color: #bb6688; } /* SpecialString */
code > span.im { } /* Import */
code > span.va { color: #19177c; } /* Variable */
code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code > span.op { color: #666666; } /* Operator */
code > span.bu { } /* BuiltIn */
code > span.ex { } /* Extension */
code > span.pp { color: #bc7a00; } /* Preprocessor */
code > span.at { color: #7d9029; } /* Attribute */
code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
</style>
<link rel="stylesheet" href="css/style.css" type="text/css" />
</head>
<body>
<div class="book without-animation with-summary font-size-2 font-family-1" data-basepath=".">
<div class="book-summary">
<nav role="navigation">
<ul class="summary">
<li><a href="./" class="title">Android Development</a></li>
<li class="divider"></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html"><i class="fa fa-check"></i>About this Book</a></li>
<li class="part"><span><b>I Lectures</b></span></li>
<li class="chapter" data-level="1" data-path="introduction.html"><a href="introduction.html"><i class="fa fa-check"></i><b>1</b> Introduction</a><ul>
<li class="chapter" data-level="1.1" data-path="introduction.html"><a href="introduction.html#android-history"><i class="fa fa-check"></i><b>1.1</b> Android History</a><ul>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#android-versions"><i class="fa fa-check"></i>Android Versions</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#legal-battles"><i class="fa fa-check"></i>Legal Battles</a></li>
</ul></li>
<li class="chapter" data-level="1.2" data-path="introduction.html"><a href="introduction.html#building-apps"><i class="fa fa-check"></i><b>1.2</b> Building Apps</a><ul>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#creating-a-project"><i class="fa fa-check"></i>Creating a Project</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#running-the-app"><i class="fa fa-check"></i>Running the App</a></li>
</ul></li>
<li class="chapter" data-level="1.3" data-path="introduction.html"><a href="introduction.html#app-source-code"><i class="fa fa-check"></i><b>1.3</b> App Source Code</a><ul>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#xml-resources"><i class="fa fa-check"></i>XML Resources</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#the-manifest"><i class="fa fa-check"></i>The Manifest</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#java-activities"><i class="fa fa-check"></i>Java Activities</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#gradle-scripts"><i class="fa fa-check"></i>Gradle Scripts</a></li>
</ul></li>
<li class="chapter" data-level="1.4" data-path="introduction.html"><a href="introduction.html#logging-adb"><i class="fa fa-check"></i><b>1.4</b> Logging & ADB</a><ul>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#log-methods"><i class="fa fa-check"></i>Log Methods</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#logcat"><i class="fa fa-check"></i>Logcat</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#toast"><i class="fa fa-check"></i>Toast</a></li>
</ul></li>
<li class="chapter" data-level="1.5" data-path="introduction.html"><a href="introduction.html#adding-interaction"><i class="fa fa-check"></i><b>1.5</b> Adding Interaction</a></li>
<li class="chapter" data-level="1.6" data-path="introduction.html"><a href="introduction.html#kotlin-setup"><i class="fa fa-check"></i><b>1.6</b> Kotlin</a></li>
</ul></li>
<li class="chapter" data-level="2" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html"><i class="fa fa-check"></i><b>2</b> Resources and Layouts</a><ul>
<li class="chapter" data-level="2.1" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#resources"><i class="fa fa-check"></i><b>2.1</b> Resources</a><ul>
<li class="chapter" data-level="" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#r"><i class="fa fa-check"></i>R</a></li>
<li class="chapter" data-level="" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#alternative-resources"><i class="fa fa-check"></i>Alternative Resources</a></li>
</ul></li>
<li class="chapter" data-level="2.2" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#views"><i class="fa fa-check"></i><b>2.2</b> Views</a><ul>
<li class="chapter" data-level="" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#view-properties"><i class="fa fa-check"></i>View Properties</a></li>
<li class="chapter" data-level="" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#views-and-java"><i class="fa fa-check"></i>Views and Java</a></li>
<li class="chapter" data-level="" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#practice"><i class="fa fa-check"></i>Practice</a></li>
</ul></li>
<li class="chapter" data-level="2.3" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#layouts"><i class="fa fa-check"></i><b>2.3</b> Layouts</a><ul>
<li class="chapter" data-level="" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#linearlayout"><i class="fa fa-check"></i>LinearLayout</a></li>
<li class="chapter" data-level="" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#relativelayout"><i class="fa fa-check"></i>RelativeLayout</a></li>
<li class="chapter" data-level="" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#constraintlayout"><i class="fa fa-check"></i>ConstraintLayout</a></li>
<li class="chapter" data-level="" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#other-layouts"><i class="fa fa-check"></i>Other Layouts</a></li>
<li class="chapter" data-level="" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#combining-and-inflating-layouts"><i class="fa fa-check"></i>Combining and Inflating Layouts</a></li>
</ul></li>
<li class="chapter" data-level="2.4" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#inputs"><i class="fa fa-check"></i><b>2.4</b> Inputs</a></li>
</ul></li>
<li class="chapter" data-level="3" data-path="activities.html"><a href="activities.html"><i class="fa fa-check"></i><b>3</b> Activities</a><ul>
<li class="chapter" data-level="3.1" data-path="activities.html"><a href="activities.html#making-activities"><i class="fa fa-check"></i><b>3.1</b> Making Activities</a></li>
<li class="chapter" data-level="3.2" data-path="activities.html"><a href="activities.html#the-activity-lifecycle"><i class="fa fa-check"></i><b>3.2</b> The Activity Lifecycle</a><ul>
<li class="chapter" data-level="" data-path="activities.html"><a href="activities.html#overriding-the-callback-methods"><i class="fa fa-check"></i>Overriding the Callback Methods</a></li>
<li class="chapter" data-level="" data-path="activities.html"><a href="activities.html#saving-and-restoring-activity-state"><i class="fa fa-check"></i>Saving and Restoring Activity State</a></li>
</ul></li>
<li class="chapter" data-level="3.3" data-path="activities.html"><a href="activities.html#context"><i class="fa fa-check"></i><b>3.3</b> Context</a></li>
<li class="chapter" data-level="3.4" data-path="activities.html"><a href="activities.html#multiple-activities"><i class="fa fa-check"></i><b>3.4</b> Multiple Activities</a><ul>
<li class="chapter" data-level="" data-path="activities.html"><a href="activities.html#activity-intents"><i class="fa fa-check"></i>Intents</a></li>
<li class="chapter" data-level="" data-path="activities.html"><a href="activities.html#back-tasks"><i class="fa fa-check"></i>Back & Tasks</a></li>
<li class="chapter" data-level="" data-path="activities.html"><a href="activities.html#up-navigation"><i class="fa fa-check"></i>Up Navigation</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="4" data-path="data-views.html"><a href="data-views.html"><i class="fa fa-check"></i><b>4</b> Data-Driven Views</a><ul>
<li class="chapter" data-level="4.1" data-path="data-views.html"><a href="data-views.html#listviews-and-adapters"><i class="fa fa-check"></i><b>4.1</b> ListViews and Adapters</a></li>
<li class="chapter" data-level="4.2" data-path="data-views.html"><a href="data-views.html#networking-with-volley"><i class="fa fa-check"></i><b>4.2</b> Networking with Volley</a><ul>
<li class="chapter" data-level="" data-path="data-views.html"><a href="data-views.html#using-volley"><i class="fa fa-check"></i>Using Volley</a></li>
<li class="chapter" data-level="" data-path="data-views.html"><a href="data-views.html#requestqueue-singletons"><i class="fa fa-check"></i>RequestQueue Singletons</a></li>
<li class="chapter" data-level="" data-path="data-views.html"><a href="data-views.html#downloading-images"><i class="fa fa-check"></i>Downloading Images</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="5" data-path="material-design.html"><a href="material-design.html"><i class="fa fa-check"></i><b>5</b> Material Design</a><ul>
<li class="chapter" data-level="5.1" data-path="material-design.html"><a href="material-design.html#the-material-design-language"><i class="fa fa-check"></i><b>5.1</b> The Material Design Language</a></li>
<li class="chapter" data-level="5.2" data-path="material-design.html"><a href="material-design.html#material-styles-icons"><i class="fa fa-check"></i><b>5.2</b> Material Styles & Icons</a></li>
<li class="chapter" data-level="5.3" data-path="material-design.html"><a href="material-design.html#design-support-libraries"><i class="fa fa-check"></i><b>5.3</b> Design Support Libraries</a><ul>
<li class="chapter" data-level="" data-path="material-design.html"><a href="material-design.html#widgets"><i class="fa fa-check"></i>Widgets</a></li>
<li class="chapter" data-level="" data-path="material-design.html"><a href="material-design.html#coordinator-layout"><i class="fa fa-check"></i>Coordinator Layout</a></li>
</ul></li>
<li class="chapter" data-level="5.4" data-path="material-design.html"><a href="material-design.html#animations"><i class="fa fa-check"></i><b>5.4</b> Animations</a></li>
<li class="chapter" data-level="" data-path="material-design.html"><a href="material-design.html#resources-1"><i class="fa fa-check"></i>Resources</a></li>
</ul></li>
<li class="chapter" data-level="6" data-path="fragments.html"><a href="fragments.html"><i class="fa fa-check"></i><b>6</b> Fragments</a><ul>
<li class="chapter" data-level="6.1" data-path="fragments.html"><a href="fragments.html#creating-a-fragment"><i class="fa fa-check"></i><b>6.1</b> Creating a Fragment</a><ul>
<li class="chapter" data-level="" data-path="fragments.html"><a href="fragments.html#activity-to-fragment-communication"><i class="fa fa-check"></i>Activity-to-Fragment Communication</a></li>
</ul></li>
<li class="chapter" data-level="6.2" data-path="fragments.html"><a href="fragments.html#dynamic-fragments"><i class="fa fa-check"></i><b>6.2</b> Dynamic Fragments</a><ul>
<li class="chapter" data-level="" data-path="fragments.html"><a href="fragments.html#instantiating-fragments"><i class="fa fa-check"></i>Instantiating Fragments</a></li>
<li class="chapter" data-level="" data-path="fragments.html"><a href="fragments.html#transactions"><i class="fa fa-check"></i>Transactions</a></li>
<li class="chapter" data-level="" data-path="fragments.html"><a href="fragments.html#inter-fragment-communication"><i class="fa fa-check"></i>Inter-Fragment Communication</a></li>
<li class="chapter" data-level="" data-path="fragments.html"><a href="fragments.html#the-back-stack"><i class="fa fa-check"></i>The Back Stack</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="7" data-path="intents.html"><a href="intents.html"><i class="fa fa-check"></i><b>7</b> Intents</a><ul>
<li class="chapter" data-level="7.1" data-path="intents.html"><a href="intents.html#intents-for-another-activity-explicit"><i class="fa fa-check"></i><b>7.1</b> Intents for Another Activity (Explicit)</a><ul>
<li class="chapter" data-level="" data-path="intents.html"><a href="intents.html#extras"><i class="fa fa-check"></i>Extras</a></li>
</ul></li>
<li class="chapter" data-level="7.2" data-path="intents.html"><a href="intents.html#intents-for-another-app-implicit"><i class="fa fa-check"></i><b>7.2</b> Intents for Another App (Implicit)</a></li>
<li class="chapter" data-level="7.3" data-path="intents.html"><a href="intents.html#intents-for-a-response"><i class="fa fa-check"></i><b>7.3</b> Intents for a Response</a></li>
<li class="chapter" data-level="7.4" data-path="intents.html"><a href="intents.html#listening-for-intents"><i class="fa fa-check"></i><b>7.4</b> Listening for Intents</a></li>
<li class="chapter" data-level="7.5" data-path="intents.html"><a href="intents.html#broadcasts-and-receivers"><i class="fa fa-check"></i><b>7.5</b> Broadcasts and Receivers</a></li>
<li class="chapter" data-level="7.6" data-path="intents.html"><a href="intents.html#menus"><i class="fa fa-check"></i><b>7.6</b> Menus</a><ul>
<li class="chapter" data-level="" data-path="intents.html"><a href="intents.html#action-views"><i class="fa fa-check"></i>Action Views</a></li>
<li class="chapter" data-level="" data-path="intents.html"><a href="intents.html#context-menus"><i class="fa fa-check"></i>Context Menus</a></li>
</ul></li>
<li class="chapter" data-level="7.7" data-path="intents.html"><a href="intents.html#an-intent-example-sms"><i class="fa fa-check"></i><b>7.7</b> An Intent Example: SMS</a></li>
</ul></li>
<li class="chapter" data-level="8" data-path="notifications-settings.html"><a href="notifications-settings.html"><i class="fa fa-check"></i><b>8</b> Notifications & Settings</a><ul>
<li class="chapter" data-level="8.1" data-path="notifications-settings.html"><a href="notifications-settings.html#dialogs"><i class="fa fa-check"></i><b>8.1</b> Dialogs</a><ul>
<li class="chapter" data-level="" data-path="notifications-settings.html"><a href="notifications-settings.html#dialogfragments"><i class="fa fa-check"></i>DialogFragments</a></li>
</ul></li>
<li class="chapter" data-level="8.2" data-path="notifications-settings.html"><a href="notifications-settings.html#notifications"><i class="fa fa-check"></i><b>8.2</b> Notifications</a><ul>
<li class="chapter" data-level="8.2.1" data-path="notifications-settings.html"><a href="notifications-settings.html#tap-actions"><i class="fa fa-check"></i><b>8.2.1</b> Tap Actions</a></li>
</ul></li>
<li class="chapter" data-level="8.3" data-path="notifications-settings.html"><a href="notifications-settings.html#settings"><i class="fa fa-check"></i><b>8.3</b> Settings</a><ul>
<li class="chapter" data-level="" data-path="notifications-settings.html"><a href="notifications-settings.html#sharedpreferences"><i class="fa fa-check"></i>SharedPreferences</a></li>
<li class="chapter" data-level="" data-path="notifications-settings.html"><a href="notifications-settings.html#preference-settings"><i class="fa fa-check"></i>Preference Settings</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="9" data-path="loaders.html"><a href="loaders.html"><i class="fa fa-check"></i><b>9</b> Providers and Loaders</a><ul>
<li class="chapter" data-level="9.1" data-path="loaders.html"><a href="loaders.html#content-providers-intro"><i class="fa fa-check"></i><b>9.1</b> Content Providers</a></li>
<li class="chapter" data-level="9.2" data-path="loaders.html"><a href="loaders.html#cursors"><i class="fa fa-check"></i><b>9.2</b> Cursors</a></li>
<li class="chapter" data-level="9.3" data-path="loaders.html"><a href="loaders.html#loaders"><i class="fa fa-check"></i><b>9.3</b> Loaders</a></li>
<li class="chapter" data-level="9.4" data-path="loaders.html"><a href="loaders.html#other-provider-actions"><i class="fa fa-check"></i><b>9.4</b> Other Provider Actions</a></li>
</ul></li>
<li class="chapter" data-level="10" data-path="files-and-permissions.html"><a href="files-and-permissions.html"><i class="fa fa-check"></i><b>10</b> Files and Permissions</a><ul>
<li class="chapter" data-level="10.1" data-path="files-and-permissions.html"><a href="files-and-permissions.html#file-storage-locations"><i class="fa fa-check"></i><b>10.1</b> File Storage Locations</a></li>
<li class="chapter" data-level="10.2" data-path="files-and-permissions.html"><a href="files-and-permissions.html#permissions"><i class="fa fa-check"></i><b>10.2</b> Permissions</a></li>
<li class="chapter" data-level="10.3" data-path="files-and-permissions.html"><a href="files-and-permissions.html#external-storage"><i class="fa fa-check"></i><b>10.3</b> External Storage</a></li>
<li class="chapter" data-level="10.4" data-path="files-and-permissions.html"><a href="files-and-permissions.html#internal-storage-cache"><i class="fa fa-check"></i><b>10.4</b> Internal Storage & Cache</a></li>
<li class="chapter" data-level="10.5" data-path="files-and-permissions.html"><a href="files-and-permissions.html#example-saving-pictures"><i class="fa fa-check"></i><b>10.5</b> Example: Saving Pictures</a><ul>
<li class="chapter" data-level="10.5.1" data-path="files-and-permissions.html"><a href="files-and-permissions.html#fileproviders"><i class="fa fa-check"></i><b>10.5.1</b> FileProviders</a></li>
</ul></li>
<li class="chapter" data-level="10.6" data-path="files-and-permissions.html"><a href="files-and-permissions.html#sharing-files"><i class="fa fa-check"></i><b>10.6</b> Sharing Files</a></li>
</ul></li>
<li class="chapter" data-level="11" data-path="databases.html"><a href="databases.html"><i class="fa fa-check"></i><b>11</b> Providers and Databases</a><ul>
<li class="chapter" data-level="11.1" data-path="databases.html"><a href="databases.html#review-providers-and-loaders"><i class="fa fa-check"></i><b>11.1</b> Review: Providers and Loaders</a></li>
<li class="chapter" data-level="11.2" data-path="databases.html"><a href="databases.html#sqlite-databases"><i class="fa fa-check"></i><b>11.2</b> SQLite Databases</a></li>
<li class="chapter" data-level="11.3" data-path="databases.html"><a href="databases.html#implementing-a-contentprovider"><i class="fa fa-check"></i><b>11.3</b> Implementing a ContentProvider</a><ul>
<li class="chapter" data-level="" data-path="databases.html"><a href="databases.html#uris-and-types"><i class="fa fa-check"></i>URIs and Types</a></li>
<li class="chapter" data-level="" data-path="databases.html"><a href="databases.html#query-methods"><i class="fa fa-check"></i>Query Methods</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="12" data-path="location.html"><a href="location.html"><i class="fa fa-check"></i><b>12</b> Location</a><ul>
<li class="chapter" data-level="12.1" data-path="location.html"><a href="location.html#localization-techniques"><i class="fa fa-check"></i><b>12.1</b> Localization Techniques</a><ul>
<li class="chapter" data-level="" data-path="location.html"><a href="location.html#gps"><i class="fa fa-check"></i>GPS</a></li>
<li class="chapter" data-level="" data-path="location.html"><a href="location.html#cell-tower-localization"><i class="fa fa-check"></i>Cell Tower Localization</a></li>
<li class="chapter" data-level="" data-path="location.html"><a href="location.html#wifi-localization"><i class="fa fa-check"></i>WiFi Localization</a></li>
<li class="chapter" data-level="" data-path="location.html"><a href="location.html#representing-location"><i class="fa fa-check"></i>Representing Location</a></li>
</ul></li>
<li class="chapter" data-level="12.2" data-path="location.html"><a href="location.html#android-location"><i class="fa fa-check"></i><b>12.2</b> Android Location</a><ul>
<li class="chapter" data-level="" data-path="location.html"><a href="location.html#google-play-services"><i class="fa fa-check"></i>Google Play Services</a></li>
<li class="chapter" data-level="" data-path="location.html"><a href="location.html#accessing-location"><i class="fa fa-check"></i>Accessing Location</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="13" data-path="services.html"><a href="services.html"><i class="fa fa-check"></i><b>13</b> Threads and Services</a><ul>
<li class="chapter" data-level="13.1" data-path="services.html"><a href="services.html#threads-and-processes"><i class="fa fa-check"></i><b>13.1</b> Threads and Processes</a><ul>
<li class="chapter" data-level="" data-path="services.html"><a href="services.html#java-threads"><i class="fa fa-check"></i>Java Threads</a></li>
<li class="chapter" data-level="" data-path="services.html"><a href="services.html#android-threads"><i class="fa fa-check"></i>Android Threads</a></li>
</ul></li>
<li class="chapter" data-level="13.2" data-path="services.html"><a href="services.html#intentservices"><i class="fa fa-check"></i><b>13.2</b> IntentServices</a><ul>
<li class="chapter" data-level="" data-path="services.html"><a href="services.html#the-service-lifecycle"><i class="fa fa-check"></i>The Service Lifecycle</a></li>
</ul></li>
<li class="chapter" data-level="13.3" data-path="services.html"><a href="services.html#example-a-music-service"><i class="fa fa-check"></i><b>13.3</b> Example: A Music Service</a><ul>
<li class="chapter" data-level="" data-path="services.html"><a href="services.html#mediaplayer"><i class="fa fa-check"></i>MediaPlayer</a></li>
<li class="chapter" data-level="" data-path="services.html"><a href="services.html#creating-a-service"><i class="fa fa-check"></i>Creating a Service</a></li>
</ul></li>
<li class="chapter" data-level="13.4" data-path="services.html"><a href="services.html#foreground-services"><i class="fa fa-check"></i><b>13.4</b> Foreground Services</a></li>
<li class="chapter" data-level="13.5" data-path="services.html"><a href="services.html#bound-services"><i class="fa fa-check"></i><b>13.5</b> Bound Services</a></li>
</ul></li>
<li class="chapter" data-level="14" data-path="sensors.html"><a href="sensors.html"><i class="fa fa-check"></i><b>14</b> Sensors</a><ul>
<li class="chapter" data-level="14.1" data-path="sensors.html"><a href="sensors.html#motion-sensors"><i class="fa fa-check"></i><b>14.1</b> Motion Sensors</a><ul>
<li class="chapter" data-level="" data-path="sensors.html"><a href="sensors.html#accessing-sensors"><i class="fa fa-check"></i>Accessing Sensors</a></li>
<li class="chapter" data-level="" data-path="sensors.html"><a href="sensors.html#composite-sensors"><i class="fa fa-check"></i>Composite Sensors</a></li>
</ul></li>
<li class="chapter" data-level="14.2" data-path="sensors.html"><a href="sensors.html#rotation"><i class="fa fa-check"></i><b>14.2</b> Rotation</a><ul>
<li class="chapter" data-level="" data-path="sensors.html"><a href="sensors.html#coordinates"><i class="fa fa-check"></i>Coordinates</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="15" data-path="graphics.html"><a href="graphics.html"><i class="fa fa-check"></i><b>15</b> Graphics and Touch</a><ul>
<li class="chapter" data-level="15.1" data-path="graphics.html"><a href="graphics.html#drawing-graphics"><i class="fa fa-check"></i><b>15.1</b> Drawing Graphics</a><ul>
<li class="chapter" data-level="" data-path="graphics.html"><a href="graphics.html#custom-views"><i class="fa fa-check"></i>Custom Views</a></li>
<li class="chapter" data-level="" data-path="graphics.html"><a href="graphics.html#surfaceviews"><i class="fa fa-check"></i>SurfaceViews</a></li>
</ul></li>
<li class="chapter" data-level="15.2" data-path="graphics.html"><a href="graphics.html#touch-and-gestures"><i class="fa fa-check"></i><b>15.2</b> Touch and Gestures</a><ul>
<li class="chapter" data-level="" data-path="graphics.html"><a href="graphics.html#advanced-gestures"><i class="fa fa-check"></i>Advanced Gestures</a></li>
</ul></li>
<li class="chapter" data-level="15.3" data-path="graphics.html"><a href="graphics.html#property-animation"><i class="fa fa-check"></i><b>15.3</b> Property Animation</a></li>
</ul></li>
<li class="part"><span><b>II Additional Topics (Labs)</b></span></li>
<li class="chapter" data-level="16" data-path="styles-themes.html"><a href="styles-themes.html"><i class="fa fa-check"></i><b>16</b> Styles & Themes</a><ul>
<li class="chapter" data-level="16.1" data-path="styles-themes.html"><a href="styles-themes.html#defining-styles"><i class="fa fa-check"></i><b>16.1</b> Defining Styles</a><ul>
<li class="chapter" data-level="" data-path="styles-themes.html"><a href="styles-themes.html#style-inheritance"><i class="fa fa-check"></i>Style Inheritance</a></li>
<li class="chapter" data-level="" data-path="styles-themes.html"><a href="styles-themes.html#built-in-styles"><i class="fa fa-check"></i>Built-in Styles</a></li>
<li class="chapter" data-level="" data-path="styles-themes.html"><a href="styles-themes.html#styles-for-text-views"><i class="fa fa-check"></i>Styles for Text Views</a></li>
</ul></li>
<li class="chapter" data-level="16.2" data-path="styles-themes.html"><a href="styles-themes.html#themes"><i class="fa fa-check"></i><b>16.2</b> Themes</a><ul>
<li class="chapter" data-level="" data-path="styles-themes.html"><a href="styles-themes.html#material-themes"><i class="fa fa-check"></i>Material Themes</a></li>
<li class="chapter" data-level="" data-path="styles-themes.html"><a href="styles-themes.html#theme-attributes"><i class="fa fa-check"></i>Theme Attributes</a></li>
</ul></li>
<li class="chapter" data-level="" data-path="styles-themes.html"><a href="styles-themes.html#resources-2"><i class="fa fa-check"></i>Resources</a></li>
</ul></li>
<li class="chapter" data-level="17" data-path="fragment-viewpager.html"><a href="fragment-viewpager.html"><i class="fa fa-check"></i><b>17</b> Fragments: ViewPager</a><ul>
<li class="chapter" data-level="17.1" data-path="fragment-viewpager.html"><a href="fragment-viewpager.html#define-a-searchfragment"><i class="fa fa-check"></i><b>17.1</b> Define a SearchFragment</a></li>
<li class="chapter" data-level="17.2" data-path="fragment-viewpager.html"><a href="fragment-viewpager.html#add-the-viewpager-and-adapter"><i class="fa fa-check"></i><b>17.2</b> Add the ViewPager and Adapter</a></li>
<li class="chapter" data-level="17.3" data-path="fragment-viewpager.html"><a href="fragment-viewpager.html#add-user-interaction"><i class="fa fa-check"></i><b>17.3</b> Add User Interaction</a></li>
</ul></li>
<li class="chapter" data-level="18" data-path="bluetooth.html"><a href="bluetooth.html"><i class="fa fa-check"></i><b>18</b> Bluetooth</a></li>
<li class="chapter" data-level="19" data-path="maps.html"><a href="maps.html"><i class="fa fa-check"></i><b>19</b> Maps</a><ul>
<li class="chapter" data-level="19.1" data-path="maps.html"><a href="maps.html#create-a-map-activity"><i class="fa fa-check"></i><b>19.1</b> Create a Map Activity</a><ul>
<li class="chapter" data-level="" data-path="maps.html"><a href="maps.html#getting-an-api-key"><i class="fa fa-check"></i>Getting an API Key</a></li>
<li><a href="maps.html#the-supportmapfragment">The <code>SupportMapFragment</code></a></li>
</ul></li>
<li class="chapter" data-level="19.2" data-path="maps.html"><a href="maps.html#specifying-the-user-interface"><i class="fa fa-check"></i><b>19.2</b> Specifying the User Interface</a></li>
<li class="chapter" data-level="19.3" data-path="maps.html"><a href="maps.html#markers-and-drawings"><i class="fa fa-check"></i><b>19.3</b> Markers and Drawings</a><ul>
<li class="chapter" data-level="" data-path="maps.html"><a href="maps.html#drawing-shapes"><i class="fa fa-check"></i>Drawing Shapes</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="20" data-path="memory.html"><a href="memory.html"><i class="fa fa-check"></i><b>20</b> Memory Management</a><ul>
<li class="chapter" data-level="20.1" data-path="memory.html"><a href="memory.html#memory-allocation"><i class="fa fa-check"></i><b>20.1</b> Memory Allocation</a></li>
<li class="chapter" data-level="20.2" data-path="memory.html"><a href="memory.html#the-memory-monitor"><i class="fa fa-check"></i><b>20.2</b> The Memory Monitor</a><ul>
<li class="chapter" data-level="" data-path="memory.html"><a href="memory.html#garbage-collection"><i class="fa fa-check"></i>Garbage Collection</a></li>
</ul></li>
<li class="chapter" data-level="20.3" data-path="memory.html"><a href="memory.html#memory-leaks"><i class="fa fa-check"></i><b>20.3</b> Memory Leaks</a></li>
</ul></li>
<li class="chapter" data-level="21" data-path="multi-touch.html"><a href="multi-touch.html"><i class="fa fa-check"></i><b>21</b> Multi-Touch</a><ul>
<li class="chapter" data-level="21.1" data-path="multi-touch.html"><a href="multi-touch.html#identifying-fingers"><i class="fa fa-check"></i><b>21.1</b> Identifying Fingers</a></li>
<li class="chapter" data-level="21.2" data-path="multi-touch.html"><a href="multi-touch.html#drawing-touches"><i class="fa fa-check"></i><b>21.2</b> Drawing Touches</a></li>
<li class="chapter" data-level="21.3" data-path="multi-touch.html"><a href="multi-touch.html#moving-fingers"><i class="fa fa-check"></i><b>21.3</b> Moving Fingers</a></li>
<li class="chapter" data-level="21.4" data-path="multi-touch.html"><a href="multi-touch.html#other-multi-touch-gestures"><i class="fa fa-check"></i><b>21.4</b> Other Multi-Touch Gestures</a></li>
</ul></li>
<li class="appendix"><span><b>Appendix</b></span></li>
<li class="chapter" data-level="A" data-path="java-review.html"><a href="java-review.html"><i class="fa fa-check"></i><b>A</b> Java Review</a><ul>
<li class="chapter" data-level="A.1" data-path="java-review.html"><a href="java-review.html#building-apps-with-gradle"><i class="fa fa-check"></i><b>A.1</b> Building Apps with Gradle</a></li>
<li class="chapter" data-level="A.2" data-path="java-review.html"><a href="java-review.html#class-basics"><i class="fa fa-check"></i><b>A.2</b> Class Basics</a></li>
<li class="chapter" data-level="A.3" data-path="java-review.html"><a href="java-review.html#inheritance"><i class="fa fa-check"></i><b>A.3</b> Inheritance</a></li>
<li class="chapter" data-level="A.4" data-path="java-review.html"><a href="java-review.html#interfaces"><i class="fa fa-check"></i><b>A.4</b> Interfaces</a></li>
<li class="chapter" data-level="A.5" data-path="java-review.html"><a href="java-review.html#polymorphism"><i class="fa fa-check"></i><b>A.5</b> Polymorphism</a></li>
<li class="chapter" data-level="A.6" data-path="java-review.html"><a href="java-review.html#abstract-methods-and-classes"><i class="fa fa-check"></i><b>A.6</b> Abstract Methods and Classes</a></li>
<li class="chapter" data-level="A.7" data-path="java-review.html"><a href="java-review.html#generics"><i class="fa fa-check"></i><b>A.7</b> Generics</a></li>
<li class="chapter" data-level="A.8" data-path="java-review.html"><a href="java-review.html#nested-classes"><i class="fa fa-check"></i><b>A.8</b> Nested Classes</a></li>
</ul></li>
<li class="chapter" data-level="B" data-path="java-swing.html"><a href="java-swing.html"><i class="fa fa-check"></i><b>B</b> Java Swing Framework</a><ul>
<li class="chapter" data-level="B.1" data-path="java-swing.html"><a href="java-swing.html#events"><i class="fa fa-check"></i><b>B.1</b> Events</a></li>
<li class="chapter" data-level="B.2" data-path="java-swing.html"><a href="java-swing.html#layouts-and-composites"><i class="fa fa-check"></i><b>B.2</b> Layouts and Composites</a></li>
</ul></li>
<li class="chapter" data-level="C" data-path="publishing.html"><a href="publishing.html"><i class="fa fa-check"></i><b>C</b> Publishing</a><ul>
<li class="chapter" data-level="C.1" data-path="publishing.html"><a href="publishing.html#signing-an-app"><i class="fa fa-check"></i><b>C.1</b> Signing an App</a><ul>
<li><a href="publishing.html#release-.apk">Release <code>.apk</code></a></li>
</ul></li>
</ul></li>
<li class="divider"></li>
<li><a href="https://github.com/rstudio/bookdown" target="blank">Published with bookdown</a></li>
</ul>
</nav>
</div>
<div class="book-body">
<div class="body-inner">
<div class="book-header" role="navigation">
<h1>
<i class="fa fa-circle-o-notch fa-spin"></i><a href="./">Android Development: Lecture Notes</a>
</h1>
</div>
<div class="page-wrapper" tabindex="-1" role="main">
<div class="page-inner">
<section class="normal" id="section-">
<div id="fragments" class="section level1">
<h1><span class="header-section-number">Lecture 6</span> Fragments</h1>
<p>This lecture discusses Android <a href="https://developer.android.com/guide/components/fragments.html"><strong>Fragments</strong></a>. A Fragment is “a behavior or a <em>portion</em> of user interface in Activity.” You can think of them as “mini-activities” or “sub-activities”. Fragments are designed to be <strong>reusable</strong> and <strong>composable</strong>, so you can mix and match them within a single screen of a user interface. While XML resource provide reusable and composable <em>views</em>, Fragments provide reusable and composable <em>controllers</em>. Fragments allow us to make re-usable pieces of Activities that can have their own layouts, data models, event callbacks, etc.</p>
<p class="alert alert-info">
This lecture references code found at <a href="https://github.com/info448/lecture06-fragments" class="uri">https://github.com/info448/lecture06-fragments</a>.
</p>
<p>Fragments were introduced in API 11 (Honeycomb), which provided the first “tablet” version of Android. Fragments were designed to provide a UI component that would allow for side-by-side activity displays appropriate to larger screens:</p>
<div class="figure">
<img src="img/fragments/fragments.png" alt="Fragment example, from Google." />
<p class="caption">Fragment example, from Google<a href="#fn17" class="footnoteRef" id="fnref17"><sup>17</sup></a>.</p>
</div>
<p>Instead of needing to navigate between two related views (particularly for this “master and detail” setup), the user can see both views within the same Activity… but those “views” could also be easily split between two Activities for smaller screens, because their required <em>controller logic</em> has been isolated into a Fragment.</p>
<p class="alert alert-warning">
Fragments are intended to be <strong>modular</strong>, <strong>reusable</strong> components. They should <strong><em>not</em></strong> depend on the Activity they are inside, so that you can be flexible about when and where they are displayed!
</p>
<p>Although Fragments are like “mini-Activities”, they are <em>always</em> embedded inside an <code>Activity</code>; they cannot exist independently. While it’s possible to have Fragments that are not visible or that don’t have a UI, they still are part of an Activity. Because of this, a Fragment’s lifecycle is directly tied to its containing Activity’s lifecycle. (e.g., if the Activity is paused, the Fragment is too. If the Activity is destroyed, the Fragment is too). However, Fragments also have their own lifecycle with corresponding lifecycle callbacks functions.</p>
<div class="pull-right">
<div class="figure">
<img src="img/fragments/fragment_lifecycle.png" alt="Fragment lifecycle state diagram, from Google." />
<p class="caption">Fragment lifecycle state diagram,<br>from Google<a href="#fn18" class="footnoteRef" id="fnref18"><sup>18</sup></a>.</p>
</div>
</div>
<p>The Fragment lifecycle is very similar to the Activity lifecycle, with a couple of additional steps:</p>
<ul>
<li><p><strong><code>onAttach()</code></strong>: called when the Fragment is first associated with (“added to”) an Activity, and thus gains a <strong>Context</strong>. This callback is generally used for initializing communication between the Fragment and its Activity.</p>
<p>This callback is mirrored by <code>onDetach()</code>, for when the Fragment is removed from an Activity.</p></li>
<li><p><strong><code>onCreateView()</code></strong>: called when the View (the user interface) is about to be drawn. This callback is used to establish any details dependent on the View (including adding event listeners, etc).</p>
<p>Note that code initializing data models, or anything that needs to be <em>persisted</em> across configuration changes, should instead be done in the <code>onCreate()</code> callback. <code>onCreate()</code> is not called if the fragment is <em>retained</em> (see below).</p>
<p>This callback is mirrored by <code>onDestroyView()</code>, for when the Fragment’s UI View hierarchy is being removed from the screen.</p></li>
<li><p><strong><code>onActivityCreated()</code></strong>: called when the <em>containing Activity’s</em> <code>onCreate()</code> method has returned, and thus indicates that the Activity is fully created. This is useful for <em>retained</em> Fragments.</p>
<p>This callback has no mirror!</p></li>
</ul>
<div id="creating-a-fragment" class="section level2 clear">
<h2><span class="header-section-number">6.1</span> Creating a Fragment</h2>
<p>In order to illustrate how to make a Fragment, we will <a href="https://en.wikipedia.org/wiki/Code_refactoring"><strong>refactor</strong></a> the <code>MainActivity</code> to use Fragments for displaying a list of movies. This will help to illustrate the relationship between Activities and Fragments.</p>
<p>To create a Fragment, you subclass the <code>Fragment</code> class. Let’s make one called <code>MovieListFragment</code> (in a <code>MovieListFragment.java</code> file). You can use Android Studio to do this work: via the <code>File > New > Fragment > Fragment (blank)</code> menu option. (<strong>DO NOT</strong> select any of the other options for in the wizard for now; they provide template code that can distract from the core principles).</p>
<p>There are two versions of the <code>Fragment</code> class: one in the framework’s <code>android.app</code> package and one in the <code>android.support.v4</code> package. The later package refers to the <a href="https://developer.android.com/topic/libraries/support-library/index.html">Support Library</a>. As discussed in the previous chapter, these are libraries of classes designed to make Android applications <em>backwards compatible</em>: for example, <code>Fragment</code> and its related classes came out in API 11 so aren’t in the <code>android.app</code> package for earlier devices. By including the support library, we can include those classes on older devices as well!</p>
<ul>
<li><p>Support libraries <em>also</em> include additional convenience and helper classes that are not part of the core Android package. These include interface elements (e.g., <code>ConstraintLayout</code>, <code>RecyclerView</code>, or <a href="https://developer.android.com/reference/android/support/v4/view/ViewPager.html"><code>ViewPager</code></a>) and <a href="https://developer.android.com/reference/android/support/v4/view/accessibility/package-summary.html">accessibility</a> classes. See <a href="https://developer.android.com/topic/libraries/support-library/features.html">the features list</a> for details. Thus it is often useful to include and utilize support library versions of classes even when targeting later devices so that you don’t need to “roll your own” versions of these convenience classes.</p></li>
<li><p>The main disadvantage to using support libraries is that they need to be included in your application, so will make the final <code>.apk</code> file larger (and may potentially require workarounds for method count limitations). You will also run into problems if you try and mix and match versions of the classes (e.g., from different versions of the support library). But as always, you should <em>avoid premature optimization</em>. Thus in this course you should <strong>default</strong> to using the support library version of a class when given a choice!</p></li>
<li><p>Note that the <a href="https://developer.android.com/jetpack/androidx/"><code>androidx</code></a> package that is being developed as part of <a href="https://developer.android.com/jetpack/">Jetpack</a> will likely be replacing support libraries.</p></li>
</ul>
<p>After we’ve created the <code>MovieListFragment.java</code> file, we’ll want to specify a layout for that Fragment (so it can be shown on the screen). As part of using the New Fragment Wizard we were provided with a <code>fragment_movie_list</code> layout that we can use.</p>
<ul>
<li>Since we want the Movie list to live in that Fragment, we can move (copy) the View definitions from <code>activity_main</code> into <code>fragment_movie_list</code>.</li>
<li>We will then adjust <code>activity_main</code> so that it instead contains an empty <code>FrameLayout</code>. This will act as a simple <strong>“container”</strong> for our Fragment (similar to an empty <code><div></code> in HTML). <em>Be sure to give it an <code>id</code> so we can refer to it later!</em>.</li>
</ul>
<p>It is possible to include the Fragment directly through the XML, using the XML to instantiate the Fragment (the same way that we have the XML instantiate Buttons). We do this by specifying a <code><fragment></code> element, with an <code>android:name</code> attribute assigned a reference to the <code>Fragment</code> class:</p>
<div class="sourceCode"><pre class="sourceCode xml"><code class="sourceCode xml"><span class="kw"><fragment</span>
<span class="ot"> android:id=</span><span class="st">"@+id/fragment"</span>
<span class="ot"> android:name=</span><span class="st">"edu.uw.fragmentdemo.MovieListFragment"</span>
<span class="ot"> android:layout_width=</span><span class="st">"match_parent"</span>
<span class="ot"> android:layout_height=</span><span class="st">"match_parent"</span><span class="kw">/></span></code></pre></div>
<p>Defining the Fragment in the XML works (and will be fine to start with), but in practice it is <em>much</em> more common and worthwhile to instantiate the Fragments <strong>dynamically</strong> at runtime in the Java/Kotlin code—thereby allowing the Fragments to be dynamically determined and changed. We will start with the XML version to build the Fragment initially, and then shift to the Kotlin version to talk about changing Fragments.</p>
<p>We can next begin filling in the Kotlin logic for the Fragment. Android Studio provides a little starter code: the <code>onCreateView()</code> callback, which is what we will use that to set up the layout (similar to what we do with the <code>onCreate()</code> method of <code>MainActivity</code>). But the <code>MainActivity#onCreate()</code> method specifies a layout by calling <code>setContentView()</code> and passing a resource id. With Fragments, we can’t just “set” the View because the Fragment <em>belongs to</em> an Activity, and so will exist <em>inside</em> of that Activity’s View hierarchy! Instead, we need to figure out which ViewGroup the Fragment is inside of, and then <strong>inflate</strong> the Fragment’s View inside that ViewGroup.</p>
<p>This “inflated” View is referred to as the <strong><em>root view</em></strong>: it is the “root” of the Fragment’s View tree (the View that all the Views inside the Fragment’s layout will be attached to). We access the root view by <em>inflating</em> the fragment’s layout, and saving a reference to the inflated View:</p>
<div class="sourceCode"><pre class="sourceCode java"><code class="sourceCode java"><span class="co">//java</span>
<span class="bu">View</span> rootView = inflater.<span class="fu">inflate</span>(R.<span class="fu">layout</span>.<span class="fu">fragment_layout</span>, container, <span class="kw">false</span>);</code></pre></div>
<div class="sourceCode"><pre class="sourceCode kotlin"><code class="sourceCode kotlin"><span class="co">//kotlin</span>
<span class="kw">val</span> <span class="va">rootView</span> = inflater.inflate(R.layout.fragment_layout, container, <span class="kw">false</span>)</code></pre></div>
<ul>
<li>Note that the <code>inflater</code> object we are calling <code>inflate()</code> on was passed as a parameter to the <code>onCreateView()</code> callback. The parameters to the <code>inflate()</code> method are: the layout to inflate, the <code>ViewGroup</code> (<code>container</code>) into which the layout should be inflated (also passed as a parameter to the callback), and whether or not to “attach” the inflated layout to the container (<code>false</code> in this case because the Fragment system already handles the attachment, so the inflate method doesn’t need to). The <code>onCreateView()</code> callback must <code>return</code> the inflated <em>root view</em>, so that the system can perform this attachment.</li>
</ul>
<p>With the Fragment’s layout defined, we can start moving functionality from the Activity into the Fragment.</p>
<ul>
<li><p>The <code>ListView</code> and <code>adapter</code> setup will need to be moved over. The UI setup (including initializing the Adapter) will be moved from the Activity’s <code>onCreate()</code> to the Fragment’s <code>onCreateView()</code>. However, you will need to make a few changes during this refactoring:</p>
<ul>
<li><p>The <code>findViewById()</code> method is a method of the <code>Activity</code> class, and thus can’t be called on an implicit <code>this</code> inside the Fragment. Instead, the method can be called on the <strong>root view</strong>, searching just that View and its children.</p></li>
<li><p>The Adapter’s constructor requires a <code>Context</code> as its first parameter; while an <code>Activity</code> is a <code>Context</code>, a <code>Fragment</code> is <em>not</em>—Fragments operate in the Context of their containing Activity! Fragments can refer to the Activity that they are inside (and the <code>Context</code> it represents) by using the <code>getActivity()</code> method (or just the <code>activity</code> property in Kotlin). Note that this method should be used <em>only</em> for getting a reference to a <code>Context</code>, not for arbitrary communication with the Activity (see below for details).</p>
<p>In Kotlin, because syntactically the <code>Activity</code> is allowed to be <code>null</code> (even though that would never happen), we either have to explicitly note that the Activity is not null with <code>!!activity</code>. Or more idiomatically, we can wrap the Activity-required functionality in a <code>.let()</code> lambda:</p>
<div class="sourceCode"><pre class="sourceCode kotlin"><code class="sourceCode kotlin"><span class="co">//kotlin</span>
<span class="co">//if Activity is not null, perform the following on `it`</span>
activity?.let {
<span class="co">//do stuff on Activity</span>
adapter = adapter = ArrayAdapter(it, R.layout.list_item, R.id.txt_item, ArrayList())
}</code></pre></div></li>
</ul></li>
<li><p>The <code>downloadMovieData()</code> helper method can be moved over, so that it belongs to the Fragment instead of the Activity. It will be the <em>Fragment’s</em> responsibility to handle data downloading.</p></li>
</ul>
<div id="activity-to-fragment-communication" class="section level3 unnumbered">
<h3>Activity-to-Fragment Communication</h3>
<p>This example has intentionally left the <em>input controls</em> (the search field and button) in the Activity, rather than making them part of the Fragment. Apart from being a useful demonstration, this allows the Fragment to have a single purpose (showing the list of movies) and would let us change the search UI independent of the displayed results. But since the the button is in the Activity while the downloading functionality is in the Fragment, we need a way for the Activity to “talk” to the Fragment. We thus need a <em>reference</em> to the contained Fragment—access to the XML similar to that provided by <code>findViewById</code>.</p>
<p>We can get a reference to a contained Fragment from an Activity by using a <a href="https://developer.android.com/reference/android/support/v4/app/FragmentManager.html"><code>FragmentManager</code></a>. This is an object responsible for (ahem) managing Fragments. It allows us to “look up” Fragments, as well as to manipulate which Fragments are shown. We access this FragmentManager by calling the <code>getSupportFragmentManager()</code> method (or using the <code>supportFragmentManager</code> property in Kotlin) of the Activity, and then can use <code>findFragmentById()</code> to look up an XML-defined Fragment by its <code>id</code>:</p>
<div class="sourceCode"><pre class="sourceCode java"><code class="sourceCode java"><span class="co">//java</span>
<span class="co">//MovieListFragment example</span>
MovieListFragment fragment = (MovieListFragment)<span class="fu">getSupportFragmentManager</span>().<span class="fu">findFragmentById</span>(R.<span class="fu">id</span>.<span class="fu">fragment</span>);</code></pre></div>
<div class="sourceCode"><pre class="sourceCode kotlin"><code class="sourceCode kotlin"><span class="co">//kotlin</span>
<span class="kw">val</span> <span class="va">fragment</span>: MovieListFragment = supportFragmentManager.findFragmentById(R.id.fragment) <span class="kw">as</span> MovieListFragment</code></pre></div>
<ul>
<li>Note that we’re using a method to explicit access the <strong>support</strong> <code>FragmentManager</code>. The Activity class (API level 15+) is able to work with both the platform and support <code>FragmentManager</code> classes. But because these classes don’t have a shared <code>interface</code>, the Activity needs to provide different Java/Kotlin methods which can return the correct type.</li>
</ul>
<p>Once you have a reference to the Fragment, this acts just like any other object—you can call any <code>public</code> methods it has! For example, if you give the Fragment a public method (e.g., <code>searchMovies()</code>), then this method can be called from the Activity:</p>
<div class="sourceCode"><pre class="sourceCode java"><code class="sourceCode java"><span class="co">//called from Activity on the referenced fragment</span>
fragment.<span class="fu">searchMovies</span>(searchTerm)</code></pre></div>
<p>(The parameter to this public method allows the Activity to provide information to the Fragment!)</p>
<p>At this point, the program should be able to be executed… and continue to function in exactly the same way! The program has just been refactored, so that all the movie downloading and listing work is <strong>encapsulated</strong> inside a Fragment that can be used in different Activities.</p>
<ul>
<li>In effect, we’ve created our own “widget” that can be included in any other screen, such as if we repeatedly wanted the list of movies to be available alongside some other user interface components.</li>
</ul>
</div>
</div>
<div id="dynamic-fragments" class="section level2">
<h2><span class="header-section-number">6.2</span> Dynamic Fragments</h2>
<p>The real benefit from encapsulating behavior in a Fragment is to be able to support multiple Fragments within a single Activity. For example, in the the archetypal <a href="https://developer.android.com/training/implementing-navigation/descendant.html#master-detail">“master/detail”</a> navigation flow, one screen (Fragment) holds the “master list” and another screen (Fragment) holds details about a particular item. This is a very common navigation pattern for Android apps, and can be seen in most email or news apps.</p>
<ul>
<li>On large screens, Fragments allow these two Views to be placed side by side!</li>
</ul>
<p>In this section, we will continue to refine the Movie app so that when the user clicks on a Movie in the list, the app shows a screen (Fragment) with details about the selected movie.</p>
<div id="instantiating-fragments" class="section level3 unnumbered">
<h3>Instantiating Fragments</h3>
<p>To do this, we will need to instantiate the desired Fragment <strong>dynamically</strong> (in Java code), rather than statically in the XML using the <code><fragment></code> element. This is because we need to be able to dynamically change <em>which</em> Fragment is currently being shown, which is not possibly for Fragments that are “hard-coded” in the XML.</p>
<p>Unlike Activities, Fragments (such as <code>MovieListFragment</code>) <strong>do</strong> have constructor methods that can be called. In fact, Android <em>requires</em> that every Fragment have a default (no-argument) primary constructor that is called when Fragments are created by the system! While we have access to the constructor, it is considered best practice to <strong>not</strong> call this constructor directly from the Activity when you want to instantiate a Fragment, and to in fact leave the method empty. This is because we do not have full control over when the constructor is executed: the Android system may call the no-argument constructor whenever it needs to recreate the Activity (or just the Fragment), which can happen at arbitrary times. Since only this default constructor is called, we can’t add an additional constructor with any arguments we may want the Fragment to have (e.g., the <code>searchTerm</code>)… and thus it’s best to not use it at all.</p>
<p>Instead, we specify a <strong>simple factory</strong> method (by convention called <code>newInstance()</code>) which is able to “create” an instance of the Fragment for us. This factory method can take as many arguments as we want, and then does the work of passing these arguments into the Fragment instantiated with the default constructor. Note that this factory needs to be a <code>static</code> method (it is called on the class, not the object), and so is defined in a <code>companion object</code> in Kotlin.</p>
<div class="sourceCode"><pre class="sourceCode java"><code class="sourceCode java"><span class="co">//java</span>
<span class="kw">public</span> <span class="dt">static</span> MyFragment <span class="fu">newInstance</span>(<span class="bu">String</span> argument) {
MyFragment fragment = <span class="kw">new</span> <span class="fu">MyFragment</span>(); <span class="co">//instantiate the Fragment</span>
Bundle args = <span class="kw">new</span> <span class="fu">Bundle</span>(); <span class="co">//an (empty) Bundle for the arguments</span>
args.<span class="fu">putString</span>(ARG_PARAM_KEY, argument); <span class="co">//add the argument to the Bundle</span>
fragment.<span class="fu">setArguments</span>(args); <span class="co">//add the Bundle to the Fragment</span>
<span class="kw">return</span> fragment; <span class="co">//return the Fragment</span>
}</code></pre></div>
<div class="sourceCode"><pre class="sourceCode kotlin"><code class="sourceCode kotlin"><span class="co">//kotlin</span>
<span class="kw">companion</span> <span class="kw">object</span> {
<span class="kw">private</span> <span class="kw">val</span> <span class="va">ARG_PARAM_KEY</span> = <span class="st">"my key"</span>
<span class="kw">fun</span> <span class="fu">newInstance</span>(<span class="va">argument</span>: <span class="dt">String</span>): <span class="dt">MyFragment</span> {
<span class="kw">val</span> <span class="va">args</span> = Bundle().apply {
putString(ARG_PARAM_KEY, argument)
}
<span class="kw">val</span> <span class="va">fragment</span> = MyFragment().apply {
setArguments(args)
}
<span class="kw">return</span> fragment
}
}</code></pre></div>
<p>In order to pass the arguments into the new Fragment, we wrap them up in a <a href="https://developer.android.com/reference/android/os/Bundle.html"><code>Bundle</code></a> (an object containing basic <em>key-value pairs</em>). Values can be added to a <code>Bundle</code> using an appropriate <code>putType()</code> method; note that these do need to be primitive types (<code>int</code>, <code>String</code>, etc.). The <code>Bundle</code> of arguments can then be assignment to the Fragment by calling the <a href="http://developer.android.com/reference/android/app/Fragment.html#setArguments(android.os.Bundle)"><code>setArguments()</code></a> method.</p>
<ul>
<li><p>In Kotlin, it’s idiomatic to do this work using the <code>apply()</code> method described in the previous chapter. This lets you easily put lots of values in the Bundle without needing to write the word <code>args</code> over and over again.</p></li>
<li><p>We will be able to access this <code>Bundle</code> from inside the Fragment (e.g., in the <code>onCreateView()</code> callback) by using the <code>getArguments()</code> method, and the <code>getTYPE()</code> methods to retrieve the values from it; in Kotlin you can access these as properties. This allows us to dynamically adjust the content of the Fragment’s Views! For example, we can run the <code>downloadMovieData()</code> function using this argument, fetching movie results as soon as the Fragment is created (e.g., on a button press)… allowing the <code>downloadMovieData()</code> function to again be made private, for example.</p></li>
<li><p>Since the <code>Bundle</code> is a set of <em>key-value</em> pairs, each value needs to have a particular key. These keys are usually defined as <code>private</code> constants (e.g., <code>ARG_PARAM_KEY</code> in the above example) to make storage and retrieval easier. Remember: hese Bundles are internal to the Fragment!</p></li>
</ul>
<p>We will then be able to instantiate the Fragment (e.g., in the Activity class), passing it any arguments we wish:</p>
<div class="sourceCode"><pre class="sourceCode java"><code class="sourceCode java"><span class="co">//java</span>
MyFragment fragment = MyFragment.<span class="fu">newInstance</span>(<span class="st">"My Argument"</span>);</code></pre></div>
<div class="sourceCode"><pre class="sourceCode kotlin"><code class="sourceCode kotlin"><span class="co">//kotlin</span>
<span class="kw">val</span> <span class="va">fragment</span> = MyFragment.newInstance(<span class="st">"My Argument"</span>)</code></pre></div>
</div>
<div id="transactions" class="section level3 unnumbered">
<h3>Transactions</h3>
<p>Once we’ve instantiated a Fragment in the Java, we need to attach it to the view hierarchy: since we’re no longer using the XML <code><fragment></code> element, we need some other way to load the Fragment into the <code><FrameLayout></code> container.</p>
<p>We do this loading using a <a href="https://developer.android.com/guide/components/fragments.html#Transactions"><strong><code>FragmentTransaction</code></strong></a><a href="#fn19" class="footnoteRef" id="fnref19"><sup>19</sup></a>. A transaction represents a <em>change</em> in the Fragment that is being displayed. You can think of this like a bank (or database) transaction: they allow you to add or remove Fragments like we would add or remove money from a bank account. We instantiate new transactions representing the change we wish to make, and then “run” that transaction in order to apply the change.</p>
<p>To create a transaction, we utilize the <code>FragmentManager</code> again; the <code>FragmentManager#beginTransaction()</code> method is used to instantiate a <strong>new</strong> <a href="https://developer.android.com/reference/android/support/v4/app/FragmentTransaction.html"><code>FragmentTransaction</code></a>.</p>
<p>Transactions represent a set of Fragment changes that are all “applied” at the same time (similar to depositing and withdrawing money from multiple bank accounts all at once). We specify these transactions using by calling the <code>add()</code>, <code>remove()</code>, or <code>replace()</code> methods on the <code>FragmentTransaction</code>.</p>
<ul>
<li><p>The <code>add()</code> method lets you specify which View <strong>container</strong> you want to add a particular Fragment to. The <code>remove()</code> method lets you remove a Fragment you have a reference to. The <code>replace()</code> method removes any Fragments in the container and then adds the specified Fragment instead.</p></li>
<li><p>Each of these methods returns the modified <code>FragmentTransaction</code>, so they can be “chained” together. In Kotlin, you can also use the <code>run()</code> method to perform this a block—similar to <code>apply()</code>, but it doesn’t return the object in the end.</p></li>
</ul>
<p>Finally, we call the <code>commit()</code> method on the transaction in order to “submit” it and have all of the changes go into effect.</p>
<p>We can do this work in the Activity’s search click handler to add a Fragment, rather than specifying the Fragment in the XML:</p>
<div class="sourceCode"><pre class="sourceCode java"><code class="sourceCode java"><span class="co">//java</span>
FragmentTransaction transaction = <span class="fu">getSupportFragmentManager</span>().<span class="fu">beginTransaction</span>();
<span class="co">//params: container to add to, Fragment to add, (optional) tag</span>
transaction.<span class="fu">add</span>(R.<span class="fu">id</span>.<span class="fu">container</span>, myFragment, MOVIE_LIST_FRAGMENT_TAG);
transaction.<span class="fu">commit</span>();</code></pre></div>
<div class="sourceCode"><pre class="sourceCode kotlin"><code class="sourceCode kotlin"><span class="co">//kotlin</span>
supportFragmentManager.beginTransaction().run {
add(R.id.container, myFragment, MOVIE_LIST_FRAGMENT_TAG)
commit()
}</code></pre></div>
<ul>
<li>The third argument for the <code>add()</code> method is a “tag” we apply to the Fragment being added. This gives it a “name” that we can use to find a reference to this Fragment later if we want (via <code>FragmentManager#findFragmentByTag(tag)</code>). Alternatively, we can save a reference to the Fragment as an instance variable; this is faster but more memory intensive (and can cause possible leaks, since the reference keeps the Fragment from being reclaimed by the system).</li>
</ul>
</div>
<div id="inter-fragment-communication" class="section level3 unnumbered">
<h3>Inter-Fragment Communication</h3>
<p>We can use this transaction-based structure to instantiate and load a <strong>second Fragment</strong> (e.g., a “detail” view for a selected Movie). We can add functionality (e.g., in the <code>onClick()</code> handler) so that when the user clicks on a movie in the list, we <strong><code>replace()</code></strong> the currently displayed Fragment with this new details Fragment.</p>
<p>However, remember that Fragments are supposed to be <strong>modular</strong>—each Fragment should be <em>self-contained</em>, and not know about any other Fragments that may exist (after all, what if we wanted the master/detail views to be side-by-side on a large screen, instead of the list replacing itself?)</p>
<p class="alert alert-warning">
Using <code>getActivity()</code> to reference the Activity and <code>getSupportFragmentManager()</code> to access the manager is a violation of the <a href="http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/paper-boy/demeter.pdf">Law of Demeter</a>—don’t do it!
</p>
<p>Instead, we have Fragments communicate by passing messages through their contained Activity: the <code>MovieFragment</code> should tell its Activity that a particular movie has been selected, and then that Activity can determine what to do about it (e.g., creating a <code>DetailFragment</code> to display that information).</p>
<p>The recommended way to provide <a href="https://developer.android.com/training/basics/fragments/communicating.html">Fragment-to-Activity communication</a> is to define an <strong>interface</strong>. The Fragment class should specify an <code>interface</code> (for one or more public methods) that its containing Activity <em>must</em> support—and since the Fragment can only exist within an Activity that implements that interface, it knows the Activity has the specified public methods that it can call to pass information to that Activity.</p>
<p>As an example of this process:</p>
<ul>
<li><p>Create a new <code>interface</code> inside the Fragment (e.g., <code>OnMovieSelectedListener</code>). This interface needs a public method (e.g., <code>onMovieSelected(Movie movie)</code>) that the Fragment can call to give instructions or messages to the Activity.</p></li>
<li><p>In the Fragment’s <code>onAttach()</code> callback (called when the Fragment is first associated with an Activity), we can check that the Activity actually implements the interface by trying to <em>cast</em> it to that interface. We can also save a reference to this Activity for later, to save some time:</p>
<div class="sourceCode"><pre class="sourceCode java"><code class="sourceCode java"><span class="co">//java</span>
<span class="kw">public</span> <span class="dt">void</span> <span class="fu">onAttach</span>(<span class="bu">Context</span> context) {
<span class="kw">super</span>.<span class="fu">onAttach</span>(context);
<span class="kw">try</span> {
callback = (OnMovieSelectedListener)context; <span class="co">//attempt to cast</span>
} <span class="kw">catch</span> (<span class="bu">ClassCastException</span> e) {
<span class="kw">throw</span> <span class="kw">new</span> <span class="bu">ClassCastException</span>(context.<span class="fu">toString</span>() + <span class="st">" must implement OnMovieSelectedListener"</span>);
}
}</code></pre></div>
<div class="sourceCode"><pre class="sourceCode kotlin"><code class="sourceCode kotlin"><span class="co">//kotlin</span>
<span class="kw">override</span> <span class="kw">fun</span> <span class="fu">onAttach</span>(<span class="va">context</span>: <span class="dt">Context?</span>) {
<span class="kw">super</span>.onAttach(context)
callback = context <span class="kw">as</span>? OnMovieSelectedListener
<span class="cf">if</span>(callback == <span class="kw">null</span>){
<span class="kw">throw</span> ClassCastException(<span class="st">"$context must implement OnMovieSelectedListener"</span>)
}
} </code></pre></div></li>
<li><p>Then when an action occurs in the Fragment (e.g., a movie is selected), you call the interface’s method on the <code>callback</code> reference.</p></li>
<li><p>Finally, you will need to make sure that the Activity <code>implements</code> this callback. Remember that a class can implement multiple interfaces!</p>
<p>In the Activity’s implementation of the interface, you can handle the information provided. For example, use the <code>FragmentManager</code> to create a <code>replace()</code> transaction to load a new <code>DetailFragment</code> for the appropriate data.</p></li>
</ul>
<p>In the end, this will allow you to have one Fragment cause the application to switch to another!</p>
<p class="alert alert-info">
This is not the only way for Fragments to communicate. It is also possible to have a Fragment send an <code>Intent</code> to the Activity, who then responds to that as appropriate. But using the Intent system is more resource-intensive than using interfaces.
</p>
<div id="parcelable" class="section level4 unnumbered">
<h4>Parcelable</h4>
<p>It’s not uncommon to want to pass multiple or complex data values as arguments to a new Fragment, such as a <code>Movie</code> object. However, the <code>arguments</code> for a new Fragment must be passed in through a <code>Bundle</code>, which are only able to store primitive values (e.g., <code>int</code>, <code>float</code>, <code>String</code>)… and a special data type called <a href="https://developer.android.com/reference/android/os/Parcelable.html"><strong>Parcelable</strong></a>. An object that implements the <code>Parcelable</code> interface includes methods that allow it to be <em>serialized</em> into a value that is simple enough to place in a Bundle—in effect, it’s values are converted into a formatted String (similar in concept to <code>JSON.stringify()</code> in JavaScript).</p>
<p>Implementing the <code>Parcelable</code> interface involves the following steps: 1. provide a <code>writeToParcel()</code> method that adds the object’s fields to a given <code>Parcel</code> object 2. provide a constructor that can re-create the object from a <code>Parcel</code> by reading the values from it (<em>in the EXACT SAME order they were added</em>!) 3. provide a <code>describeContents()</code> that returns whether the parcel includes a file descriptor (usually <code>0</code>, meaning not) 4. provide a <code>Parcelable.Creator</code> <em>constant</em> that can be used to create the Parcelable.</p>
<p>These steps seem complex but are fairly rote: as such, it’s possible to “automate” making a class into a Parcelable. My favorite strategy for Java is to use <strong><a href="http://www.parcelabler.com/" class="uri">http://www.parcelabler.com/</a></strong>, a website that allows you to copy and paste a class and provides you a version of that class with the Parcelable interface implemented!</p>
<p>In Kotlin it’s even easier: if you include the <a href="https://kotlinlang.org/docs/tutorials/android-plugin.html">Kotlin Android Extensions</a>, you can activate <a href="https://kotlinlang.org/docs/tutorials/android-plugin.html#experimental-mode">experimental mode</a> by adding a declaration to your app’s <code>build.gradle</code> file. Once that has been included, you can simply annotate the class with the <code>@Parcelize</code> annotation, and the clas will automatically be provided with the methods to implement the Parcelable interface.</p>
<p class="alert alert-danger">
Bundles are only supposed to store small amounts of information (a few variables); and by extension Parcelable objects should also only include a few attributes. <strong>Never</strong> make an object that contains an array or a list into a Parcelable! Complex or variable-length data should instead be persisted separate from the Activity (e.g., in a database), with identifiers passed in Bundles instead.
</p>
</div>
</div>
<div id="the-back-stack" class="section level3 unnumbered">
<h3>The Back Stack</h3>
<p>But what happens when we hit the “back” button? The Activity exits! <em>Why?</em> Because “back” normally says to “leave the Activity”—we only had one Activity, even though there were multiple fragments.</p>
<p>Recall that the Android system may have lots of Activities (even across multiple apps!) with the user moving back and forth between them. As described in <a href="activities.html#back-tasks">Lecture 3</a>, each new Activity is associated with a “task” and placed on a <strong>stack</strong><a href="#fn20" class="footnoteRef" id="fnref20"><sup>20</sup></a>. When the “back” button is pressed, that Activity is popped off the stack, and the user is taken to the Activity that is now at the top.</p>
<p>Fragments by default are not part of this “back-stack”, since they are just components of Activities. However, you <em>can</em> <a href="(https://developer.android.com/training/implementing-navigation/temporal.html#back-fragments)">specify</a> that a transaction should include the Fragment change as part of the stack navigation by calling <code>FragmentTransaction#addToBackStack()</code> as part of your transaction (e.g., right before you <code>commit()</code>):</p>
<div class="sourceCode"><pre class="sourceCode java"><code class="sourceCode java"><span class="co">//java</span>
<span class="fu">getSupportFragmentManager</span>().<span class="fu">beginTransaction</span>()
.<span class="fu">add</span>(detailFragment, <span class="st">"detail"</span>)
<span class="co">// Add this transaction to the back stack</span>
.<span class="fu">addToBackStack</span>(<span class="kw">null</span>)
.<span class="fu">commit</span>();</code></pre></div>
<p>Note that the “back” button will cause <em>the entire transaction</em> to “reverse”. Thus if you performed a <code>remove()</code> then an <code>add()</code> (e.g., via a <code>replace()</code>), then hitting “back” will cause the the previously added Fragment to be removed <em>and</em> the previously removed Fragment to be added.</p>
<ul>
<li><code>FragmentManager</code> also includes numerous methods for manually manipulating the back-stack (e.g., “popping” off transactions) if you want to include custom navigation elements such as extra “back” buttons.</li>
</ul>
</div>
</div>
</div>
<div class="footnotes">
<hr />
<ol start="17">
<li id="fn17"><p><a href="https://developer.android.com/images/fundamentals/fragments.png" class="uri">https://developer.android.com/images/fundamentals/fragments.png</a><a href="fragments.html#fnref17">↩</a></p></li>
<li id="fn18"><p><a href="https://developer.android.com/images/fragment_lifecycle.png" class="uri">https://developer.android.com/images/fragment_lifecycle.png</a><a href="fragments.html#fnref18">↩</a></p></li>
<li id="fn19"><p><a href="https://developer.android.com/reference/android/support/v4/app/FragmentTransaction.html" class="uri">https://developer.android.com/reference/android/support/v4/app/FragmentTransaction.html</a><a href="fragments.html#fnref19">↩</a></p></li>
<li id="fn20"><p><a href="http://developer.android.com/images/fundamentals/diagram_backstack.png" class="uri">http://developer.android.com/images/fundamentals/diagram_backstack.png</a><a href="fragments.html#fnref20">↩</a></p></li>
</ol>
</div>
</section>
</div>
</div>
</div>
<a href="material-design.html" class="navigation navigation-prev " aria-label="Previous page"><i class="fa fa-angle-left"></i></a>
<a href="intents.html" class="navigation navigation-next " aria-label="Next page"><i class="fa fa-angle-right"></i></a>
</div>
</div>
<script src="libs/gitbook-2.6.7/js/app.min.js"></script>
<script src="libs/gitbook-2.6.7/js/lunr.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-search.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-sharing.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-fontsettings.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-bookdown.js"></script>
<script src="libs/gitbook-2.6.7/js/jquery.highlight.js"></script>
<script>
gitbook.require(["gitbook"], function(gitbook) {
gitbook.start({
"sharing": {
"github": true,
"facebook": false,
"twitter": false,
"google": false,
"weibo": false,
"instapper": false,
"vk": false,
"all": ["github", "facebook", "twitter", "google"]
},
"fontsettings": {
"theme": "white",
"family": "sans",
"size": 2
},
"edit": {
"link": "https://github.com/info448/book/edit/master/fragments.Rmd",
"text": "Edit"
},
"download": ["android-development.pdf", "android-development.epub"],
"toc": {
"collapse": "section",
"scroll_highlight": true
}
});
});
</script>
<!-- dynamically load mathjax for compatibility with self-contained -->
<script>
(function () {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "https://cdn.bootcss.com/mathjax/2.7.1/MathJax.js?config=TeX-MML-AM_CHTML";
if (location.protocol !== "file:" && /^https?:/.test(script.src))
script.src = script.src.replace(/^https?:/, '');
document.getElementsByTagName("head")[0].appendChild(script);
})();
</script>
</body>
</html>