-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathmaterial-design.html
More file actions
795 lines (749 loc) · 86 KB
/
material-design.html
File metadata and controls
795 lines (749 loc) · 86 KB
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
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
<!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="data-views.html">
<link rel="next" href="fragments.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="material-design" class="section level1">
<h1><span class="header-section-number">Lecture 5</span> Material Design</h1>
<p>This lecture discusses <a href="https://material.io/guidelines/material-design/introduction.html">Material design</a>: the <em>design language</em> created by Google to support mobile user interfaces. The design language focuses on mobile designs (e.g., for Android), but can also be used across platforms (e.g., on the web through <a href="https://material.io/components/web/">css frameworks</a>).</p>
<p class="alert alert-info">
This lecture references code found at <a href="https://github.com/info448/lecture05-material" class="uri">https://github.com/info448/lecture05-material</a>.
</p>
<p class="alert alert-warning">
Material Design support was introduced in API 21 Lollipop, and so a device running that version of Android or later is required to access all the Material features supported by Android. However, most functionality is also available via <a href="https://developer.android.com/training/material/compatibility.html">compatibility libraries</a> (i.e., <code>AppCompat</code>), and so can be utilized on older devices as well.
</p>
<p class="alert alert-warning">
Google is in the process of updating their Material Design implementation to use <a href="https://material.io/develop/android/">Material Design Components (MDC)</a>. As that version is still in beta and only available on Android Pie, this lecture describes how to use the “legacy” version of the Material support library.
</p>
<div id="the-material-design-language" class="section level2">
<h2><span class="header-section-number">5.1</span> The Material Design Language</h2>
<p><strong>Material design</strong> is a <em>design language</em>: a “vocabulary” of visual and interactive patterns that are shared across systems. Material forms both a “look and feel” for Google applications and modern (API 21+) Android apps in general, as well as providing a</p>
<div class="figure">
<iframe width="560" height="315" src="https://www.youtube.com/embed/YaG_ljfzeUw?rel=0" frameborder="0" allowfullscreen>
</iframe>
<p class="caption">
A video explanation of the Material language (via <a href="https://developer.android.com/design/material/index.html" class="uri">https://developer.android.com/design/material/index.html</a>)
</p>
</div>
<p>In summary, the Material Design language is based around <a href="https://material.io/guidelines/material-design/introduction.html#introduction-principles">three main principles</a>:</p>
<ul>
<li><p><strong><em>Material is the metaphor</em></strong>. The Material design language is built around presenting user interfaces as being made of virtual <a href="https://material.io/guidelines/material-design/material-properties.html"><strong>materials</strong></a>, which ara <a href="https://material.io/guidelines/layout/principles.html#principles-how-paper-works">paper-like</a> surfaces floating in space. Each surface has a uniform thickness (<code>1dp</code>), but different <em>elevation</em> (conveyed primarily through shadows and <em>perspective</em>). This physical metaphor helps to indicate different affordances and user interactions: for example, a button is “raised” and can be “pushed down”.</p></li>
<li><p><strong><em>Motion provides meaning</em></strong>. Material also places great emphasis on the use of <a href="https://material.io/guidelines/motion/material-motion.html"><strong>motion</strong></a> of these materials in order to help describe the relationships between components as well as make design overall more “delightful”. Material applications include lots of animations and flourishes, making the app’s usage continuous and connected. Surfaces are able to change shape, size, and position (as long as they stay in their plane—they cannot fold, but they can split and rejoin) in response to user input.</p></li>
<li><p><strong><em>Bold, graphic, intentional</em></strong>. Material applications follow a particular aesthetic in terms of things such as <a href="https://material.io/guidelines/style/color.html">color</a> (not muted), <a href="https://material.io/guidelines/style/imagery.html">imagery</a> (usually lots of it). Material applications <em>look</em> like material applications, though they can still be customized to meet your particular needs.</p></li>
</ul>
<p>For more information on the Material design language, see the <a href="https://material.io/guidelines/"><strong>official guidelines</strong></a> (click the hamburger button on the left to navigate). This documentation contains extensive examples and instructions, ranging from suggested font sizes to widget usage advice.</p>
<p class="alert">
This lecture focuses on ways to implement specific aspects of the Material Design language in Android applications, rather than on specifics of how to obey the language guidelines.
</p>
</div>
<div id="material-styles-icons" class="section level2">
<h2><span class="header-section-number">5.2</span> Material Styles & Icons</h2>
<p>The first and easiest step towards making a Material-based application is to utilize the provided <a href="https://developer.android.com/training/material/theme.html">Material Themes</a> in order to “skin” your application. These themes are available on API 21 Lollipop and later; for earlier operating system, you can instead use equivalent themes in <code>AppCompat</code> (which are in fact the default themes for new Android apps!)</p>
<p>Applying themes (including Material themes) are discussed in more detail in the <a href="styles-themes.html#styles-themes">Styles & Themes</a> lab.</p>
<ul>
<li>You can see what specific properties are applied by these styles and themes by browsing the <a href="https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/res/res/values">source code</a> for the Android framework—check out the <code>styles_material.xml</code> and <code>themes_material.xml</code> (these will also reference values defined in the variable <code>color</code> and <code>dimens</code> resources). The <code>AppCompat</code> styles and themes can be <a href="https://android.googlesource.com/platform/frameworks/support.git/+/refs/heads/master/v7/appcompat/res/values/">source code</a> for the <code>v7</code> support library.</li>
</ul>
<!-- App bar stuff here? Also check old book (s17)-->
<!-- Don't do this in lecture... -->
<p>Let’s start by pointing to one of the most prominent visual components in the default app: the <a href="https://developer.android.com/training/appbar/index.html"><strong><em>App Bar</em></strong></a> or <strong><em>Action Bar</em></strong>. This acts as the sort of “header” for your app, providing a dedicated space for navigation and interaction (e.g., through menus). The <a href="https://developer.android.com/reference/android/support/v7/app/ActionBar.html"><code>ActionBar</code></a><a href="#fn14" class="footnoteRef" id="fnref14"><sup>14</sup></a> is a specific type of <a href="https://developer.android.com/reference/android/support/v7/widget/Toolbar.html"><code>Toolbar</code></a> that is most frequently used as the App Bar, offering a particular “look and feel” common to Android applications.</p>
<p>While the <code>AppCompatActivity</code> used throughout this course automatically provides an Action Bar for the app, it is also possible to add it directly (such as if you are using a different Activity subclass). To add your own Action Bar, you specify a <strong>theme</strong> that does <em>not</em> include an <code>ActionBar</code>, and then include an <code><android.support.v7.window.Toolbar></code> element inside your layout wherever you want the toolbar to go. See <a href="http://developer.android.com/training/appbar/setting-up.html">Setting up the App Bar</a> for details. This will also allow you to put the Toolbar anywhere in the application’s layout (e.g., if you want it to be stuck to the bottom).</p>
<p>In practice, the biggest part of utilizing a Material Theme is defining the <a href="https://developer.android.com/training/material/theme.html#ColorPalette">color palette</a> for your app. The Material design specification describes a broad color palette (with available <a href="https://material.io/guidelines/style/color.html#color-color-palette">swatches</a>); however, it is often more useful to pick your colors using the provided <a href="https://material.io/color/#!/"><strong>color picker tool</strong></a><a href="#fn15" class="footnoteRef" id="fnref15"><sup>15</sup></a>, which allows you to easily experiment with different color combinations.</p>
<ul>
<li>Pick your <em>primary</em> and <em>secondary</em> color, and then assign the resource values <code>colorPrimary</code>, <code>colorPrimaryDark</code>, and <code>colorAccent</code> in <code>res/values/colors.xml</code>. This will let you easily “brand” your application.</li>
</ul>
<p>Material-specific attributes such as <code>android:elevation</code> are also available in API 21+, though making shadows visible on arbitrary elements requires some additional work.</p>
<p>In addition to styles, Material also includes a large set of <a href="https://material.io/icons/"><strong>icons</strong></a> for use in applications. These icons supplement the built in <code>ic_*</code> <a href="http://androiddrawables.com/">drawables</a> that are built into the platform and are available for use (and show up as auto-complete options in the IDE).</p>
<p>Instead these icons are available as <a href="https://developer.android.com/training/material/drawables.html#VectorDrawables">vector drawables</a>—rather than being a <code>.png</code> file, images are defined as using an XML schema similar to that used in <a href="https://en.wikipedia.org/wiki/Scalable_Vector_Graphics">Scalable Vector Graphics (SVG)</a>.</p>
<p class="alert alert-info">
SVG is used to represent <a href="https://en.wikipedia.org/wiki/Vector_graphics">vector graphics</a>—that is, pictures defined in terms of the connection between points (lines and other shapes), rather than in terms of the pixels being displayed (called a <a href="https://en.wikipedia.org/wiki/Raster_graphics">raster image</a>). In order to be shown on a screen, these lines are converted (rastered) into grids of pixels based on the size and resolution of the display. This allows SVG images to “scale” or “zoom” independent of the size of the display or the image—you never need to worry about things getting blurry as you make them larger!
</p>
<p>In order to include a Material icon, you will need to generate the XML code for that particular image. Luckily, Android Studio includes XML definitions for all the Material icons (though you can also define your own vector drawables).</p>
<ul>
<li><p>To create a vector drawable, select <code>File > New > Vector Asset</code> from the Android Studio menu. You can then click on the icon to browse for which Material icon you want to create.</p></li>
<li><p>By default the icon will be colored <em>black</em>. If you wish to change the color of the icon when included in your layout, specify the color through the <a href="https://developer.android.com/training/material/drawables.html#DrawableTint"><code>android:tint</code></a> attribute of the View in your XML (e.g., on the <code>ImageButton</code>).</p></li>
</ul>
<p>It is also possible to define arbitrary vector shapes in API 21+. For example, the starter code includes a resource for a <code><shape></code> element that is shaped like an oval.</p>
</div>
<div id="design-support-libraries" class="section level2">
<h2><span class="header-section-number">5.3</span> Design Support Libraries</h2>
<p>In addition to the styling and resource properties available as part of the Android framework, there are also additional components available through extra <a href="https://developer.android.com/training/material/design-library.html"><strong>support libraries</strong></a>.</p>
<p>Similar to Volley, these libraries are not built into Android and so need to be explicitly listed under <code>dependencies</code> in your app’s <code>build.gradle</code> file. For example:</p>
<pre class="gradle"><code>//note the version number needs to match your SDK version
implementation 'com.android.support:design:28.0.0'</code></pre>
<p>will include the latest version (as of this writing) of the <strong>design support library</strong>, which includes elements such as the Floating Action Button and Coordinator Layouts (described below).</p>
<div class="alert alert-warning">
<p>
<p>Note that if you have issues installing the dependency, the <a href="https://developer.android.com/topic/libraries/support-library/setup.html">setup for including support libraries</a> was changed in July 2017 to support downloading dependency libraries through <a href="https://maven.apache.org/">maven</a> rather than directly from Android Studio. To support this, you will need to change the <em>project’s</em> <code>build.gradle</code> repository declaration to look like:</p>
<pre class="gradle"><code>allprojects {
repositories {
jcenter()
maven {
url "https://maven.google.com"
}
}
}</code></pre>
</div>
<!-- 40min? -->
<div id="widgets" class="section level3 unnumbered">
<h3>Widgets</h3>
<p>The support libraries support a number of useful widgets (specialized Views) for creating Material-styled apps.</p>
<div id="recyclerview" class="section level4 unnumbered">
<h4>RecyclerView</h4>
<p>The <a href="https://developer.android.com/training/material/lists-cards.html#RecyclerView"><code>RecyclerView</code></a> is a more advanced version of a <code>ListView</code>, providing a more robust system for support interactive Views within the list as well as providing animations for things like adding and removing list items.</p>
<p>This class is part of the <code>v7</code> support library (and not the Material Design library specifically), and so you will need to include it specifically in your <em>app’s</em> <code>build.gradle</code> file (the same way you included Volley):</p>
<pre class="gradle"><code>implementation 'com.android.support:cardview-v7:28.0.0'</code></pre>
<p>Implementing a <code>RecyclerView</code> is very similar to implementing a <code>ListView</code> (with the addition of the <a href="https://developer.android.com/training/improving-layouts/smooth-scrolling.html#ViewHolder">ViewHolder pattern</a>), though you also need to declare a <code>LayoutManager</code> to specific if your RecyclerView should use a List or a Grid.</p>
<p>The best way to understand the RecyclerView is to look at the example and modify that to fit your particular item view. For example, you can change a ListView into a RecyclerView by adapting the sample code provided by Google’s <a href="https://developer.android.com/guide/topics/ui/layout/recyclerview">official documentation</a><a href="#fn16" class="footnoteRef" id="fnref16"><sup>16</sup></a>:</p>
<ul>
<li><p>First, you will need to replace the XML View declaration with a <code><android.support.v7.widget.RecyclerView></code> element. In effect, we’re just modifying the <strong>controller</strong> for the list.</p></li>
<li><p>There are a few extra steps when setting up the <code>RecyclerView</code> in the Java code. In particular, you will also need to associate a <code>LayoutManager</code> object to with the View—for example, a <code>LinearLayoutManager</code> to show items in a line (a la a ListView), or a <code>GridLayoutManager</code> to show items in a grid (a la a GridView).</p>
<ul>
<li><p>In Kotlin, these can be assigned using the <code>.apply()</code> method. This method takes a callback function, and executes each line in that callback function with the object (e.g., the <code>recyclerView</code>) scoped as <code>this</code>. This is a shortcut for calling lots of methods on the same object in a row.</p>
<p>Similar shortcuts are provided by the <code>run()</code>, <code>with()</code> and <code>let()</code> functions. See <a href="https://medium.com/@elye.project/mastering-kotlin-standard-functions-run-with-let-also-and-apply-9cd334b0ef84">this guide</a> for a clear explanation.</p></li>
</ul></li>
<li><p>All <code>RecyclerViews</code> require <em>custom adapters</em>: we cannot just use a built-in adapter such as <code>ArrayAdapter</code>. To do this, create a class that <code>extends RecyclerView.Adapter<VH></code>.</p>
<ul>
<li><p>The generic in this class is a class representing a <a href="https://developer.android.com/training/improving-layouts/smooth-scrolling.html#ViewHolder">View Holder</a>. This is a pattern by which each individual View that will be inflated and referenced is stored as an individual <em>object</em> with the particular Views to be modified (e.g., <code>TextView</code>) saved as instance variables. This avoids the need for the adapter to repeatedly use <code>findViewById()</code>, which is an expensive operation (since it involves crawling the View hierarchy tree!)</p>
<p>The <code>ViewHolder</code> will be <em>another</em> class—usually an inner class of the adapter. We can treat it as a <code>data</code> class (a simple “container” object, similar to a <code>struct</code> in C). but don’t need to declare it as such directly. If needed, you can assign these instance variables the results of the <code>findViewById()</code> calls when the ViewHolder object is initialized.</p></li>
<li><p>The <code>RecyclerView</code> (not the <code>ViewHolder</code>) requires you to override the <code>onCreateViewHolder()</code> method, which will <code>inflate()</code> the View and instantiate a <code>ViewHolder</code> for each item when that item needs to be displayed for the first time.</p></li>
<li><p>In the overridden <code>onBindViewHolder()</code> you can do the actual work of assigning model content to the particular View (e.g., called <code>setText()</code>). You don’t need to use <code>findViewById()</code> here, because you’ve already saved a reference to that View in the <code>ViewHolder</code>, so you can assign to it directly!</p></li>
<li><p>The <code>getItemCount()</code> is used internally for the RecyclerView to determine when you’ve gotten to the “end” of the list.</p></li>
</ul></li>
<li><p>Finally, you can assign the custom adapter to the <code>RecyclerView</code> in order to associate the model and the View.</p></li>
</ul>
<p>And that’s about it! While it is more code and more complex than a basic ListView, as soon as you’ve added in the ViewHolder pattern or done any other kinds of customizations, you’re basically at the same level. Using a RecyclerView instead of a ListView also enables built-in animations, as well as common user actions such as “drag-to-order” or “swipe-to-dismiss”. See <a href="https://medium.com/@ipaulpro/drag-and-swipe-with-recyclerview-b9456d2b1aaf">this guide</a> for a walkthrough on adding these capabilities.</p>
<p>Note that <em>unlike</em> with a ListView, we usually modify the items shown in a <code>RecyclerView</code> by modifying the data model (e.g., the array or ArrayList) directly. But we will need to <a href="https://guides.codepath.com/android/using-the-recyclerview#notifying-the-adapter">notify</a> the <code>RecyclerView</code>’s adapter of these changes by calling one of the various <code>.notify()</code> methods on the adapter (e.g., <code>adapter.notifyItemInserted(position)</code>). This will cause the adapter to “refresh” the display, and it will actually animate the changes to the list by default!</p>
</div>
<div id="cards" class="section level4 unnumbered">
<h4>Cards</h4>
<p>The <code>v7</code> support library also provides a View for easily styling content as <a href="https://developer.android.com/training/material/lists-cards.html#CardView"><strong>Cards</strong></a>. A <code>CardView</code> is basically a <code>FrameLayout</code> (a ViewGroup that contains one child View), but include borders and shadows that make the group look like a card.</p>
<ul>
<li>You will need to load the <code>CardView</code> class as a gradle dependency using <code>compile 'com.android.support:cardview-v7:26.1.0'</code>.</li>
</ul>
<p>To utilize a <code>CardView</code>, simply include it in your layout as you would any other ViewGroup:</p>
<div class="sourceCode"><pre class="sourceCode xml"><code class="sourceCode xml"><span class="kw"><android.support.v7.widget.CardView</span>
<span class="ot"> xmlns:card_view=</span><span class="st">"http://schemas.android.com/apk/res-auto"</span>
<span class="ot"> android:layout_width=</span><span class="st">"@dimen/card_width"</span>
<span class="ot"> android:layout_height=</span><span class="st">"@dimen/card_height"</span>
<span class="ot"> android:layout_gravity=</span><span class="st">"center"</span>
<span class="ot"> card_view:cardCornerRadius=</span><span class="st">"4dp"</span><span class="kw">></span>
<span class="co"><!-- A single TextView in the card --></span>
<span class="kw"><TextView</span>
<span class="ot"> android:layout_width=</span><span class="st">"wrap_content"</span>
<span class="ot"> android:layout_height=</span><span class="st">"wrap_content"</span>
<span class="ot"> android:text=</span><span class="st">"@string/card_text"</span> <span class="kw">/></span>
<span class="kw"></android.support.v7.widget.CardView></span></code></pre></div>
<ul>
<li>Notice the <code>card_view:cardCornerRadius</code> attribute; this is an example of how specific Views may have their own custom properties (sometimes available via a different schema).</li>
</ul>
<p>Since Cards are <code>FrameLayouts</code>, they should only contain a single child. If you want to include multiple elements inside a Card (e.g., an image, some text, and a button), you will need to nest another ViewGroup (such as a <code>LinearLayout</code>) inside the Card.</p>
<p>For design suggestions on using Cards, including spacing information, see the <a href="https://material.io/guidelines/components/cards.html">Material Design guidelines</a>.</p>
<p class="alert alert-info">
If you want to include a circular image in your card (or anywhere else in your app), the easiest solution is to include an external library that provides such a View, the most popular of which is <a href="https://github.com/hdodenhof/CircleImageView"><code>de.hdodenhof.circleimageview</code></a>.
</p>
</div>
<div id="floating-action-buttons-fab" class="section level4 unnumbered">
<h4>Floating Action Buttons (FAB)</h4>
<p>While RecyclerViews and Cards are found in the <code>v7</code> support library, the most noticeable and interesting components come from the <a href="https://developer.android.com/training/material/design-library.html">Design Support Library</a>, which specifically includes components for supporting Material Design.</p>
<ul>
<li>This library should be included in gradle as <code>com.android.support:design:27.1.1</code>, as in the above example.</li>
</ul>
<p>The most common element from this library is the <a href="https://developer.android.com/training/material/design-library.html#CreateFAB"><strong>Floating Action Button (FAB)</strong></a>. This is a circular button that “floats” above the content of the screen (at a higher elevation), and represents the <em>primary action</em> of the UI.</p>
<ul>
<li>A screen should only ever have one FAB, and only if there is a single main action that should be performed. See the <a href="https://material.io/guidelines/components/buttons-floating-action-button.html">design guidelines</a> for more examples on how to use (and not use) FABS.</li>
</ul>
<p>Like a Card, you can include a FAB in your application by specifying it as an element in your XML:</p>
<div class="sourceCode"><pre class="sourceCode xml"><code class="sourceCode xml"><span class="kw"><android.support.design.widget.FloatingActionButton</span>
<span class="ot"> android:layout_width=</span><span class="st">"wrap_content"</span>
<span class="ot"> android:layout_height=</span><span class="st">"wrap_content"</span>
<span class="ot"> android:layout_gravity=</span><span class="st">"end|bottom"</span>
<span class="ot"> android:layout_margin=</span><span class="st">"@dimen/fab_margin"</span>
<span class="ot"> android:src=</span><span class="st">"@drawable/ic_my_icon"</span> <span class="kw">/></span></code></pre></div>
<ul>
<li>Because FABs are a subclass of <code>ImageButton</code>, we can just replace an existing button with a FAB without breaking anything.</li>
</ul>
<p>Fabs support a number of additional effects. For example, if you make the FAB clickable (via <code>android:clickable</code>), you can specify an <code>app:rippleColor</code> to give it a rippling effect when pressed. Further details will be presented below.</p>
</div>
<div id="snackbars" class="section level4 unnumbered">
<h4>Snackbars</h4>
<p>The Design Support Library also includes an alternative to Toast messages called <a href="https://developer.android.com/training/snackbar/showing.html"><strong>Snackbars</strong></a>. This is a user-facing pop-up message that appears at the bottom of the screen (similar to a Toast).</p>
<p>Snackbars are shown using a similar structure to Toasts:</p>
<div class="sourceCode"><pre class="sourceCode kotlin"><code class="sourceCode kotlin"><span class="kw">val</span> <span class="va">snack</span> = Snackbar.make(view, <span class="st">"Let's go out to the lobby!"</span>, Snackbar.LENGTH_LONG).show();</code></pre></div>
<ul>
<li><p>Instead of calling the <code>Toast.makeText()</code> factory method, we call the <code>Snackbar.make()</code> factory method. The first parameter in this case needs to be a View that the Snackbar will be “attached” to (so shown with)—however, it doesn’t really matter which View is given, since the method will search up the view hierarchy until it gets to the root content view or a special layout called a <code>CoordinatorLayout</code>.</p></li>
<li><p>You’ll notice that the Snackbar overlays the content (including the FAB). This will be addressed below by introducing a <code>CoordinatorLayout</code>.</p></li>
</ul>
<p>Additionally, it is possible to give Snackbars their own <em>action</em> that the user can activate by clicking on the Snackbar. This allows the bar to, for example, show a delete confirmation but providing an “undo” action. The action is specified by calling the <code>.setAction()</code> method on the Snackbar, and passing in a title for the action as well as an <code>OnClickListener</code>:</p>
<div class="sourceCode"><pre class="sourceCode java"><code class="sourceCode java">mySnackbar.<span class="fu">setAction</span>(<span class="st">"Click"</span>, <span class="kw">new</span> <span class="bu">View</span>.<span class="fu">OnClickListener</span>() {
<span class="at">@Override</span>
<span class="kw">public</span> <span class="dt">void</span> <span class="fu">onClick</span>(<span class="bu">View</span> view) {
<span class="co">//...</span>
}
});</code></pre></div>
<div class="sourceCode"><pre class="sourceCode kotlin"><code class="sourceCode kotlin">snack.setAction(<span class="st">"Click"</span>) {
<span class="co">//...</span>
};</code></pre></div>
<ul>
<li>For practice, make the Snackbar <code>.hide()</code> the FAB, but provide an “undo” action that will <code>.show()</code> it!</li>
</ul>
<p>Again, see the <a href="https://material.io/guidelines/components/snackbars-toasts.html">design guidelines</a> for more examples on how to use (and not use) Snackbars.</p>
<!-- Break here! -->
</div>
</div>
<div id="coordinator-layout" class="section level3 unnumbered">
<h3>Coordinator Layout</h3>
<p>In order to fix the Snackbar and Fab overlap, we’ll need to utilize one of the most powerful but complex classes in the Material support library: the <a href="https://developer.android.com/reference/android/support/design/widget/CoordinatorLayout.html"><strong>CoordinatorLayout</strong></a>. This layout is described as “a super-powered Framelayout”, and provides support for a number of interactive and animated behaviors involves other classes. A lot of the “whizbang” effects in Material are built on top of the CoordinatorLayout (or other classes that rely on it).</p>
<p>To start our exploration of CoordinatorLayout, let’s begin by fixing the Snackbar overlap. To do this, we’ll take the existing layout for the activity and “wrap” it in a <code><android.support.design.widget.CoordinatorLayout></code> element:</p>
<div class="sourceCode"><pre class="sourceCode xml"><code class="sourceCode xml"><span class="kw"><android.support.design.widget.CoordinatorLayout</span>
<span class="ot"> xmlns:android=</span><span class="st">"http://schemas.android.com/apk/res/android"</span>
<span class="ot"> xmlns:app=</span><span class="st">"http://schemas.android.com/apk/res-auto"</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>
<span class="co"><!-- Previous layout elements --></span>
<span class="kw"><RelativeLayout</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>
<span class="co"><!-- etc --></span>
<span class="kw"></RelativeLayout></span>
<span class="kw"></android.support.design.widget.CoordinatorLayout></span></code></pre></div>
<p>We will also need to move the FAB definition so that it is a <em>direct child</em> of the CoordinatorLayout. Once we have done so, we should be able to click the button and watch it move up to make room for the Snackbar!</p>
<ul>
<li>How this works is that the CoordinatorLayout allows you to give <a href="https://developer.android.com/reference/android/support/design/widget/CoordinatorLayout.Behavior.html"><strong>Behaviors</strong></a> to its child views; these Behaviors will then be executed when the state of the CoordinatorLayout (or its children) changes. For example, the built-in <code>FloatingActionButton.Behavior</code> defines how the button should move in response to its parent changing size, but Behaviors can also be defined in response to use interactions such as swipes or other gestures.</li>
</ul>
<div id="scrolling-layouts" class="section level4 unnumbered">
<h4>Scrolling Layouts</h4>
<p>Indeed, the built-in behaviors can be quite complex (and wordy to implement), and the best way to understand them is to see them in action. To see an example of this, create a <strong>new</strong> Activity for your application (e.g., <code>File > New > Activity</code>). But instead of creating an <em>Empty</em> Activity as you’ve done before, you should instead create a new <strong>ScrollingActivity</strong>.</p>
<ul>
<li><p>Modify the FAB action so that when you click on it, you send an <code>Intent</code> for to open up this new Activity:</p>
<div class="sourceCode"><pre class="sourceCode java"><code class="sourceCode java"><span class="fu">startActivity</span>(<span class="kw">new</span> <span class="fu">Intent</span>(MainActivity.<span class="fu">this</span>, ScrollingActivity.<span class="fu">class</span>));</code></pre></div></li>
<li><p>And once you’ve opened up the Activity… try scrolling! You should see the ActionBar collapse while the FAB moves up and disappears.</p></li>
</ul>
<p>This is an example of a collection of behaviors built into <code>CoordinatorLayout</code> and other classes in the Design Support library. To get a sense for how they work, open up the newly created <code>activity_scrolling.xml</code> layout resource and see how this layout was constructed!</p>
<ul>
<li><p>At the root of the layout we find the <code>CoordinatorLayout</code>, ready to “coordinate” all of its children and allow them to interact.</p></li>
<li><p>The first child is an <a href="https://developer.android.com/reference/android/support/design/widget/AppBarLayout.html"><code>AppBarLayout</code></a>. This layout specifically supports responding to scroll events produced from within the CoordinatorLayout (e.g., when the user scrolls through the text content). You can control the visibility of this element based on scrolling using the <code>app:layout_scrollFlags</code> attribute.</p>
<p>The AppBarLayout works together with its child <a href="http://developer.android.com/reference/android/support/design/widget/CollapsingToolbarLayout.html"><code>CollapsingToolbarLayout</code></a>, which does just what it says on the tin. It shows a larger title, but then shrinks down in response to scrolling. Here the <code>scrollFlags</code> are declared: <code>scroll|exitUntilCollapse</code> indicates two flags (combined with a bitwise OR <code>|</code>): that the content should scroll, and that it should shrink to its minimum height until it collapses.</p>
<p>The Toolbar itself is finally defined as a child of <code>CollapsingToolbarLayout</code>, though other children could be added here as well. For example, an <code>ImageView</code> could be included as a child of the CollapsingToolbarLayout in order to create a collapsing image!</p>
<p>(Check the documentation for details about all of the specific attributes).</p></li>
<li><p>After the collapsing AppBar, the <code>CoordinatorLayout</code> includes a <a href="https://developer.android.com/reference/android/support/v4/widget/NestedScrollView.html"><code>NestedScrollView</code></a> (declared in a separate file for organization). This is a scrollable view (similar to what is used in a ListView), but can both include and be included within scrollable layouts.</p>
<ul>
<li>Notice that this element includes an <code>app:layout_behavior</code> attribute, which refers to a particular class: <code>AppBarLayout$ScrollingViewBehavior</code> (the <code>$</code> is used to refer to a compiled nested class). This Behavior will “automatically scroll any AppBarLayout siblings”, allowing the scrolling of the page content to <em>also</em> cuase the AppBarLayout to scroll!</li>
</ul></li>
<li><p>Finally, we have the FAB for this screen. The biggest piece to note here is how the FAB includes the <code>app:layout_anchor</code> attribute assigned a reference to the AppBarLayout. This indicates that the FAB should follow (scroll with) the AppBarLayout; the <code>app:anchorGravity</code> property indicates where it should be relative to its anchor. Moreover, the FAB’s default behavior will cause it to disappear when then is no room… and since the AppBarLayout exits on collapse, the FAB disappears as well!</p></li>
</ul>
<p>In sum: the <code>NestedScrollingView</code> has a Behavior that will cause the AppBarLayout to scroll with it. The AppBarLayout has Behaviors that allow it to collapse, and the FAB is connected to that layout to moves up with it and eventually disappear.</p>
</div>
<div id="custom-behaviors" class="section level4 unnumbered">
<h4>Custom Behaviors</h4>
<p>We can also create our own custom behaviors if we want to change the way elements interact with the CoordinatorLayout. For example, we can create a Behavior so that the FAB on the <code>MainActivity</code> shrinks and disappears when the Snackbar is shown, rather than moving up out of the way!</p>
<p>First, we will create a new Java class to represent our <code>ShrinkBehavior</code>. This class will need to <code>extend CoordinatorLayout.Behavior<FloatingActionButton></code> (because it is a <code>CoordinatorLayout.Behavior</code> and it will be applied to a <code>FloatingActionButton</code>).</p>
<ul>
<li><p>We will need also need to override the constructor so that we can declare/instantiate this class from the XML:</p>
<div class="sourceCode"><pre class="sourceCode java"><code class="sourceCode java"><span class="kw">public</span> <span class="fu">ShrinkBehavior</span>(<span class="bu">Context</span> context, <span class="bu">AttributeSet</span> attrs) {
<span class="kw">super</span>(context, attrs);
}</code></pre></div></li>
</ul>
<p>The next step is to make sure the Behavior is able to react to changes in the Snackbar. To do this we have to make the Behavior report that is has the Snackbar as a <em>dependency</em>. This way when the CoordinatorLayout is propagating events and changes to all of its children, it will know that it should also inform the FAB about changes to the Snackbar. We do this by overriding the <code>layoutDependsOn()</code> method:</p>
<div class="sourceCode"><pre class="sourceCode java"><code class="sourceCode java"><span class="kw">public</span> <span class="dt">boolean</span> <span class="fu">layoutDependsOn</span>(CoordinatorLayout parent,
FloatingActionButton child, <span class="bu">View</span> dependency) {
<span class="co">//add SnackbarLayout to the dependency list (if any)</span>
<span class="kw">return</span> dependency <span class="kw">instanceof</span> Snackbar.<span class="fu">SnackbarLayout</span> ||
<span class="kw">super</span>.<span class="fu">layoutDependsOn</span>(parent, child, dependency);
}</code></pre></div>
<ul>
<li>(Technically the <code>super</code> class doesn’t have any other dependencies, but it’s still good practice to call up the tree).</li>
</ul>
<p>Finally, we can specify what should happen when one of the dependency’s Views change by overriding the <code>onDependentViewChange()</code> callback:</p>
<div class="sourceCode"><pre class="sourceCode java"><code class="sourceCode java"><span class="kw">public</span> <span class="dt">boolean</span> <span class="fu">onDependentViewChanged</span>(CoordinatorLayout parent, FloatingActionButton child, <span class="bu">View</span> dependency) {
<span class="kw">if</span>(dependency <span class="kw">instanceof</span> Snackbar.<span class="fu">SnackbarLayout</span>){
<span class="co">//calculate how much Snackbar we see</span>
<span class="dt">float</span> snackbarOffset = <span class="dv">0</span>;
<span class="kw">if</span>(parent.<span class="fu">doViewsOverlap</span>(child, dependency)){
snackbarOffset = <span class="bu">Math</span>.<span class="fu">min</span>(snackbarOffset, dependency.<span class="fu">getTranslationY</span>() - dependency.<span class="fu">getHeight</span>());
}
<span class="dt">float</span> scaleFactor = <span class="dv">1</span> - (-snackbarOffset/dependency.<span class="fu">getHeight</span>());
child.<span class="fu">setScaleX</span>(scaleFactor);
child.<span class="fu">setScaleY</span>(scaleFactor);
<span class="kw">return</span> <span class="kw">true</span>;
}<span class="kw">else</span> {
<span class="kw">return</span> <span class="kw">super</span>.<span class="fu">onDependentViewChanged</span>(parent, child, dependency);
}
}</code></pre></div>
<ul>
<li><p>This method will be passed a reference to the <code>CoordinatorLayout</code> that is managing the changes, the <code>FloatingActionButton</code> who is receiving the change, and <em>which dependency</em> had it’s View changed. We check that the dependency is actually a <code>Snackbar</code> (since we might have multiple dependencies and want to respond differently to each one), and then call some getters on that dependency to figure out how tall it is (and thus how much we should shrink by). Finally, we use setters to change the scaling of the <code>child</code> (the FAB), thereby having it scale!</p></li>
<li><p>And because this scale is dependent on the Snackbar’s height, the FAB will also “grow back” when the Snackbar goes away!</p></li>
</ul>
<p>This is about the simplest form of Behavior we can have: more complex behaviors can be based on scroll or fling events, utilizing different state attributes for different dependencies!</p>
<p class="alert alert-warning">
Custom behaviors are very tricky to write and design; the overridden functions are not very well documented, and by definition these behaviors involve coordinating lots of different classes! Most custom behaviors are designed by reading the Android source code (e.g., for <code>FloatingActionButton.Behavior</code>) and modifying that as an example. My suggestion is to search online for behaviors similar to the one you’re trying to achieve, and work from there.
</p>
</div>
</div>
</div>
<div id="animations" class="section level2">
<h2><span class="header-section-number">5.4</span> Animations</h2>
<p>One of the key principles of Material Design was the use of <em>motion</em>: many of the previous examples have involved adding animated changes to elements (e.g., moving or scrolling). The Material theme available in API 21+ provides a number of different techniques for including <a href="https://developer.android.com/training/material/animations.html"><strong>animations</strong></a> in your application—in particular, using animation to give user feedback and provide connections between elements when the display changes. As a final example, this section will cover how to add simple <a href="https://developer.android.com/training/material/animations.html#Transitions">Activity Transitions</a> so that Views “morph” from one Activity to the next.</p>
<p>In order to utilize Activity Transitions, you will need to enable them in your application’s <em>theme</em> by adding an addition <code><item></code> in the theme declaration (in <code>res/values/styles.xml</code>):</p>
<div class="sourceCode"><pre class="sourceCode xml"><code class="sourceCode xml"><span class="co"><!-- in style: enable window content transitions --></span>
<span class="kw"><item</span><span class="ot"> name=</span><span class="st">"android:windowActivityTransitions"</span><span class="kw">></span>true<span class="kw"></item></span></code></pre></div>
<p>There are three different kinds of Activity Transitions we can specify:</p>
<ol style="list-style-type: decimal">
<li><em>enter</em> transitions, or how Views in an Activity enter the screen</li>
<li><em>exit</em> transitions, or how Views in an Activity leave the screen</li>
<li><em>shared element</em> transitions, or how Views that are shared between Activities change</li>
</ol>
<p>We’ll talk about the later, though the previous two follow a similar process.</p>
<p>In order to animate a <strong>shared element</strong> between two Activities, we need to give them matching identifiers so that the transition framework knows to animate them. We do this by giving each of the shared elements an <code>android:transitionName</code> attribute, making sure that they have the <em>same</em> value.</p>
<ul>
<li><p>For example, we can give the FAB in each activity an <code>android:transitionName="fab"</code>.</p></li>
<li><p>Because the FAB is <em>anchored</em>, we actually need to do some extra work (because FAB will morph to the “unanchored” point and then get moved once the anchorage is calculated). The easiest workaround for this is to wrap the anchored FAB inside an anchored <code>FrameLayout</code>—the FAB just then becomes a normal element with the FrameLayout handling the scrolling behavior.</p>
<div class="sourceCode"><pre class="sourceCode xml"><code class="sourceCode xml"><span class="kw"><FrameLayout</span>
<span class="ot"> android:layout_width=</span><span class="st">"wrap_content"</span>
<span class="ot"> android:layout_height=</span><span class="st">"wrap_content"</span>
<span class="ot"> app:layout_anchor=</span><span class="st">"@id/app_bar"</span>
<span class="ot"> app:layout_anchorGravity=</span><span class="st">"bottom|end"</span>
<span class="ot"> android:elevation=</span><span class="st">"12dp"</span>
<span class="kw">></span>
<span class="kw"><android.support.design.widget.FloatingActionButton</span>
<span class="ot"> android:id=</span><span class="st">"@+id/fab"</span>
<span class="ot"> android:transitionName=</span><span class="st">"same_fab"</span>
<span class="ot"> android:layout_width=</span><span class="st">"wrap_content"</span>
<span class="ot"> android:layout_height=</span><span class="st">"wrap_content"</span>
<span class="ot"> android:layout_margin=</span><span class="st">"@dimen/fab_margin"</span>
<span class="ot"> app:srcCompat=</span><span class="st">"@android:drawable/ic_dialog_email"</span> <span class="kw">/></span>
<span class="kw"></FrameLayout></span></code></pre></div></li>
</ul>
<p>Finally, we need to make sure that the Intent used to start the Activity also starts up the transition animation. We do this be including an additional argument to the <code>startActivity()</code> method: an options <code>Bundle</code> containing details about the animation:</p>
<div class="sourceCode"><pre class="sourceCode java"><code class="sourceCode java"><span class="co">//transition this single item</span>
ActivityOptions options = ActivityOptions.<span class="fu">makeSceneTransitionAnimation</span>(MainActivity.<span class="fu">this</span>, button, <span class="st">"fab"</span>);
<span class="co">// start the new activity</span>
<span class="fu">startActivity</span>(<span class="kw">new</span> <span class="fu">Intent</span>(MainActivity.<span class="fu">this</span>, ScrollingActivity.<span class="fu">class</span>), options.<span class="fu">toBundle</span>());</code></pre></div>
<p>This should cause the FAB to “morph” between Activities (and even morph back when you hit the “back” button)!</p>
<p>For more about what makes effective animation, see the <a href="https://material.io/guidelines/motion/material-motion.html">Material deisgn guidelines</a>.</p>
<p class="alert alert-warning">
I find Activity Transitions to be slick, but finicky: getting them to work properly takes a lot of effort and practice. Most professional apps that utilize Material Design use extensive custom animations for generating these transitions. For examples of more complex Material Design animations and patterns, check out sample applications such as <a href="https://github.com/chrisbanes/cheesesquare">cheesesquare</a> or <a href="https://github.com/nickbutcher/plaid">plaid</a>.
</p>
<!-- Property Animation here??? -->
</div>
<div id="resources-1" class="section level2 unnumbered">
<h2>Resources</h2>
<div class="list-condensed">
<ul>
<li><a href="https://material.io/guidelines/">Material Design Guidelines</a> check the whole document (via the hamburger menu on the left).</li>
<li><a href="https://developer.android.com/training/material/index.html">Material Design for Developers (Google)</a> official documentation for implementing material design</li>
<li><a href="https://guides.codepath.com/android/Material-Design-Primer">Material Design Primer (CodePath)</a> excellent compiled documentation and examples for implementing Material patterns (CodePath in general is an excellent resource).</li>
<li><a href="https://android-developers.googleblog.com/2015/05/android-design-support-library.html">Android Design Support Library (Google Blog)</a> an introduction to the support library features</li>
<li><a href="http://saulmm.github.io/mastering-coordinator">Mastering the Coordinator Layout (Blog)</a> a great set of examples of how to use CoordinatorLayout.</li>
<li><p><a href="http://www.androidauthority.com/using-coordinatorlayout-android-apps-703720/">Using CoordinatorLayout in Android Apps (Blog)</a> another good explanation of CoordinatorLayout</p></li>
<li><a href="https://lab.getbase.com/introduction-to-coordinator-layout-on-android/" class="uri">https://lab.getbase.com/introduction-to-coordinator-layout-on-android/</a></li>
<li><p><a href="https://medium.com/@andkulikov/animate-all-the-things-transitions-in-android-914af5477d50" class="uri">https://medium.com/@andkulikov/animate-all-the-things-transitions-in-android-914af5477d50</a></p></li>
</ul>
</div>
</div>
</div>
<div class="footnotes">
<hr />
<ol start="14">
<li id="fn14"><p><a href="http://developer.android.com/reference/android/support/v7/app/ActionBar.html" class="uri">http://developer.android.com/reference/android/support/v7/app/ActionBar.html</a><a href="material-design.html#fnref14">↩</a></p></li>
<li id="fn15"><p><a href="https://material.io/color/#!/" class="uri">https://material.io/color/#!/</a><a href="material-design.html#fnref15">↩</a></p></li>
<li id="fn16"><p><a href="https://developer.android.com/guide/topics/ui/layout/recyclerview" class="uri">https://developer.android.com/guide/topics/ui/layout/recyclerview</a><a href="material-design.html#fnref16">↩</a></p></li>
</ol>
</div>
</section>
</div>
</div>
</div>
<a href="data-views.html" class="navigation navigation-prev " aria-label="Previous page"><i class="fa fa-angle-left"></i></a>
<a href="fragments.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/material.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>