Академический Документы
Профессиональный Документы
Культура Документы
1
004.43
66
., ., .
ISBN 978-5-496-01517-2
, Java,
C#, C++, C, -, JavaScript, XML, Visual Basic, Visual C++, Perl, Python
.
, , , ,
Android Google Play. ,
16 Android. , Google Play
.
Android 4.3 4.4, Eclipse Android Studio.
32.973.2-018.1
004.43
ISBN 978-0133570922 .
ISBN 978-5-496-01517-2
Prentice Hall
, 2015
, , 2015
........................................................................................... 16
...................................................................................... 17
...................................................................................................................... 17
............................................................................................................. 18
..................................................................................... 19
............................................................................................................................... 20
...................................................................................................................................... 21
.............................................................................................. 23
........................................... 23
Java Development Kit (JDK)....................................................................... 23
.................................................................................................. 24
Android 4.3 SDK................................................................................................................... 25
Android (AVD)
Android............................................................................................................................................. 26
Android ....................................................... 28
............................................................................................ 29
1. Android.................................................................. 31
1.1. .................................................................................................................................. 32
1.2. Android .......... 32
1.3. Android.......................................................................................................... 33
1.4. Android...................................................................................... 37
1.4.1. Android 2.2 (Froyo).................................................................................................. 38
1.4.2. Android 2.3 (Gingerbread)...................................................................................... 39
1.4.3. Android 3.03.2 (Honeycomb).............................................................................. 39
1.4.4. Android Ice Cream Sandwich................................................................................. 40
1.4.5. Android 4.14.3 (Jelly Bean).................................................................................. 41
1.4.6. Android 4.4 (KitKat)................................................................................................ 42
6
1.5. Google Play........................................................................... 43
1.6. ...................................................................................................................................... 45
1.7. Android Software Development Kit (SDK)................................................................... 46
1.8. - ....................... 49
1.8.1. .......................................................................................... 50
1.8.2. ...................................................................................................... 50
1.8.3. ................................................................................ 51
1.8.4. ..................................................................................... 51
1.8.5. ............................................................................. 51
1.8.6. ................................................... 51
1.8.7. ........................................................................................................... 52
1.8.8. ............................................................................................................. 52
1.8.9. - ............................. 52
1.9. Doodlz AVD............... 53
1.9.1. Doodlz AVD Nexus 4.................... 54
1.9.2. Doodlz App AVD......................................................... 64
1.9.3. Doodlz Android.......................... 64
1.10. Android-............................................................... 66
1.11. ............................................................................................ 68
1.12. ................................................................................................................................... 70
2. Welcome.............................................................. 72
2.1. .................................................................................................................................. 73
2.2. .................................................................................... 74
2.2.1. Android Developer Tools IDE................................................................................ 74
2.2.2. TextView ImageView............................................................................................ 74
2.2.3. .............................................................................................. 74
2.2.4. ............................................................................................................... 74
2.2.5. ........................................................................................... 75
2.3. ........................................................................................................ 75
2.3.1. Android Developer Tools... 75
2.3.2. ....................................................................................... 75
2.3.3. New Android Application...................................................... 75
2.3.4. Configure Project............................................................................................. 78
2.3.5. Configure Launcher Icon............................................................................... 78
2.3.6. Create Activity.................................................................................................. 80
2.3.7. Blank Activity................................................................................................... 81
8
3.5. ........................................................ 123
3.6. AndroidManifest.xml ............................................................................................. 132
3.7. .................................................................................................................................... 133
4. Twitter Searches............................................ 135
4.1. ................................................................................................................................ 136
4.2. .............................................................................................. 137
4.2.1. ......................................................... 137
4.2.2. ................................................................................. 137
4.2.3. ............................................................................ 139
4.2.4. ...................................................................................... 140
4.2.5. ................................................................................................. 141
4.2.6. .................................................................................................... 142
4.2.7. ..................................................... 143
4.3. .................................................................................. 144
4.3.1. ListView...................................................................................................................... 144
4.3.2. ListActivity................................................................................................................ 145
4.3.3. ListActivity........................................................................... 145
4.3.4. ImageButton.............................................................................................................. 145
4.3.5. SharedPreferences . ................................................................................................. 145
4.3.6. ............................................................ 146
4.3.7. AlertDialog................................................................................................................ 147
4.3.8. AndroidManifest.xml.................................................................................. 148
4.4. ............................................. 148
4.4.1. ................................................................................................... 148
4.4.2. activity_main.xml........................................................................................ 149
4.4.3. GridLayout ........................................... 150
4.4.4. ................................................. 155
4.4.5. ListView: list_item.xml . ....................................................... 157
4.5. MainActivity................................................................................... 158
4.5.1. package import................................................................................... 159
4.5.2. ListActivity...................................................................................... 160
4.5.3. MainActivity .................................................................................. 161
4.5.4. onCreate .......................................... 162
4.5.5. ,
OnClickListener ................ 164
4.5.6. addTaggedSearch........................................................................................ 167
4.5.7. ,
OnItemClickListener ListView
............................................................................................................ 168
4.5.8. ,
OnItemLongClickListener ListView ,
......................................................................................................... 170
4.5.9. shareSearch.................................................................................................. 172
4.5.10. deleteSearch.............................................................................................. 174
4.6. AndroidManifest.xml.......................................................................................................... 175
4.7. .................................................................................................................................... 176
5. FlagQuiz............................................................ 177
5.1. ................................................................................................................................ 178
5.2. Flag Quiz.......................................................................... 179
5.2.1. ......................................................... 179
5.2.2. .......................................................................................... 180
5.2.3. ......................................................................... 180
5.3. .................................................................................. 184
5.3.1. ........................................................................................................................... 184
5.3.2. ................................................................................................................ 184
5.3.3. ......................................................... 185
5.3.4. .................................................................................... 186
5.3.5. Preference................................................................................................ 186
5.3.6. assets.............................................................................................................. 186
5.3.7. ....................................................................................................... 187
5.3.8. ................................. 187
5.3.9. .............................................................................. 188
5.3.10. ......................................................................... 188
5.3.11.
............................................................................................................ 189
5.3.12. ........................................................ 189
5.3.13. Log.e............................................... 189
5.3.14.
............................................................................... 190
5.3.15. Java..................................................................................... 190
5.4. ................................. 190
5.4.1. ................................................................................................... 190
5.4.2. strings.xml ............................................. 191
10
5.4.3. arrays.xml ................................................................................................................. 192
5.4.4. colors.xml.................................................................................................................... 193
5.4.5. dimens.xml................................................................................................................. 194
5.4.6. activity_settings.xml................................................................................. 194
5.4.7. activity_main.xml
.......................................................................................................................... 195
5.4.8. fragment_quiz.xml...................................................................................... 196
5.4.9. activity_main.xml ........ 198
5.4.10.
preferences.xml.................................................................................................................... 199
5.4.11. ................................................. 201
5.5. MainActivity............................................................................................................ 203
5.5.1. package, import ...................................................... 203
5.5.2. onCreate . ................................................................ 204
5.5.3. onStart . ................................................................... 206
5.5.4. onCreateOptionsMenu........................................ 207
5.5.5. onOptionsItemSelected....................................... 208
5.5.6. ,
OnSharedPreferenceChangeListener .......................................................................... 208
5.6. QuizFragment.......................................................................................................... 210
5.6.1. package import ................................................................ 210
5.6.2. ............................................................................................................................ 211
5.6.3. onCreateView......................................................... 212
5.6.4. updateGuessRows ..................................................................................... 214
5.6.5. updateRegions............................................................................................. 215
5.6.6. resetQuiz ..................................................................................................... 215
5.6.7. loadNextFlag .............................................................................................. 217
5.6.8. getCountryName........................................................................................ 219
5.6.9. ,
OnClickListener . .............................................................................................................. 220
5.6.10. disableButtons ......................................................................................... 222
5.7. SettingsFragment.................................................................................................... 223
5.8. SettingsActivity....................................................................................................... 223
5.9. AndroidManifest.xml ......................................................................................................... 224
5.10. ................................................................................................................................. 225
6. CannonGame.................................................... 227
6.1. ................................................................................................................................ 228
11
12
7. Doodlz................................................................ 259
7.1. ................................................................................................................................ 260
7.2. .................................................................................. 261
7.2.1. SensorManager
.......................................................... 262
7.2.2. DialogFragment.......................................... 262
7.2.3. Canvas Bitmap . ........................................ 263
7.2.4.
Path................................................................................................................... 263
7.2.5. Android 4.4......................................................................... 263
7.2.6. GestureDetector SimpleOnGestureListener ............................................... 264
7.2.7. .................................................... 264
7.2.8. Android 4.4 PrintHelper
Android Support Library............................................................................................. 264
7.3. ............ 264
7.3.1. ................................................................................................... 265
7.3.2. strings.xml...................................................................................................... 265
7.3.3. dimens.xml..................................................................................................... 266
7.3.4. DoodleFragment ........................................................................................ 267
7.3.5. activity_main.xml MainActivity . ................................................. 268
7.3.6. fragment_doodle.xml DoodleFragment . ................ 269
7.3.7. fragment_color.xml ColorDialogFragment........... 269
7.3.8. fragment_line_width.xml
LineWidthDialogFragment . ........................................................................................... 272
7.3.9. EraseImageDialogFragment .......................................... 273
7.4. MainActivity............................................................................................................ 274
7.5. DoodleFragment...................................................................................................... 275
7.6. DoodleView.............................................................................................................. 282
7.7. ColorDialogFragment............................................................................................ 295
7.8. LineWidthDialogFragment.................................................................................. 299
7.9. EraseImageDialogFragment................................................................................. 302
7.10. ................................................................................................................................. 304
8. Address Book..................................................... 306
8.1. ................................................................................................................................ 307
8.2. Address Book................................................................... 309
8.3. .................................................................................. 311
8.3.1. FragmentTransaction..... 311
13
8.3.2.
........................................................................................................................ 311
8.3.3. onSaveInstanceState................................................................................. 312
8.3.4. GUI......................... 312
8.3.5. TextView........................................... 312
8.3.6. ListFragment ,
ListView..................................................................................................... 312
8.3.7. SQLite........................................................................... 313
8.3.8. GUI
AsyncTask......................................................................................... 313
8.4. .......... 313
8.4.1. ................................................................................................... 313
8.4.2. .......................................................................... 314
8.4.3. strings.xml...................................................................................................... 315
8.4.4. styles.xml........................................................................................................ 316
8.4.5. textview_border.xml .................................................................................. 317
8.4.6. MainActivity: activity_main.xml . ........................................... 317
8.4.7. DetailsFragment: fragment_details.xml ................................. 318
8.4.8. AddEditFragment: fragment_add_edit.xml . ..................................... 320
8.4.9. ........................................................................ 321
8.5. MainActivity............................................................................................................ 323
8.6. ContactListFragment............................................................................................. 329
8.7. AddEditFragment................................................................................................... 336
8.8. DetailsFragment...................................................................................................... 342
8.9. DatabaseConnector............................................................. 350
8.10. ................................................................................................................................. 356
9. Google Play ............... 358
9.1. ................................................................................................................................ 359
9.2. ..................................................................... 359
9.2.1. .................................................................................. 360
9.2.2. .................................................................................. 360
9.2.3. ........................................................................................................ 360
9.2.4. ........................................................................... 361
9.2.5.
................................................................................................ 362
9.2.6. .................................................................................................... 362
9.2.7. ............................... 362
14
9.2.8. ........................................................................................................ 363
9.2.9. ......................................................................... 364
9.3. : ?........................................................... 365
9.3.1. ........................................................................................... 366
9.3.2. ..................................................................................... 367
9.4. ............................. 368
9.5. ............................................................. 369
9.6. Google Play.............................................................................................. 371
9.7. Google Wallet.................................................................... 371
9.8. Google Play.......................................................................... 372
9.9. Play Store ................................................................................. 374
9.10. Google Play.............................................................. 375
9.11. Android................................................................... 375
9.12. ............................... 376
9.13. ................................................................................................. 377
9.14. ................................................................................................................................. 382
. ,
MIT, Bose Corporation.
,
,
.
, ,
, .
Android Android Software Development Kit (SDK),
Java, Android
Development Tools Eclipse,
Android Studio.
.
, , Android,
. ,
.
, .
.
www.deitel.com/books/AndroidFP2/. .
Android Android- . Android
2008 . ,
Strategy Analytics, 2013 Android
81,3% , Apple iPhone 13,4%,
Microsoft 4,1%, BlackBerry 1%1.
IDC, 2013 Android 56,5%
, 39,6% Apple iPad 3,7%
Microsoft Windows2.
Android3, 1,5 4.
IDC, Samsung
http://blogs.strategyanalytics.com/WSS/post/2013/10/31/Android-Captures-Record-81Percent-Share-of-Global-Smartphone-Shipments-in-Q3-2013.aspx
http://www.idc.com/getdoc.jsp?containerId=prUS24093213
http://www.android.com/kitkat
http://www.technobuffalo.com/2013/04/16/google-daily-android-activations-1-5-million
17
Android-, ,
Deitel & Associates, Inc. , , Creative Commons Attribution 3.0 Unported
License (http://creativecommons.org/licenses/by/3.0/) ,
-
, .
, .
, .
.
- , deitel@deitel.com.
, Java - , XML.
Android- XML.
XML-, .
, , Java, - C#/.NET, Objective-C/Cocoa C++ ( ), ,
Java - .
Java,
Android-.
Java, :
18
Java for Programmers, 2/e (www.deitel.com/books/javafp2)
Java Fundamentals: Parts I and II LiveLessons videos (www.deitel.com/books/
LiveLessons)
Java How to Program, 10/e (www.deitel.com/books/jhtp10)
XML, :
http://www.ibm.com/developerworks/xml/newto
http://www.w3schools.com/xml/xml_whatis.asp
http://www.deitel.com/articles/xml_tutorials/20060401/XMLBasics
http://www.deitel.com/articles/xml_tutorials/20060401/XMLStructuringData
, . 28
, ,
, .
,
; ,
, Android API, .
Android SDK 4.3 4.4. , Android SDK (Software Development Kit) 4.3 4.4.
. 5
.
, ,
. ,
;
8.
.
Android (, ..)
.
ADT (Android Development Tools) Eclipse
. (IDE)
Android Development Tools (ADT), Eclipse ADT,
JDK (Java Development Kit)
, Android, (, Google Play) ..
19
, , .
deitel@deitel.com.
www.deitel.com/books/AndroidFP2
20
Facebook, Twitter, Google+, LinkedIn Deitel Buzz Online.
www.deitel.com, :
;
-
;
;
Deitel Buzz Online,
, www.deitel.com/newsletter/subscribe.html;
Dive Into Series,
(Barbara Deitel)
Android,
.
Pearson.
18- . (MarkL.
Taub), Pearson Technology Group.
. (Kim Boedigheimer)
Android
, Android. ,
(Chuti Prasertsith) (Sandra Schroeder)
. (John Fuller)
Deitel Developer Series.
(Tracy Johnson), .
. (Carole Snyder)
.
(Bob Engelhardt) .
, Deitel & Associates,
Inc., Android- Imerj,
, iPhone for Programmers: An App-Driven Approach.
.
21
. (Paul J. Deitel),
Deitel & Associates, Inc., (MIT)
(Information Technology). Java Certified Programmer, Java Certified Developer Oracle
Java Champion. Deitel& Associates, Inc.
, Cisco, IBM, Siemens, Sun Microsystems,
Dell, Fidelity, NASA ( ),
, -, Rogue Wave
Software, Boeing, SunGard Higher Education, Stratus, Cambridge Technology Partners,
One Wave, Hyperion Software, Adra Systems, Entergy, CableData Systems, Nortel
Networks, Puma, iRobot, Invensys . , -
22
. ,
, , .
. (Dr. Harvey M. Deitel),
Deitel & Associates, Inc., 50-
. .
1960- , IBM, Advanced Computer Techniques Computer Usage Corporation,
1970- .
. 1991
. Deitel & Associates, Inc.
LiveLessons.
, , , , , , , , , , ,
. , , .
(Abbey Deitel), Deitel & Associates, Inc.,
Tepper -
.
Deitel & Associates, Inc. 16 .
Deitel & Associates
Android for Programmers: An App-Driven
Approach, 2/e, iPhone for Programmers: An App-Driven Approach, Internet &
World Wide Web How to Program, 5/e, Visual Basic 2012 How to Program, 6/e
Simply Visual Basic 2010, 5/e.
, . Android
. ,
http://www.deitel.com/books/AndroidFP2/
, .
Android Windows,
Linux Mac OS X.
http://developer.android.com/sdk/requirements.html
( SYSTEM REQUIREMENTS). , , :
Java SE 7 Software Development Kit;
Android SDK/ADT Bundle Eclipse;
Android SDK, 4.3 4.4.
, , .
24
JDK. 32- 64-
.
64-
. 32-
, 32- JDK.
http://docs.oracle.com/javase/7/docs/webnotes/install/index.html
Google Android.
Android SDK/ADT Eclipse -
IDEA; , .
Android SDK/ADT Android
. Android Studio, 2013, .
Android SDK/ADT.
Android SDK/ADT
Android SDK/ADT,
http://developer.android.com/sdk/index.html
Download the SDK ADT Bundle. , ZIP- .
eclipse Eclipse sdk Android SDK.
JDK, 32- 64- . 32-
Android SDK/ADT 32-
JDK, 64- 64- 64-bit JDK.
Android Studio
, ,
Android SDK/ADT.
Android Studio. Android Studio,
http://developer.android.com/sdk/installing/studio.html
Download Android Studio. , . [:
25
) eclipse ,
Android SDK/ADT.
2. Workspace Launcher, OK.
3. WindowPreferences, Preferences. Mac
OS X ADTPreferences
4. Java Compiler. JDK Compliance (Compiler compliance level) 1.6 ( ,
Eclipse ,
Java SE 6).
5. GeneralEditors TextEditors. ,
Show line numbers . OK.
6. Eclipse.
.
2. Workspace Launcher, OK.
3. Mac OS X Could not find SDK folder /Users/
YourAccount/android-sdk-macosx/, Open Preferences, Browse sdk , Android SDK/ADT.
4. WindowAndroid SDK Manager; Android SDK
Manager (. 0.1).
26
Android (AVD)
Android
Android, Android SDK, Android ,
Android. , Android, ,
, .
(developer.android.com/tools/devices/emulator.html#acceleration).
, Android
Virtual Device (AVD). ,
: (),
, , SD, , .
Android,
AVD .
AVF Android ( Nexus 4, Nexus 7
Nexus 10) Android.
AVD, .
1. Eclipse.
2. WindowAndroid Virtual Device Manager.
Android Virtual Device Manager Device Definitions (. 0.2).
3. Google ,
AVD. Nexus 4 by Google Create AVD,
Create new Android Virtual Device (AVD) (. 0.3).
, , OK,
AVD. Hardware keyboard present,
, AVD,
.
, Emulated Front
Camera Back Camera. AVD
, config.ini. ,
;
http://developer.android.com/tools/devices/managing-avds.html
28
Android
, AVD .
Android, . ,
. ,
Android,
http://developer.android.com/tools/device.html
Microsoft Windows,
Windows USB Android.
USB-, .
USB-, ,
http://developer.android.com/tools/extras/oem-usb.html
, ,
http://www.deitel.com/books/AndroidFP2/
-, www.deitel.
com Register. .
, .
30
.
deitel.com ,
.
deitel.com,
. ,
, Deitel Buzz Online
www.deitel.com/newsletter/subscribe.html
www.deitel.com , Login
. http://
www.deitel.com/books/AndroidFP2/. Examples,
Zip- . , . ,
.
Android
Google Android. ,
. Eclipse Android Studio
, , - . , deitel@deitel.com
:
Facebook facebook.com/DeitelFan
Google+ google.com/+DeitelFan
.
, , Android-
. !
Android
Android Android SDK
Google Play Store
Android,
Android
,
Android, Android SDK, Java SDK, Eclipse Android Studio
Android
Android Eclipse
Android
32 1 Android
1.1.
Android! ,
Android . . 2- ,
.
Java.
, , Java,
- (C#/,
Objective-C/Cocoa C++ ),
, Java -
Java
Android.
Android,
. .
Eclipse ( ), Java Android
SDK (Software Development Kit), .
,
Eclipse.
.
- . ,
, .
, , - www.
deitel.com/books/AndroidFP2/.
, Eclipse, Android Studio.
Android Studio ,
Android Studio .
.
1.2. Android
Android
Android.
Android 2008.
1.3. Android33
56,5% 39,6%
Apple iPad 3,7% Microsoft Windows.2
2013 1,5
Android ( , ..).3
-
Android-.4
Android , ,
, , , NASA, ,
, , , , ,
( , GPS, , ..) .5
1.3. Android
Android . Android
. Android ,
.
Android. (http://source.android.com/source/report-bugs.html)
Open Source Project (http://source.android.com/
community/index.html). Android
, Google
(. 1.1). . 1.2 ,
Android, ,
, .
http://blogs.strategyanalytics.com/WSS/post/2013/10/31/Android-Captures-Record-81Percent-Share-of-Global-Smartphone-Shipments-in-Q3-2013.aspx
http://www.idc.com/getdoc.jsp?containerId=prUS24093213
http://www.technobuffalo.com/2013/04/16/google-daily-android-activations-1-5-million
http://venturebeat.com/2013/09/03/android-hits-1b-activations-and-will-be-called-kitkatin-next-version
http://www.businessweek.com/articles/2013-05-29/behind-the-internet-of-things-is-androidand-its-everywhere
34 1 Android
1.1. Android
URL
http://en.wikipedia.org/wiki/List_of_
open_source_Android_applications
, (,
.)
http://developer.android.com/tools/
samples/index.html
Google
Android; 60
(, , -)
http://github.com/
GitHub
,
http://sourceforge.net
SourceForge
,
http://f-droid.org/
http://blog.interstellr.com/
post/39321551640/14-great-androidapps-that-are-also-open-source
14 Android, ,
http://www.openintents.org/en/
libraries
100 ,
http://www.androidviews.net
http://www.stackoverflow.com
Stack Overflow .
,
1.2. Android
URL
Android
http://source.android.com/source/downloading.html
Governance Philosophy
http://source.android.com/about/philosophy.html
http://source.android.com/source/licenses.html
FAQ
http://source.android.com/source/faqs.html
1.3. Android35
.
iOS Apple, Apple, Android
(OEM, Original
Equipment Manufacturer) .
, .
Java
Android Java
. Java Android, ,
, .
Java Android-,
Google Android API (Application Programming Interface)
.
Java -,
, .
,
, .
,
Eclipse Android Studio, , ,
, .
, Android.
Android
, -, MP3-, , . .
, ,
, - .. ,
( Android
).
, . 1.3.
Android ,
,
36 1 Android
1.3. , Android
,
Google Maps -.
,
,
(, ).
(
)
1.4. Android37
1.4. - (www.programmableweb.com/apis/
directory/1?sort=mashups)
-
Google Maps
YouTube
Foursquare
Groupon
Netflix
eBay
Wikipedia
PayPal
Last.fm
Amazon eCommerce
Salesforce.com
Skype
Microsoft Bing
Bing
Flickr
Zillow
Yahoo Search
Yahoo!
WeatherBug
1.4. Android
Android Android, Inc.,
2005 Google. 2007
Open Handset Alliance,
84 (http://www.openhandsetalliance.com/oha_members.html).
, Android, ,
Android .
Android
Android ,
- (. 1.5).
38 1 Android
1.5. Android
Android
Android 1.5
Cupcake
Android 1.6
Donut
Android 2.02.1
clair
Android 2.2
Froyo
Android 2.3
Gingerbread
Android 3.03.2
Honeycomb
Android 4.0
Android 4.14.3
Jelly Bean
Android 4.4
KitKat
http://code.google.com/android/c2dm/
1.4. Android39
;
, -
;
-
, ,
;
Holo,
;
;
40 1 Android
-
;
Bluetooth (, -
, ..);
.
Android 3.0 ,
http://developer.android.com/about/versions/android-3.0-highlights.html
Face detection ( )
,
.
,
,
Android Beam
Android Beam
(, , ) Android
1.4. Android41
Wi-Fi Direct
Wi
-
Fi
P
2
P
(
Peer
-
to
-
Peer
)
API
Android Wi-Fi.
,
Bluetooth
Social API
( )
Calendar API
,
, , ..
Accessibility API
API
(
..).
Explore
-
by
-
touch
Android@Home framework (
Android@Home)
Android,
: , ,
..
,
Bluetooth: , ..
Android Beam
Android
Beam
Bluetooth
42 1 Android
1.7 ()
, ,
,
Photo Sphere
API
, ,
Google Maps Street View
Daydreams
, -.
Daydreams
,
,
(
, , ..)
, ,
http://techcrunch.com/2013/10/31/android-4-4-kitkat-google/
(Immersive mode)
,
.
,
, ( Back, Home
Recent Apps)
,
Wi-Fi ,
,
, (, )
SMS
SMS API.
Chromium WebView
-,
HTML5, CSS3 JavaScript
, , , ,
HCE
NFC
(, )
SIM-
44 1 Android
Google Play : http://play.google.com ,
Android, .
WiFi 3G/4G. 9
, (
), ..
1.9. Android- Google Play
1.6. 45
1.6.
Android ,
.
Android, Java Google.
Android,
. Android-,
Android
(http://developer.android.com/design/index.html). . 1.10 ,
. Android
- developer.android.com/reference/packages.html.
1.10. Android Java, , ,
android.app
Android ( Tip Calculator 3)
android.content
( Cannon Game 6)
android.content.res
, (, , ,
), ,
( Flag Quiz 5)
android.database
,
( Address Book 8)
android.database.sqlite
SQLite
( Address Book 8)
android.graphics
,
( Flag Quiz 5 Doodlz
7)
android.hardware
(
Doodlz 7)
android.media
,
( Cannon Game 6)
android.net
c ( Twitter Searches
4)
android.os
( Tip Calculator
3)
android.preference
( Flag Quiz 5)
android.provider
Android ( Doodlz
7)
46 1 Android
1.10 ()
android.support.v4.print
Android
Support
Library
Android 4.4 ( Doodlz 7)
android.text
( Tip Calculator 3)
android.util
android.widget
, ( Tip Calculator 3)
android.view
,
( Favorite Twitter Searches 4)
java.io
,
( Flag Quiz 5)
java.text
( Twitter
Searches 4)
java.util
( Twitter Searches
4)
android.graphics.drawable
, (, ) ( Flag Quiz
5)
;
.
48 1 Android
Android, AVD
(, testdroid.com
appthwack.com), .
,
Android.
Android (. 1.11) (. 1.12), . , ,
Android. ,
GPS- , , GPS.
( /
), (
) ,
. Sensor Simulator,
AVD
:
https://code.google.com/p/openintents/wiki/SensorSimulator
1.11. Android
( Tip Calculator 3)
( Cannon Game
6)
,
( Cannon Game 6)
, , , ( Address Book 8)
Ctrl. , . , , ,
1.12. Android
(
http://developer.android.com/tools/help/emulator.html)
Android
Back ()
Esc
F3
Ctrl-KEYPAD_5, Ctrl-F3
1.8. - 49
Android
F4
Home ()
Home button
( )
F2 or Page Up button
F7
F5
* ( )
KEYPAD_7, Ctrl-F11
KEYPAD_9, Ctrl-F12
F8
KEYPAD_PLUS, Ctrl-F5
KEYPAD_MINUS, Ctrl-F6
( )
Bluetooth
USB
/ SD-
(, , , , )
1.8. -
Android - , .
.
50 1 Android
, , . ( , 3, ,
)
. , ,
, , .
(, , ) (,
, ). ,
- .
- .
1.8.1.
,
. , , . ,
? , -
.
, . ,
. ,
, , ,
. ,
, .
,
, , . ,
. , ,
( !), , .
1.8.2.
- .
,
, .
, , .
1.8. - 51
, , , .
, , , ,
, ,
.
, ,
.
1.8.3.
, ,
,
. .
.
1.8.4.
,
. .
,
, . , ,
.
1.8.5.
,
( ).
.
, . , deposit
, .
1.8.6.
, , ,
, . ,
(
52 1 Android
).
. . , ,
,
.
, , , . . , bankaccount
, .
bankaccount ,
.
.
1.8.7.
(
).
, ,
.
.
1.8.8.
.
,
. , .
, , .
1.8.9. -
, ? , , ,
.
, ,
, , , ?
1000 ,
?
.
, ( , )
, (
, ).
( ).
- , , - ().
, Java, -.
, - (), -
.
1.9. Doodlz
AVD
Android. Doodlz
,
. 7.
, Eclipse
(AVD) Nexus 4 (c AVD ,
). ,
Android. AVD,
; .
Android SDK/ADT Android Studio
, ,
, Windows 7, Java SE 7 SDK Android SDK/
ADT (. ). Android Studio
,
Android Studio :
www.deitel.com/books/AndroidFP2
, Google. Android SDK/ADT Android Studio
Android, AVD,
.
54 1 Android
. Nexus 4 AVD,
WindowAndroid Virtual Device Manager;
Android Virtual Device Manager (. 1.2). Nexus 4 AVD Android
KitKat Start, Launch
Launch Options. AVD.
AVD (.1.3), AVD,
.
56 1 Android
5. Doodlz. FileImport,
Import (. 1.4, ). General, Existing Projects into Workspace Next>,
Import Projects (. 1.4, ). Browse Select root
. 1.4. :
Import; Import Projects
6. Doodlz. Eclipse
Doodlz Package Explorer Run AsAndroid
Application (. 1.6). Doodlz
, 4 (. 1.7).
7. AVD . AVD ,
. ( AVD)
. 1.6. Doodlz
58 1 Android
Android. Back ()
, .
Home () .
Recent Apps ( )
.
(app bar),
,
(COLOR LINE WIDTH
. 1.7), ( ).
7. Android 4.4
(immersive mode), .
,
, .
,
.
8. . ,
, ( ) (
). .1.8,
Nexus 4 AVD, . 1.8,
Nexus 7 AVD
(). COLOR,
. LINE WIDTH
. Eraser
,
. Clear ,
, (
). Save Image . Android 4.4 Print
, PDF ( ).
.
. 1.8. Doodlz:
Nexus 4 AVD; Nexus 7 AVD
9. . ,
Color (. 1.9).
ARGB,
( 0 255) : - (), , .
- 0 , 255
. , 0
, 255 .
SeekBar,
,
. SeekBar,
. ,
Red , . 1.9.
Set Color, .
60 1 Android
. 1.9.
10. . ,
LINE WIDTH ; Choose
Line Width. SeekBar,
, (. 1.10). Set Line Width,
.
. 1.10.
11. . , ,
( ) , (.1.11).
12. -. ,
, COLOR
Choose Color. - ,
Green SeekBar , Red Blue (. 1.12, ).
13. .
, LINE WIDTH. Choose Line Width. SeekBar,
, (. 1.12, ). ,
, . 12
13 ,
(. 1.13).
. 1.11.
. 1.12. - :
- ;
14. . , .
(. 1.14, ) (. 1.14, ).
62 1 Android
. 1.13.
, ,
(. 1.15).
15. . Gallery. Save .
, , Gallery.
16. . , Print
. ,
PDF.
, Save as PDF
. , ,
Google Cloud Print .
http://www.google.com/cloudprint/learn/
17. . AVD,
Home ( ) AVD. Gallery,
, AVD.
Gallery .
. 1.14. :
;
. 1.15.
64 1 Android
66 1 Android
, Google
Play ,
. ,
.
, AVD,
, . ,
AVD.
config.ini AVD,
Setting hardware emulation options
developer.android.com/guide/developing/tools/avd.html
config.ini , Android Virtual
Device Manager.
Android .
1.10. Android-
Google Play 800000 .1
Android, , , ? , , ,
. ,
Google Play
Android.
,
? . 1.14
.
1.14.
http://www.pureoxygenmobile.com/how-many-apps-in-each-app-store/
1.10. Android-67
/
,
;
( , ..)
( , ,
, ..)
(
, , ..)
Android, Android
Android
,
(
)
, Google Play
, ,
( )
(http://developer.android.com/
guide/topics/ui/accessibility/index.html)
(, Facebook
Twitter)
68 1 Android
1.14 ()
, ( , ,
..)
(. 2) , (,
,
..)
,
Android
, , Google Play
(http://
android-developers.blogspot.com/2010/06/future-proofing-your-app.html)
1.11.
. 1.15 Android
Developer. Android-
, ,
.. Android,
(. 1.16). . 1.17 ,
, Android.
1.15. Android-
URL
http://developer.android.com/guide/components/index.html
Android
http://developer.android.com/tools/devices/emulator.html
http://developer.android.com/reference/packages.html
http://developer.android.com/reference/classes.html
http://developer.android.com/design/index.html
http://developer.android.com/guide/topics/data/backup.html
http://developer.android.com/training/articles/security-tips.
html
Eclipse ADT
http://developer.android.com/guide/developing/projects/
projects-eclipse.html
1.11. 69
URL
Android Studio
http://developer.android.com/sdk/installing/studio.html
http://developer.android.com/tools/debugging/index.html
http://developer.android.com/tools/help/index.html
http://developer.android.com/training/articles/perf-tips.html
http://developer.android.com/training/articles/perf-anr.html
( Google Play)
http://developer.android.com/distribute/googleplay/publish/
preparing.html
http://developer.android.com/distribute/googleplay/publish/
register.html
http://developer.android.com/training/articles/memory.html
Google
Play
http://play.google.com/about/developer-distributionagreement.html
1.16. Android
Android Discuss
Google
Groups:
android-discuss
:
android-discusssubscribe@googlegroups.com
Android,
Stack Overflow
http://stackoverflow.com/
questions/tagged/android
Android,
Java
Eclipse
,
Android Developers
http://groups.google.com/
forum/?fromgroups#!forum/
android-developers
, ,
..
Android Forums
http://www.androidforums.
com
,
Android
70 1 Android
1.17. Android
, ,
URL
Android-
Google
http://code.google.com/p/apps-for-android/
Android-
(OReilly)
http://answers.oreilly.com/topic/862-ten-tips-forandroid-application-development/
Bright
Hub
Android-
http://www.brighthub.com/mobile/google-android.aspx
http://android-developers.blogspot.com/
http://developer.sprint.com/site/global/develop/mobile_platforms/android/android.jsp
http://www.htcdev.com/
Android
- Motorola
http://developer.motorola.com/
http://stackoverflow.com/tags/android/topusers
http://androiddevweekly.com/
Codependent ( )
http://graphics-geek.blogspot.com/
http://cyrilmottier.com/
http://www.curious-creature.org/category/android/
Android-
YouTube
http://www.youtube.com/user/androiddevelopers
Android
http://developer.android.com/develop/index.html
Android-
http://www.youtube.com/watch?v=lmv1dTnhLH4
Google I/O
2013 Developer Conference
http://developers.google.com/events/io/sessions
1.12.
Android
. , ,
1.12. 71
.
Android Market
Google Play , .
Java, Android Google,
Android; .
Java Android SDK, Android,
Android .
, ,
, . Doodlz
Android. 2
Android-, .
.
Android-.
Welcome
Android-
( Eclipse ADT),
,
Android-
( )
Android
,
Android TalkBack Explore-by-Touch
,
2.1. 73
2.1.
Welcome.
,
. ADT ,
Android. ,
, ,
. Android- (.2.1)
,
. , Android (
Android, ). , ,
, . http://www.deitel.com/
books/AndroidFP2
Android Studio. , , 1.9.
74 2 Welcome
2.2.
, .
2.2.3.
,
res . 2.5.3
, (,
TextView) (, ). Android
TextView.
2.2.4.
Android , . ,
TalkBack ,
( , )
. Android
Explore by Touch , TalkBack
. 2.7 ,
.
2.3. 75
2.2.5.
Android .
, ,
.
2.8 , Welcome
TextView ImageView
AVD, .
2.3.
Android Developer Tools
(22.x) Android SDK (4.3 4.4), . , Java SE Development Kit
(JDK) Android Developer Tools,
1.9. ,
IDE, IDE .
2.3.1.
Android Developer Tools
IDE, eclipse Android SDK/
ADT Eclipse icon (
,
).
Welcome (. .2.1).
, HelpAndroid IDE.
2.3.2.
(,
), .
. New Android Application Welcome, New Android Application (. 2.2).
: FileNewAndroid Application Project
New (
)
Android Application Project.
76 2 Welcome
1. Application Name: . Welcome.
2. Project Name: ,
Package Explorer IDE. IDE
,
, , Address Book AddressBook. ,
Project Name:.
3. Package Name: Java . Android Google Play
, .
, . , deitel.com, com.
deitel. .
.
IDE , com.example, ,
.
2.3. 77
API
4.4
19
4.3
18
4.2.x
17
4.1.x
16
4.0.3-4.0.4
15
4.0.1
14
3.2
13
2.3.3-2.3.7
10
2.2
2.1
1.6
78 2 Welcome
7. Theme: , Android.
Holo Light, Holo Dark Holo Light with Dark Action Bars
( IDE ).
Holo Light Holo Dark.
, .
:
http://developer.android.com/design/style/themes.html
2.3. 79
. Android .
,
, . Android ,
( )
(DPI, dots per inch). 3.
http://developer.android.com/training/multiscreen/index.html
http://developer.android.com/design/style/iconography.html
Configure Launcher Icon (. 2.4) , .
, 4848, 7272, 9696 144144
.
DeitelOrange.png. , Browse
Image File:, images ,
80 2 Welcome
DeitelOrange.png Open.
Preview .
. . ,
Google Play,
. 9
Google Play ,
( ).
Next>, .
2.3. 81
2.2. Activity
Blank Activity
,
.
, ,
Fullscreen Activity
(
Blank Activity), ,
Master/Detail Flow
( Email People).
.
,
Activity, .
3
.
XML. ( 2.5)
.
Navigation Type ( IDE None).
Welcome . , ,
.
.
Finish, .
82 2 Welcome
2.4.2.
Package Explorer .2.7
(Graphical Layout). Package Explorer,
(
). Java Java.
XML, (, activity_main.
xml), .
84 2 Welcome
2.4.3.
Outline IDE (. 2.7).
.
, . Java
, .
2.4.4.
, activity_main.xml ( res/layout), res .
. . 2.3 , Welcome; (menu, animator, anim, color, raw xml)
, .
2.3. ,
drawable
,
drawable
, .
XML
, (, ,
)
layout
,
layout
,
XML
, activity_main.xml
values
, values,
(
arrays
.
xml
), (
colors
.
xml
), (
dimen
.
xml
; , , ), (
strings
.
xml
) (
styles
.
xml
). ,
.
,
Java. ,
, ,
Java
2.4.5.
IDE activity_main.xml
(. 2.9).
activity_main.xml res/layout .
Android .
Android. ,
(AVD), Google Nexus4.
, .
Nexus 4,
.2.9. ,
Nexus4,
, Nexus 4.
, , .
2.4.6.
(. 2.9) Blank Page
RelativeLayout - ( , ) TextView "Hello world!".
RelativeLayout , RelativeLayout
, ,
. TextView
86 2 Welcome
. 2.5.
. 2.9.
2.5. 87
2.5.
Welcome.
(Graphical Layout)
GUI,
Button, TextView, ImageView . ,
Blank App XML- activity_main.xml res/layout.
Outline .
Android ,
.
2.5.1.
Deitel
(bug.png) Android (android.png). images/
Welcome . ( , )
.
Android , (DPI, Dot Per Inch),
,
. res
, drawable.
(. 2.4).
2.4. Android
drawable-ldpi
120
drawable-mdpi
160
drawable-hdpi
240
drawable-xhdpi
320
drawable-xxhdpi
480
drawable-xxxhdpi
640
, Google Nexus4,
AVD, drawable-hdpi. (, ) drawable-xhdpi drawable-xxhdpi.
88 2 Welcome
Android drawable-mdpi drawable-ldpi .
.
Android drawable, ( ,
).
2.1
.
,
, .
2.2
Android
http://developer.android.com/guide/practices/screens_
support.html.
, .
1. Package Explorer res .
2. Welcome images .
res/drawable-hdpi. ,
File Operation Copy Files,
OK. PNG, JPG
GIF .
.
2.5.2. Id RelativeLayout
TextView
,
(Properties) Outline
XML.
,
Outline (. 2.10).
. 2.10.
2.5. 89
,
(
).
Id.
, XML. , Id
RelativeLayout.
RelativeLayout,
Id
@+id/welcomeRelativeLayout
+ @+id (
), /.
TextView Id
@+id/welcomeTextView
, . 2.11.
. 2.11. Id RelativeLayout
TextView
2.5.3. TextView
Welcome TextView, .
90 2 Welcome
Text TextView
Android (http://developer.android.
com/guide/topics/resources/index.html), ,
, , , ,
res , Java- .
. , , ,
.
,
,
. res values,
strings.xml. .
, values
( 2.8).
Text TextView,
strings.xml.
1. , TextView.
2. Text, , . ,
, Resource Chooser.
3. Resource Chooser New String, Create New Android String, . 2.12.
4. String New R.string (. . 2.12), Replace in
all XML file for different configurations, OK,
Resource Chooser. String ,
TextView, R.string , Text TextView.
5. welcome . OK,
.
Text , .2.13.
@string ,
strings.xml ( res/values ), welcome
.
Text Size TextView ,
GUI Android (. 2.5). ,
, -
developer.android.com/guide/practices/screens_support.html
2.5. 91
GUI
, ,
, .
px
dp dip
sp
in
mm
92 2 Welcome
, (dp dip),
Android .
, ,
160 dpi ( ). 240 dpi , ,
240/160 ( 1,5). , , 100 , ,
150 .
120
120/160 ( 0,75). , 100
75 . , , , ,
, ,
.
TextView
TextView, .
:
1. , welcomeTextView.
2. Text Size .
, Resource Chooser.
3. Resource Chooser New Dimension
4. Name welcome_textsize,
Value 40sp. OK,
Resource Chooser. sp 40sp ,
, . dp (, 10dp) , .
welcome_textsize . OK,
.
TextView
TextView.
Text Color @android:color/holo_blue_dark. Android
.
@android:color/ Text Color,
(. 2.14). @android:color/holo_blue_dark,
-.
, , TextView,
Gravity center. Value
, ,
2.5. 93
. 2.15. Gravity
, . 2.16.
ImageView
ImageView , ,
2.5.1. ImageView
94 2 Welcome
Images&Media .
.
1. Images & Media Ima
geView (. 2.17). ImageView
welcomeTextView.
, . , , ,
. . 2.17 , ImageView
(
, ) welcomeTextView (
).
. 2.16.
TextView
. 2.17.
ImageView
2. Resource Chooser
(. 2.18), . , drawable, IDE
( ),
.
2.5. 95
, android.png
android. android
OK, .
,
.
96 2 Welcome
. 2.19.
2.6. Welcome
AVD , 1.9.1. . 2.20
Nexus 4 AVD, .
(
). AVD
( ),
. , ,
, .
1.9.3,
Android. AVD
2.7. 97
, .
, , ,
, ; , .
2.7.
Android ,
. Android TalkBack ( ,
), . Explore by Touch, , .
TalkBack, ,
, . Android
98 2 Welcome
. , TalkBack
,
TextView, TalkBack . TalkBack
Settings ( Accessibility).
Android ,
(,
). , TalkBack AVD, , TalkBack
, . TalkBack Android
TalkBack Explore by Touch.
TalkBack ImageView
Welcome TextView,
TalkBack TextView. ImageView
, ,
. Android TalkBack
Content Description , .
IDE ,
( ) ImageView. ( Android Lint) ,
Content Description .
.
ImageView .
Content Description ImageView
( Android Lint), .
1. droidImageView .
2. Content
Description, Resource Chooser.
3. New String, Create New Android String.
4. String "Android logo", R.string android_logo.
OK.
5. android_logo Resource
Chooser. OK, Content
Description droidImageView.
6. bugImageView,
Create New Android String String "Deitel double-thumbs-up bug
logo", R.string "deitel_logo". .
Content Description ImageView
( ) ImageView.
2.8. 99
TalkBack
TalkBack. TextView ImageView
.
.
.
Android Android ,
:
http://developer.android.com/design/patterns/accessibility.html
http://developer.android.com/guide/topics/ui/accessibility/index.html
http://developer.android.com/guide/topics/ui/accessibility/checklist.html
2.8.
, Android . , ,
. ,
, (, ..) .
, .
. , Android ,
.
( ) , ,
XML .
, . Android
, .
XML- , ,
res . Android
, values-fr strings.xml
100 2 Welcome
, values-es strings.xml .
, valuesen-rUS values-en-rGB strings.xml ,
, .
, Android
( values res).
.
Welcome strings.
xml, ,
values-es. :
1. Package Explorer res
NewFolder, New Folder.
2. Folder name: values-es. Finish.
, ,
values-XX.
strings.xml values-es
strings.xml values values-es.
:
1. Package Explorer values res,
strings.xml Copy.
2. values-es Paste,
strings.xml.
TextView,
, ImageView ,
.
strings.xml. strings.xml.
, , .
, Google Play Developer Console (
Google Play) ,
.
Google Play Developer Console
9
developer.android.com/distribute/googleplay/publish/index.html
2.8. 101
"Welcome to Android App Development!"
"Android logo"
"Deitel double-thumbs-up bug logo"
"Bienvenido al Desarrollo de App Android!"
"Logo de Android"
"El logo de Deitel que tiene el insecto con dedos pulgares hacia arriba"
:
1. Package Explorer strings.xml valueses, Android. welcome (. 2.21).
102 2 Welcome
5. app_name, action_settings hello_world,
Remove.
. strings.xml
.
app_name. , .
6. strings.xml FileSave
.
, Android ( ).
1. Home (
2. (
( ).
) .
), Settings
3. Settings PERSONAL,
Language & input.
4. Language ( )
Espaol (Espaa).
2.8. 103
. 2.22. Welcome
AVD Nexus 4
AVD ( )
AVD ( ) :
1. Home (
) .
2. ( ), Settings
( ) Ajustes.
3. Idioma y entrada de texto, .
4. Idioma English (United States).
TalkBack
TalkBack , ,
, .
Welcome TalkBack,
TalkBack .
TalkBack,
Android . TalkBack
104 2 Welcome
, , . .
Android Localization Checklist :
developer.android.com/distribute/googleplay/publish/localizing.html
2.9.
Android Developer Tools IDE
Welcome app, - .
.
TextView,
ImageView. TextView , ,
. ImageView
. ,
res .
, . ,
TalkBack , . Android
Explore by Touch , TalkBack
.
ImageView ,
TalkBack Explore by Touch.
, Android
, .
Welcome TextView
ImageView,
AVD, .
Android Java.
Tip Calculator ;
, Java .
TipCalculator
106 3 TipCalculator
3.1.
Tip Calculator (. 3.1, ) .
( 15% ).
0% 30% ( 18%).
Seekbar,
, Seekbar (.
3.1, ). 18%,
,
. . 3.1
- Android
AVD ,
.
. 3.1. :
; 34,56
20%
. ,
.
108 3 TipCalculator
Seekbar 0
100, 30.
3.3.
Java Android,
Tip Calculator. ,
- Java. ,
:
Android ;
Android;
;
Android Activity,
Tip Calculator;
3.3.1. Activity
Java, Android main.
(activities), (services),
(broadcast receivers). , Activity ( android.app).
(views), GUI.
Android 3.0 . 5,
(fragments).
, .
,
.
3.3.2.
( ),
. :
3.3. 109
.
,
(, ).
,, -
, . , .
Android
(
Activity):
http://developer.android.com/reference/android/app/Activity.html
onCreate. Android
,
. : onStart, onPause, onRestart, onResume, onStop
onDestroy. .
; .
,
Activity , ,
.
3.3.3.
LinearLayout GridLayout
(layouts)
. LinearLayout ( android.widget)
( ), , .
TextView ,
.
GridLayout ( android.widget) Android 4.0
. ,
. GridLayout
TableLayout,
;
TableRow,
TableRow. GridLayout API
14 . Android Support Library
110 3 TipCalculator
GridLayout
, Android. , ,
http://developer.android.com/tools/support-library/index.html
GridLayout ,
. TextView
LinearLayout.
TextView GridLayout , .
http://developer.android.com/reference/android/widget/package-summary.html
3.3.4.
TextView, EditText SeekBar
IDE (. 2) Outline,
IDE Outline
.
XML-, res .
EditText ( )
TextView (. 2);
, . EditText ,
.
SeekBar ( 0100).
,
. SeekBar , 0 30.
, (. 3.2).
. , TextView
View,
TextView , TextView,
View , View.
3.3. 111
. 3.2. TextView
3.3.5.
NumberFormat ( java.text)
. , 2.72.8,
.
3.3.6. TextWatcher
EditText
TextWatcher ( android.text),
EditText . ,
onTextChanged , ,
.
112 3 TipCalculator
3.3.7. OnSeekBarChangeListener
SeekBar
SeekBar.OnSeekBarChangeListener ( android.
widget), SeekBar. ,
onProgressChanged ,
SeekBar.
3.3.8. AndroidManifest.xml
AndroidManifest.xml . ,
New Android Application: , ,
SDK, , .. (Android Manifest editor) ,
,
. ,
( ).
3.4.
Tip
Calculator.
, .3.1.
, , IDE.
3.4.1. GridLayout
GridLayout (. 3.3) GUI . GridLayout
, , , .
, .
GridLayout .
.
.
3.4. 113
. , . GridLayout
. GridLayout
http://developer.android.com/reference/android/widget/GridLayout.html
Id
.3.4 Id .
Id
Java.
amountDisplayTextView amountEditText,
. ,
, .
114 3 TipCalculator
.
100,
amountDisplayTextView.
3456 amountDisplayTextView
$0.03, $0.34, $3.45 $34.56.
Id LinearLayout
.3.5 Id
LinearLayout GridLayout.
. 3.5. LinearLayout Id
3.4.2. TipCalculator
Android Developer Tools
,
, TipCalculator, 3.2.
Delete. , Delete project contents on
disk , OK. ,
,
.
Android. New Android
Project , Next>:
Application Name: Tip Calculator
Project Name: TipCalculator
Package Name: com.deitel.tipcalculator
3.4. 115
3.4.3. GridLayout
Blank App RelativeLayout. GridLayout.
TextView Outline
Delete, . RelativeLayout Outline Change
Layout. Change Layout GridLayout OK.
GridLayout1. gridLayout Id .
Orientation GridLayout horizontal; ,
( ).
GridLayout
116 3 TipCalculator
3.4. 117
EditText (, , , , ).
EditText, ,
EditText. EditText , .
Text Fields Number EditText ( 42)
gridLayout Outline. Id EditText
amountEditText. EditText
GridLayout.
3. Medium TextView gridLayout Outline
Id amountDisplayTextView.
TextView GridLayout.
GridLayout ,
Row Column TextView ( Layout Parameters
) 0 1 .
2:
GridLayout TextView SeekBar. :
1. Medium TextView (customPercentTextView) Form
Widgets gridLayout Outline.
2. SeekBar (customTipSeekBar) Form Widgets
gridLayout Outline.
3:
GridLayout LinearLayout TextView.
1. Linear Layout (Horizontal) (percentLinearLayout)
gridLayout Outline.
2. Medium TextView (percent15TextView) percentLinear
Layout Outline. TextView
LinearLayout.
3. Medium TextView (percentCustomTextView)
percentLinearLayout Outline.
4. percentLinearLayout TextView GridLayout.
, percentLinearLayout Outline
Column 1.
4:
GridLayout TextView LinearLayout,
TextView:
118 3 TipCalculator
1. Medium TextView (tipTextView) gridLayout
Outline.
2. Linear Layout (Horizontal) (tipLinearLayout) gridLayout.
3. Medium TextView (tip15TextView tipCustomTextView)
tipLinearLayout.
5:
, 4, Id: totalTextView, totalLinearLayout, total15TextView
totalCustomTextView.
Outline .3.6.
Outline 3.4.5.
. 3.6. Outline
GridLayout: a ; Outline
Tip Calculator
3.4.5.
, ,
. 2.5,
strings.xml.
, (, ,
..), dimens.xml.
3.4. 119
6:
amountTextView, customPercentTextView,
percent15TextView, percentCustomTextView, tipTextView totalTextView:
1. amountTextView Outline.
2. Text.
3. Resource Chooser New String.
4. Create New Android String Amount String
amount New R.string, OK.
5. Resource Chooser OK, Text amountTextView amount.
TextView, . 3.1.
3.1.
String
New R.String
customPercentTextView
Custom %
custom_tip_percentage
percent15TextView
15%
fifteen_percent
percentCustomTextView
18%
eighteen_percent
tipTextView
Tip
tip
totalTextView
Total
total
7: TextView
. 3.3 TextView .
amountTextView, customPercentTextView, tipTextView totalTextView
Gravity ( Layout Parameters )
right.
8: Label For amountTextView
, EditText TextView
, EditText ( ) Android Lint
. , Id
EditText Label For TextView.
amountTextView Label For ( View ) @+id/amountEditText.
+ , TextView
EditText, EditText
XML- .
120 3 TipCalculator
9: amountEditText
amountEditText amountDisplayTextView
, .
amountEditText .
1. Layout Parameters Width Height
wrap_content. , EditText
, .
2. Gravity (fill_horizontal),
. fill_horizontal .
3. Ems, EditText ,
M ( ) .
GridLayout ,
.
4. TextView Digits 0123456789
,
, , . ,
Digits ,
. ,
Show Advanced Properties ( ) .
5. ,
, , 9999,99. TextView
Max Length 6.
10: amountDisplayTextView
amountDisplayTextView,
.
1. Layout Parameters Width Height
wrap_content. , TextView
.
2. Text .
3. Layout Parameters Gravity fill_
horizontal. , TextView
GridLayout.
4. View Background @android:color/holo_blue_
bright. ( @android:color) Android Holo.
Background,
. ,
, RGB.
3.4. 121
0255.
( 16),
RGB 00FF. Android
- ( ) 0 (
) 255 ( ). -, #AARRGGBB,
(AA) -.
, #RGB #ARGB. , #9AC #99AACC,
#F9AC #FF99AACC.
5. TextView.
textview_padding,
GUI. Padding . View
Padding. New
Dimension, . Name
textview_padding, Value 8dp, OK.
OK.
11: customPercentTextView
: customPercentTextView
customTipSeekBar. ,
. Layout Parameters
Gravity right right|center_vertical.
(|) Gravity
, TextView , . Width
Height customPercentTextView wrap_content.
12: customTipSeekBar
, SeekBar
0 100, Progress.
0 30, 18.
Max SeekBar 30, Progress
18. Width Height wrap_content.
13: percent15TextView percentCustomTextView
, GridLayout
. percent15TextView percentCustomTextView LinearLayout, . Weight
( , LinearLayout) (
) . ,
Weight.
122 3 TipCalculator
Weight, 1, percent15TextView
percentCustomTextView , ,
, . ,
percentLinearLayout GridLayout Gravity
fill_horizontal,
. LinearLayout ,
TextView LinearLayout.
, TextView
. Gravity ( TextView )
center. TextView,
Gravity .
14: tip15TextView, tipCustomTextView,
total15TextView totalCustomTextView
TextView
.
1. TextView.
2. Text .
3. Background @android:color/holo_orange_light.
4. Gravity center.
5. Weight 1.
6. Width 0dp
Weight .
7. Gravity TextView center.
8. Padding TextView @dimen/textview_padding
(, ).
TextView tipLinearLayout totalLinearLayout. ,
8dp tip15TextView total15TextView. Layout Parameters Margin Right
8dp; textview_margin. Right total15TextView.
15: tipTextView
totalTextView
tipTextView
totalTextView , Gravity right right|center_vertical.
3.5. 123
totalTextView, GridLayout
. Space ( Layout
) gridLayout Outline. , . , Space
.
, .3.7.
. 3.7.
3.5.
MainActivity ( 3.13.8)
Tip Calculator. 15% ,
. ,
src/com.deitel/tipcalculator MainActivity.java.
3.13.8.
package import
3.1 package import MainActivity.java.
package 3 . Java , import
. ,
import.
3.1. package import MainActivity
1
2
3
4
5
6
7
8
9
10
// MainActivity.java
// 15% .
package com.deitel.tipcalculator;
import java.text.NumberFormat; //
import
import
import
import
android.app.Activity; //
android.os.Bundle; //
android.text.Editable; // EditText
android.text.TextWatcher; // EditText
124 3 TipCalculator
11
12
13
14
15
import
import
import
import
android.widget.EditText; //
android.widget.SeekBar; // %
android.widget.SeekBar.OnSeekBarChangeListener; // SeekBar
android.widget.TextView; //
514 , :
NumberFormat java.text ( 5)
(,
).
Activity android.app ( 7)
Bundle android.os ( 8) -
. Android , (,
).
, , ( ,
), (
, ).
, ,
,
.
Editable android.text ( 9) -
EditText.
android.widget ( 1114) (
) , Android.
EditText ( 11), SeekBar ( 12)
TextView ( 14).
SeekBar.OnSeekBarChangeListener android.widget (-
13) ,
SeekBar.
SourceOrganize Imports ,
import .
, import.
Tip Calculator
MainActivity ( 3.23.8) Activity
Tip Calculator. Tip Calculator
3.5. 125
2032 3.3 MainActivity. NumberFormat ( 2023)
. getCurrencyInstance
NumberFormat NumberFormat,
, . getPercentInstance
.
3.3. MainActivity
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//
private static final NumberFormat currencyFormat =
NumberFormat.getCurrencyInstance();
private static final NumberFormat percentFormat =
NumberFormat.getPercentInstance();
private
private
private
private
private
private
private
private
, amountEditText,
double billAmount ( 25). ( 030),
Seekbar, 0,01; double
customPercent (26).
, SeekBar 25, customPercent 0,25,
0,25 25% .
126 3 TipCalculator
27 TextView ,
. 28
TextView , SeekBar (18% . 3.1, ). 2932
TextView,
.
onCreate Activity
onCreate (. 3.4) .
onCreate Activity
GUI. ,
. ,
, ANR (Application Not
Responding, ).
. ,
, 8.
3.4. onCreate Activity
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
//
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState); //
setContentView(R.layout.activity_main); // GUI
// TextView,
// MainActivity
amountDisplayTextView =
(TextView) findViewById(R.id.amountDisplayTextView);
percentCustomTextView =
(TextView) findViewById(R.id.percentCustomTextView);
tip15TextView = (TextView) findViewById(R.id.tip15TextView);
total15TextView = (TextView) findViewById(R.id.total15TextView);
tipCustomTextView = (TextView) findViewById(R.id.tipCustomTextView);
totalCustomTextView =
(TextView) findViewById(R.id.totalCustomTextView);
// GUI billAmount customPercent
amountDisplayTextView.setText(
currencyFormat.format(billAmount));
updateStandard(); // TextView 15%-
updateCustom(); // TextView
// TextWatcher amountEditText
EditText amountEditText =
(EditText) findViewById(R.id.amountEditText);
amountEditText.addTextChangedListener(amountEditTextWatcher);
// OnSeekBarChangeListener customTipSeekBar
3.5. 127
65
66
67
68
69
SeekBar customTipSeekBar =
(SeekBar) findViewById(R.id.customTipSeekBar);
customTipSeekBar.setOnSeekBarChangeListener(customSeekBarListener);
} // onCreate
Bundle onCreate
,
.
.
onCreate Bundle
Activity ( ). , onPause
onSaveInstanceState ( ). 38 onCreate ;
onCreate.
R
(, strings.xml activity_main.
xml) R,
, res . R
gen , . ,
R.. . , R, static final int,
(
, ). , R:
drawable drawable (,
), drawable res.
id ( ),
XML-.
layout ,
(, activity_main.xml).
string ,
strings.xml.
setContentView ( 39) R.layout.activity_main,
XML- MainActivity,
main.xml. setContentView
XML, .
(inflating) .
128 3 TipCalculator
,
. findViewById Activity.
int, ,
. R.id Id,
. ,
amountEditText R.id.amountEditText.
4351 TextView, .
4344 amountDisplayTextView,
. 4546
percentCustomTextView,
. 4751 TextView,
.
TextView
5455 amountDisplayTextView billAmount (0.00),
( format
currencyFormat). 5657 updateStandard (
3.5) updateCustom ( 3.6)
TextView.
6061 amountEditText , 62 addTextChangedListener
TextChangedListener, ,
EditText. ( 3.8)
,
amountEditTextWatcher.
6566 customTipSeekBar, 67
setOnSeekBarChangeListener
OnSeekBarChangeListener, ,
customTipSeekBar . ( 3.7) ,
customSeekBarListener.
updateStandard MainActivity
updateStandard ( 3.5) TextView
15% , . billAmount
. 7879
.
3.5. 129
// TextView 15%
private void updateStandard()
{
// 15%
double fifteenPercentTip = billAmount * 0.15;
double fifteenPercentTotal = billAmount + fifteenPercentTip;
// 15%
tip15TextView.setText(currencyFormat.format(fifteenPercentTip));
total15TextView.setText(currencyFormat.format(fifteenPercentTotal));
} // updateStandard
updateCustom MainActivity
updateCustom ( 3.6) TextView , customTipSeekBar,
. 86
percentCustomTextView customPercent,
. 8990 customTip
customTotal, 9394
.
3.6. updateCustom
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// TextView
private void updateCustom()
{
// percentCustomTextView
customPercent %
percentCustomTextView.setText(percentFormat.format(customPercent));
//
double customTip = billAmount * customPercent;
double customTotal = billAmount + customTip;
//
tipCustomTextView.setText(currencyFormat.format(customTip));
totalCustomTextView.setText(currencyFormat.format(customTotal));
} // updateCustom
,
OnSeekBarChangeListener
98120 3.7
customSeekBarListener, customTipSeekBar.
, :
http://bit.ly/AnonymousInnerClasses
130 3 TipCalculator
67 ( 3.4) customSeekBarListener OnSeekBarChangeListener customTipSeekBar.
,
, onCreate .
3.7. ,
OnSeekBarChangeListener customSeekBar
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
// SeekBar
private OnSeekBarChangeListener customSeekBarListener =
new OnSeekBarChangeListener()
{
// customPercent, updateCustom
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser)
{
// customPercent SeekBar
customPercent =
progress / 100.0;
updateCustom(); // TextView
} // onProgressChanged
@Override
public void onStartTrackingTouch(SeekBar seekBar)
{
} // onStartTrackingTouch
@Override
public void onStopTrackingTouch(SeekBar seekBar)
{
} // onStopTrackingTouch
}; // OnSeekBarChangeListener
onProgressChanged
OnSeekBarChangeListener
102119 OnSeekBarChangeListener.
onProgressChanged SeekBar.
107 customPercent progress
int, SeekBar.
100. 108
updateCustom .
onStartTrackingTouch onStopTrackingTouch
OnSeekBarChangeListener
Java
. , (onStartTrackingTouch)
(onStopTrackingTouch),
( 111119), .
3.5. 131
, TextWatcher
123156 3.8
amountEditTextWatcher, amountEditText. 62
amountEditText,
.
3.8. ,
amountEditText
122 // , amountEditText
123 private TextWatcher amountEditTextWatcher = new TextWatcher()
124 {
125 // ,
126 @Override
127 public void onTextChanged(CharSequence s, int start,
128 int before, int count)
129 {
130 // amountEditText double
131 try
132 {
133 billAmount = Double.parseDouble(s.toString()) / 100.0;
134 } // try
135 catch (NumberFormatException e)
136 {
137 billAmount = 0.0; //
138 } // catch
139
140 // display currency formatted bill amount
141 amountDisplayTextView.setText(currencyFormat.format(billAmount));
142 updateStandard(); //
143 updateCustom(); //
144 } // onTextChanged
145
146 @Override
147 public void afterTextChanged(Editable s)
148 {
149 } // afterTextChanged
150
151 @Override
152 public void beforeTextChanged(CharSequence s, int start, int count,
153 int after)
154 {
155 } // beforeTextChanged
156 }; // amountEditTextWatcher
157 } // MainActivity
onTextChanged TextWatcher
onTextChanged ( 126144) ,
amountEditText. .
CharSequence s, amountEditText. ,
132 3 TipCalculator
, count,
start, before.
133 , amountEditText, double. ,
100 , 2495, 24,95.
142143 updateStandard updateCustom
.
amountEditTextWatcher
,
(beforeTextChanged) (afterTextChanged),
TextWatcher
( 146155), .
3.6. AndroidManifest.xml
AndroidManifest.xml, , ,
.
.
(Android Manifest editor),
AndroidManifest.xml Package Explorer.
Application (. 3.8), MainActivity Application
Nodes . MainActivity Attributes
for com.deitel.tipcalculator.MainActivity.
MainActivity
,
. .
. Tip
Calculator
,
. MainActivity , . Attributes for com.deitel.
tipcalculator.MainActivity Screen orientation
portrait.
MainActivity
Tip Calculator
.
Attributes for com.deitel.tipcalculator.MainActivity Window
3.7. 133
. 3.8. Application
soft input mode stateAlwaysVisible. ,
3.7.
Android Tip Calculator.
134 3 TipCalculator
,
.
Android Developer Tools,
Outline . MainActivity Activity,
.
GridLayout GUI .
TextView,
EditText SeekBar.
MainActivity -
Java, , , , . ,
XML . Android Activity
. , onCreate
. onCreate findViewById
Activity ,
.
, TextWatcher,
EditText.
,
OnSeekBarChangeListener,
SeekBar.
, AndroidManifest.xml , , MainActivity ,
MainActivity .
, Outline, ,
XML AndroidManifest.xml.
Twitter Searches. .
ListActivity,
ListView, ArrayList<String>.
-.
Twitter Searches
4.1.
, 500 .
(. 4.2),
, ,
. Twitter Searches
(. 4.1)
, () (.4.1,).
,
(.4.1, ). ,
, .
, .
. ,
GUI .
, , . .
, .
4.2. 137
4.2.
Twitter Searches .
Android Developer Tools Twitter
Searches. 3, Nexus 4 AVD (
Android ) . , , Nexus 4.
4.2.1.
.
1. Import FileImport
2. Twitter Searches. General
Existing Projects into Workspace, Next > Import Projects. Select root directory,
Browse. TwitterSearches, ,
OK. , Copy projects into
workspace . Finish .
Package Explorer.
3. Twitter Searches.
TwitterSearches Package Explorer Run AsAndroid
Application AVD.
(.4.2).
4.2.2.
EditText from:deitel
from: .
.4.1 ;
.
http://bit.ly/TwitterSearchOperators.
4.1. T
deitel iOS6
, deitel iOS6
deitel OR iOS6
,
deitel iOS6 ( )
how to program
, (how to program)
deitel ?
deitel
,
deitel -sue
, deitel,
sue
deitel :)
:) , deitel
deitel :(
:( , deitel
since:2013-10-01
,
( --)
from:deitel
@deitel
to:deitel
, @deitel
4.2. 139
, Deitel Tagged
Searches (. 4.3, ). ,
, , ,
4.5.5.
. 4.3. : ( );
4.2.3.
, Deitel. , URL-,
. URL , ( ), -.
(. 4.4). ,
Back (
), Twitter Searches,
, ,
.
. 4.4.
4.2.4.
, .
, (
). AVD, , .
Deitel AlertDialog (. 4.5, ) Share,
Edit Delete Deitel.
, Cancel.
Deitel, Edit .
EditText .
, 1 2013 ,
since:2013-10-01 (. 4.5, ) EditText. since: ,
4.2. 141
. 4.5. : Edit
;
Deitel
( --). , ,
(. 4.6), Deitel Tagged Searches .
[:
.]
4.2.5.
Android
, (SMS),
Facebook, Google+ ..
Share AlertDialog. (. 4.7,),
,
. 4.6. Deitel
. , ( AVD!)
, : Facebook, Gmail, Google+, Messaging
( ) Twitter.
, .
,
. . 4.7,
Compose Gmail .
Gmail To (
).
4.2.6.
,
AlertDialog Delete.
(. 4.8) Cancel
, Delete .
4.2. 143
. 4.7. : a
; Compose Gmail
. 4.8. AlertDialog
4.2.7.
. 4.9 10 ,
.
, .
ListView (. 4.3.1). , ( AVD) Tagged Searches.
,
.
. 4.9. ,
4.3.
, .
4.3.1. ListView
. , ; ;
.. ,
, , ..
ListView ( android.widget)
, , .
ListView;
TextView. , ListView
, .
4.3. 145
4.3.2. ListActivity
, ListActivity ( android.app).
, ListView
. ListView AdapterView ( android.widget)
GUI, Adapter (
android.widget). ArrayAdapter ( android.widget)
, ListView
ArrayList. (data
binding). AdapterView,
Adapter. 8 ListView . Android
http://developer.android.com/guide/topics/ui/binding.html
4.3.3. ListActivity
ListActivity
ListView ,
Android (. . 2.1).
ListActivity ListView, ListActivity subclass.
MainActivity Twitter Searches
, MainActivity . ListActivity
ListView, Id "@android:id/
list" , ListActivity ListView.
4.3.4. ImageButton
,
.
ImageButton ( android.widget). ImageButton ImageView ,
Button ( android.widget) .
4.3.5. SharedPreferences
,
/ ( ). searches,
4.3.6.
(
) Android (intents). , ,
.
AndroidManifest.xml. , , ,
; , android.intent.action.MAIN, ,
.
,
.
, , URL-, . ,
Intent URL
startActivity,
Activity. URL startActivity
.
Intent startActivity , .
, ,
.
, , (im
plicit) -,
Android
4.3. 147
. , startActivity,
, ,
. , startActivity
ActivityNotFoundException.
. ,
Android, , , -.
,
.
http://developer.android.com/guide/components/intents-filters.html
4.3.7. AlertDialog
AlertDialog ,
. ,
.
,
AlertDialog.Builder,
AlertDialog.
AlertDialog , , ,
.
AlertDialog ,
.
(
).
, .
(
OK ).
, .
, -
, . , ,
, .
AlertDialog .
, EditText -
. .
, .
Delete).
Android
http://developer.android.com/guide/topics/ui/dialogs.html
4.3.8. AndroidManifest.xml
3, AndroidManifest.xml
. ,
. AndroidManifest.xml
http://developer.android.com/guide/topics/manifest/manifest-intro.html
4.4.
Twitter Searches.
XML; ListView .
4.4.1.
, Android Developer Tools IDE ,
TwitterSearches, 4.2.
Delete. ,
Delete project contents
on disk, OK. , ,
.
C Android Application Project.
New Android Project (New Android Application)
Next>:
Application Name: Twitter Searches
Project Name: TwitterSearches
4.4. 149
4.4.2. activity_main.xml
3, activity_main.xml
GridLayout (. 4.10). GridLayout
. .4.11 GUI.
4.4.3. GridLayout
. 4.104.11 ,
3. ,
. ,
GUI Outline.
,
.
GridLayout Outline. GUI,
. 4.11;
,
Java. ,
strings.xml ( res/values).
1: RelativeLayout GridLayout
3.4.3, TextView
RelativeLayout GridLayout.
2: GridLayout
Outline GridLayout
, ,
:
4.4. 151
Id: @+id/gridLayout
Column Count ( GridLayout): 1 GUI, -
GridLayout, .
GridLayout ,
Width Height ( Layout Parameters
) match_parent.
Padding Left Padding Right
@dimen/activity_horizontal_margin
dimens.xml res/values . 16dp,
GridLayout 16dp.
.
Padding Top Padding Bottom @dimen/activity_vertical_
margin 16dp. ,
GridLayout 16dp.
4.1
Android 16dp ;
(, ) .
3: GridLayout
EditText. Plain Text
Text Fields GridLayout Outline,
Id @+id/queryEditText. TextView
Ems, .
, :
Width ( Layout Parameters): wrap_content
Height ( Layout Parameters): wrap_content
Gravity ( Layout Parameters): fill_horizontal ,
queryEditText .
Gravity ,
, .
Hint: @string/queryPrompt ( -
.
EditText,
EditText, .
4: GridLayout
LinearLayout EditText Image
Button. ,
.
1. LinearLayout (Horizontal) Layouts
GridLayout Outline.
2. Plain Text Text Fields LinearLayout
Id @+id/tagEditText.
3. ImageButton Images & Media
LinearLayout. Resource Chooser (. 4.12),
.
Project Resources,
( res/drawable ).
Android
( . 4.12). , System
Resources, ic_menu_save OK. Id
@+id/saveButton.
tagEditText Ems,
. .
Width ( Layout Parameters): 0dp
, Weight,
.
Height ( Layout Parameters): wrap_content.
Gravity ( Layout Parameters): bottom|fill_horizontal
tagEditText saveButton , tagEditText
.
4.4. 153
, saveButton . Android ,
saveButton , tagEditText
.
5: GridLayout
LinearLayout TextView ListView.
, :
LinearLayout :
Height ( Layout Parameters): 0dp
Gravity.
Android .
, LinearLayout,
16dp.
, LinearLayout,
16dp.
TextView
:
Width ( Layout Parameters): match_parent.
Height ( Layout Parameters): wrap_content.
Gravity ( Layout Parameters): fill_horizontal TextView
LinearLayout ( ).
4.4. 155
, LinearLayout,
16dp.
ListView .
Width ( Layout Parameters): match_parent.
Height ( Layout Parameters): 0dp
, Weight,
.
, LinearLayout,
16dp.
4.4.4.
MainActivity . (. 4.13) ,
,
. ,
,
Preview Representative Sample Preview All Screen Sizes.
+ ,
. . 4.2
.
. 4.13.
4.2.
Android
, ,
,
.
Nexus
4,
Nexus
7
Nexus
10 ( ). . 4.13 Nexus 4
Activity
Fragment
,
(. 2.8) , ,
API
API
.
API
. ,
API
4.4. 157
. 4.14.
Android,
.
4.4
Android ,
, , 4848 dp.
http://developer.
android.com/design/style/metrics-grids.html.
ListView.
, .
,
,
, ;
android:id.
Android
Android ,
Height Text Appearance .
http://developer.android.com/reference/android/R.attr.html
, ?android:attr/
.
4.5. MainActivity
4.14.10 Twitter Searches
MainActivity, ListActivity. MainActivity
onCreateOptionsMenu, , , onCreateOptionsMenu 5.
, String
, .
4.5. MainActivity159
// MainActivity.java
//
//
package com.deitel.twittersearches;
import java.util.ArrayList;
import java.util.Collections;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
android.app.AlertDialog;
android.app.ListActivity;
android.content.Context;
android.content.DialogInterface;
android.content.Intent;
android.content.SharedPreferences;
android.net.Uri;
android.os.Bundle;
android.view.View;
android.view.View.OnClickListener;
android.view.inputmethod.InputMethodManager;
android.widget.AdapterView;
android.widget.AdapterView.OnItemClickListener;
android.widget.AdapterView.OnItemLongClickListener;
android.widget.ArrayAdapter;
android.widget.EditText;
android.widget.ImageButton;
android.widget.TextView;
MainActivity, ListView
.
, ,
OnClickListener.
, AlertDialog.
, ,
Android .
,
.
/ , .
, Intent, .
; GUI, .
,
ImageButton .
android.widget (2026) , -
4.5.2. ListActivity
MainActivity ( 4.24.10) -
4.5. MainActivity161
4.5.3. MainActivity
4.3 MainActivity ( ). SEARCHES ( 31)
, . 3334
EditText, .
35 savedSearches SharedPreferences; /,
.
36 ArrayList<String>
. 37
ArrayAdapter<String>, ArrayList<String>
, ListView MainActivity.
4.1
, String ( ), ( ,
strings.xml).
4.3. MainActivity
30
31
32
33
34
35
36
37
38
// XML- SharedPreferences
private static final String SEARCHES = "searches";
private
private
private
private
private
4.5.4. onCreate
onCreate ( 4.4) :
;
-
, ;
, -
, .
Activity GUI
, . 43 onCreate . , setContentView ( 44) R.layout.
activity_main activity_main.xml.
4.4. onCreate Activity
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
// MainActivity
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// EditText
queryEditText = (EditText) findViewById(R.id.queryEditText);
tagEditText = (EditText) findViewById(R.id.tagEditText);
// SharedPreferences
savedSearches = getSharedPreferences(SEARCHES, MODE_PRIVATE);
// ArrayList
tags = new ArrayList<String>(savedSearches.getAll().keySet());
Collections.sort(tags, String.CASE_INSENSITIVE_ORDER);
// ArrayAdapter ListView
adapter = new ArrayAdapter<String>(this, R.layout.list_item, tags);
setListAdapter(adapter);
//
ImageButton saveButton =
(ImageButton) findViewById(R.id.saveButton);
saveButton.setOnClickListener(saveButtonListener);
//
getListView().setOnItemClickListener(itemClickListener);
// ,
getListView().setOnItemLongClickListener(itemLongClickListener);
} // onCreate
4.5. MainActivity163
EditText
4748 queryEditText tagEditText
.
SharedPreferences
51 getSharedPreferences (
Context) SharedPreferences, SEARCHES ( , ).
.
; .
MODE_PRIVATE . -
MODE_WORLD_READABLE
MODE_WORLD_WRITABLE
(|).
,
onCreate.
4.1
UI, ANR (Application Not
Responding) ,
5 . , ,
http://developer.android.com/guide/practices/design/responsiveness.html.
SharedPreferences
, . 54 String, SharedPreferences, tags (ArrayList<String>).
getAll SharedPreferences
Map ( java.util) /.
keySet, Set
( java.util) .
tags.
55 Collections.sort .
, ,
(R.layout.list_item) , -
ListView.
List<String> ; tags
59 ListActivity setListAdapter
ListView ArrayAdapter, ListView .
saveButton ListView
6263 saveButton,
64 saveButtonListener ,
OnClickListener ( 4.5). 67 ListActivity
getListView ListView ,
OnItemClickListener ListView
itemClickListener
, ( 4.8).
70 OnItemLongClickListener
ListView itemLongClickListener , ( 4.9).
4.5.5. ,
OnClickListener
4.5 saveButton
Listener, ,
OnClickListener. 64 (4.4)
saveButtonListener saveButton. 76109 onClick OnClickListener.
( 8081), 8384 addTaggedSearch
4.5. MainActivity165
(4.7) , 8586
EditText. 8890 .
4.5. ,
OnClickListener saveButton
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
}
} // onClick
}; // OnClickListener
AlertDialog
/ , 92108
AlertDialog . AlertDialog.Builder (9596) AlertDialog.
, ,
MainActivity, this.
4.5
AlertDialog (
) setTitle AlertDialog.Builder.
Android (http://developer.android.
com/design/building-blocks/dialogs.html),
.
,
, , ... ,
, ,
.
strings.xml
(, R.string.missingMessage),
strings.xml res/values. , Resources strings.xml.
Resources Add . 4.15.
String OK, Name Value, (, missingMessage)
. strings.xml .
Resources ,
.
. 4.15.
4.5. MainActivity167
AlertDialog
AlertDialog ,
.
(. 4.14, 102) , , . setPositiveButton
( R.string.OK) .
, null.
, .
AlertDialog
AlertDialog create AlertDialog.Builder (
105), show AlertDialog
( 106).
4.5.6. addTaggedSearch
4.4 addTaggedSearch
MainActivity ( 4.6) savedSearches .
4.6. addTaggedSearch MainActivity
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//
private void addTaggedSearch(String query, String tag)
{
// SharedPreferences.Editor
SharedPreferences.Editor preferencesEditor = savedSearches.edit();
preferencesEditor.putString(tag, query); //
preferencesEditor.apply(); //
//
if (!tags.contains(tag))
{
tags.add(tag); //
Collections.sort(tags, String.CASE_INSENSITIVE_ORDER);
adapter.notifyDataSetChanged(); // ListView
}
SharedPreferences
SharedPreferences ,
edit, SharedPreferences.Editor
( 115). /,
/, ,
4.5.7. ,
OnItemClickListener
ListView
4.7 itemClick
Listener, ,
OnItemClickListener. 67 (4.4) itemClickListener ListView,
ListView. 131145
onItemClick OnItemClickListener. :
AdapterView, . ? AdapterView<?>
Java, ,
onItemClick AdapterView ListView<String>.
View, AdapterView,
TextView .
, (
!)
, ,
,
(.8).
4.7. ,
OnItemClickListener ListView
128
129
130
// itemClickListener
OnItemClickListener itemClickListener = new OnItemClickListener()
{
4.5. MainActivity169
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id)
{
// URL-
String tag = ((TextView) view).getText().toString();
String urlString = getString(R.string.searchURL) +
Uri.encode(savedSearches.getString(tag, ), UTF-8);
//
Intent webIntent = new Intent(Intent.ACTION_VIEW,
Uri.parse(urlString));
startActivity(webIntent); //
}
}; // itemClickListener
136 View ,
ListView. 137138 , URL-
. 137
Activity getString
searchURL, URL- :
http://mobile.twitter.com/search/
, ,
strings.xml.
SharedPreferences
138 URL-
urlString. getString SharedPreferences ,
. , ("" ). 138 encode Uri,
URL (, ?, /, : ..)
URL. , -,
, URL- .
141142 Intent,
.
. Intent
. Intent.ACTION_VIEW ,
. Intent , , , .
(142) Uri (Uniform Resource Identifier),
4.5.8. ,
OnItemLongClickListener ListView
,
4.8 itemLong
ClickListener, ,
OnItemLongClickListener. 70 (4.4) itemLongClickListener ListView,
ListView. 153210 onItemLongClick OnItemLongClickListener.
4.8. ,
OnItemLongClickListener ListView ,
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
// itemLongClickListener
//
OnItemLongClickListener itemLongClickListener =
new OnItemLongClickListener()
{
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id)
{
// ,
final String tag = ((TextView) view).getText().toString();
// AlertDialog
AlertDialog.Builder builder =
new AlertDialog.Builder(MainActivity.this);
// AlertDialog
builder.setTitle(
getString(R.string.shareEditDeleteTitle, tag));
//
builder.setItems(R.array.dialog_items,
new DialogInterface.OnClickListener()
4.5. MainActivity171
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
// ,
//
@Override
public void onClick(DialogInterface dialog, int which)
{
switch (which)
{
case 0: //
shareSearch(tag);
break;
case 1: //
// EditText
tagEditText.setText(tag);
queryEditText.setText(
savedSearches.getString(tag, ""));
break;
case 2: //
deleteSearch(tag);
break;
}
}
} // DialogInterface.OnClickListener
); // builder.setItems
// AlertDialog
builder.setNegativeButton(getString(R.string.cancel),
new DialogInterface.OnClickListener()
{
// "Cancel"
public void onClick(DialogInterface dialog, int id)
{
dialog.cancel(); // AlertDialog
}
}
); // setNegativeButton
builder.create().show(); // AlertDialog
return true;
} // onItemLongClick
}; // OnItemLongClickListener
158 ,
, tag final. ,
, final.
AlertDialog
161166 AlertDialog.Builder, , tag
4.5.9. shareSearch
shareSearch (4.9) 4.8,
. 217218
4.5. MainActivity173
String, . 221227 Intent URL- ,
Intent.ACTION_SEND (222).
// URL-
private void shareSearch(String tag)
{
// URL-,
String urlString = getString(R.string.searchURL) +
Uri.encode(savedSearches.getString(tag, ""), "UTF-8");
// Intent urlString
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_SUBJECT,
getString(R.string.shareSubject));
shareIntent.putExtra(Intent.EXTRA_TEXT,
getString(R.string.shareMessage, urlString));
shareIntent.setType(text/plain);
//
startActivity(Intent.createChooser(shareIntent,
getString(R.string.shareSearch)));
Intent Bundle (extras),
Activity, . ,
, , CC BCC, . 223226
putExtra Intent / Bundle, Intent.
String, ,
. , , Bundle
putExtra Intent.
223224
R.string.shareSubject ("Twitter search that might interest you"). ,
(, ), . 225226
, urlString
R.string.shareMessage ("Check out the results of this Twitter
search: %s"). 227 MIME text/plain
, .
4.5.10. deleteSearch
4.8 deleteSearch (4.10),
Delete.
AlertDialog
. 241242 , tag
R.string.confirmMessage ("Are you sure you want to delete
the search \"%s\"?"). 245254 . R.string.cancel
"Cancel". 257275 . R.string.delete "Delete". 263
tags, 266269 SharedPreferences.Editor
SharedPreferences . 272
ArrayAdapter ,
ListView .
4.10. deleteSearch MainActivity
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
//
private void deleteSearch(final String tag)
{
// AlertDialog
AlertDialog.Builder confirmBuilder = new AlertDialog.Builder(this);
// AlertDialog
confirmBuilder.setMessage(
getString(R.string.confirmMessage, tag));
// AlertDialog
confirmBuilder.setNegativeButton(getString(R.string.cancel),
new DialogInterface.OnClickListener()
{
// "Cancel"
public void onClick(DialogInterface dialog, int id)
{
4.6. AndroidManifest.xml175
251
dialog.cancel(); //
252
}
253
}
254
); // setNegativeButton
255
256
// AlertDialog
257
confirmBuilder.setPositiveButton(getString(R.string.delete),
258
new DialogInterface.OnClickListener()
259
{
260
// "Cancel"
261
public void onClick(DialogInterface dialog, int id)
262
{
263
tags.remove(tag); // tags
264
265
// SharedPreferences.Editor
266
SharedPreferences.Editor preferencesEditor =
267
savedSearches.edit();
268
preferencesEditor.remove(tag); //
269
preferencesEditor.apply(); //
270
271
//
272
adapter.notifyDataSetChanged();
273
}
274
} // OnClickListener
275
); // setPositiveButton
276
277
confirmBuilder.create().show(); // AlertDialog
278
} // deleteSearch
279 } // MainActivity
4.6. AndroidManifest.xml
3.6 AndroidManifest.xml.
, Tip Calculator
, Tip Calculator.
, .
,
.
, Twitter Searches . GUI EditText,Android
. , EditText (
4.7.
Twitter Searches.
(GUI).
ListView,
. ListView,
. ,
Java.
SharedPreferences, . . SharedPreferences.Editor ,
SharedPreferences.
Uri- startActivity
Context. Intent
, .
AlertDialog.Builder
AlertDialog, . ,
AndroidManifest.xml , ,
.
5 Flag Quiz,
, ,
.
,
.
FlagQuiz
, , AssetManager, , ,
Activity
PreferenceFragment
assets
AssetManager
View
Handler
Toast
java.util
Android
178 5 FlagQuiz
5.1.
Flag Quiz 10
(. 5.1).
. ,
. ,
( ) TextView, . ,
: ,
, ,
.
, ,
,
.
Settings. ,
. (. 5.2)
, ,
.
, , . .
.
5.2.1.
, IDE:
1. Import. FileImport.
2. Flag Quiz. Import General Existing Projects into Workspace. Next > Import Projects. ,
180 5 FlagQuiz
Select root directory, Browse FlagQuiz
, OK. ,
Copy projects into workspace . Finish,
; Package Explorer.
3. Flag Quiz.
FlagQuiz Run AsAndroid Application,
AVD . (. 5.1 5.2).
5.2.2.
,
.
,
; ().
, AVD
( , . 5.1). Settings;
Flag Quiz Settings (. 5.3, ). AVD
(. 5.2). ,
(. 5.3, ), Number of Choices. (
AVD , .) ,
.
, 6 9 OK; , Cancel, Flag Quiz Settings.
.
Regions (. 5.4, ), , (. . 5.4, ).
,
. Africa, Asia, Europe, Oceania South America,
. OK,
. , AVD
Back (
), .
AVD
.
5.2.3.
,
.
, ( ) .
182 5 FlagQuiz
(. 5.5, ),
(.5.5, ).
.
. 5.5. : a ;
(. 5.6, ),
, , ,
Incorrect! (. 5.6, ). , .
,
, AlertDialog,
(. . 5.7). Reset
Quiz .
. 5.7.
184 5 FlagQuiz
5.3.
,
Flag Quiz.
5.3.1.
MainActivity ( ) .
Settings, . ,
,
.
Menu ( android.view).
Menu, onCreateOptionsMenu Activity
(5.5.4) Menu . , onOptionsItemSelected Activity (5.5.5) .
5.3.2.
(fragment) ,
.
.
,
. ,
(. 8).
Fragment ( android.app).
Flag Quiz Fragment (
).
QuizFragment ( 5.6) Fragment; -
. Activity
Fragment ,
, . QuizFragment 5.4.8.
MainActivity
.
android.preference),
5.3. 185
SharedP references . ,
XML- , Pre
ferenceFragment (. 5.35.4).
, QuizFragment
, DialogFragment ( android.
app), AlertDialog (5.6.9).
. , MainActivity . (
) SettingsActivity ( 5.8) SettingsFragment,
MainActivity .
Android 3.0, (
Android) Android Support Library.
http://developer.android.com/tools/support-library/index.html
5.3.3.
, ,
, .
.
onCreate ( SettingsFragment)
. QuizFragment SettingsFragment
, DialogFragment,
, .
onCreateView ( QuizFragment)
.
http://developer.android.com/guide/components/fragments.html
186 5 FlagQuiz
5.3.4.
FragmentManager ( android.app), getFragmentManager Activity. ,
Id,
findFragmentById
FragmentManager. 8, FragmentManager FragmentTransaction ( android.app)
, .
5.3.5. Preference
5.2.2 . PreferenceFragment
Preference ( android.preference)
. Preference ListPreference
, , Preference MultiSelectListPreference
, . ListPreference , MultiSelectListPreference
.
PreferenceManager ( android.preference).
5.3.6. assets
1 ,
. assets .
, assets
. images/FlagQuizImages
.
drawable,
, assets , (
). ,
assets, AssetManager
( android.content.res),
, assets,
.
- www.free-country-flags.com.
5.3. 187
5.3.7.
2.4.4 drawable, layout values,
res .
menu, anim xml.
.5.1 ( animator, color
raw).
5.1. , res
anim
,
anim
,
XML
- , ,
, .
5.4.11,
5.6.9,
animator
, animator, XML-
,
. Java
, set- get-
color
,
color
,
XML
- (, , , ..)
raw
, raw,
(, ),
. 6
menu
,
menu
,
XML
- . IDE
Settings
xml
, xml, XML-,
.
XML, .
5.4.10 XML ,
SettingsFragment
5.3.8.
2.5.1 , Android , (DPI, Dots Per Inch). ,
, Android . , 2.8 ,
188 5 FlagQuiz
. Android
,
. ,
5.3.7.
MainActivity
, .
, MainActivity :
activity_main.xml res/layout .
activity_main.xml res/layout-large-land
(, ), (land)
.
:
-
,
(-). 18 ,
. .
res
http://developer.android.com/guide/topics/resources/providing-resources.html#
AlternativeResources
5.3.9.
,
(5.5.4).
, Android WindowManager
( android.view) Display
.
.
5.3.10.
Toast ( android.widget ) ,
. Toast (,
5.3. 189
).
, Toast . Toast
,
,
.
5.3.11.
,
, . Handler ( android.os). postDelayed Handler Runnable .
Runnable
, Handler. ,
, GUI-,
GUI -.
5.3.12.
, , ImageView Animation ( android.view.animation).
loadAnimation AnimationUtils
XML-, . ( setRepeatCount Animation).
ImageView startAnimation
View ( Animation) ImageView.
5.3.13. Log.e
( )
Android . Android Log
( android.util) , .
LogCat IDE,
Android logcat.
-
http://developer.android.com/reference/android/util/Log.html
190 5 FlagQuiz
5.3.14.
, SettingsActivity (5.8). 4 ,
URL- . 5.5.5
,
.
5.3.15. Java
java.util.
ArrayList<String>. shuffle Collections
ArrayList<String> .
ArrayList<String> , 10 . Set<String>
.
ArrayList<String> List<String>
Java,
, .
5.4.
(, , ,
, ) Flag Quiz.
5.4.1.
, FlagQuiz, 5.2,
Delete. ,
Delete project contents on disk , OK.
Android Application Project.
New Android Project (New Android Application)
Next >:
5.4. 191
New Android Project (New Android Application) Next >. Configure Launcher Icon Browse ( images
), Open Next >. Create Activity Blank
Activity Next >. Blank Activity
Finish, .
Nexus 4 ,
.
5.4.2. strings.xml
,
(. 5.2). strings.xml res/values,
.
5.2. , Flag Quiz
settings_activity
number_of_choices
Number of Choices
number_of_choices_description
world_regions
Regions
world_regions_description
guess_country
results
incorrect_answer
Incorrect!
default_region_message
restarting_quiz
192 5 FlagQuiz
5.2 ()
ok
OK
question
reset_quiz
Reset Quiz
image_description
default_region
North_America
results question ,
format String. String , . results 1$ %1$d
format String ,
%1$d. 2$ %2$.02f
format ,
%2$.02f. d ,
, f
. strings.xml %1$d %2$.02f
. %1$d,
%2$.02f .
5.4.3. arrays.xml
4.5.8 strings.xml . res/values .
. ,
arrays.xml, colors.xml, strings.xml
values.xml.
, arrays.xml:
regions_list ,
,
SettingsFragment;
regions_list_for_settings , -
SettingsFragment
;
guesses_list 3, 6 9
SettingsFragment .
5.4. 193
.5.3 .
5.3. , arrays.xml
regions_list
regions_list_for_settings
guesses_list
3, 6, 9
, .
1. res values
NewAndroid XML File. New Android
XML File. values, Values values.
2. File arrays.xml Finish,
.
3. XML,
Resources , .
4. , Add,
String Array OK.
5. Name regions_list .
6. Add,
.5.3.
7. 46 regions_list_for_settings guesses_list
arrays. Add , Create
a new element at the top level in Resources.
5.4.4. colors.xml
,
. , , XML,
Java.
colors.xml, .
3.4.5, RGB ARGB.
,
.
1. res values NewAndroid XML File. New
Android XML File.
194 5 FlagQuiz
2. File colors.xml Finish,
.
3. XML, Resources ,
.
4. , Add, Color OK.
5. Name Value correct_answer #00CC00 ,
.
6. 4 5 incorrect_answer #FF0000.
5.4.5. dimens.xml
,
(. 5.4).
dimens.xml res/values,
. spacing GUI, answer_size
answerTextView. 2.5.3,
, (sp),
( ).
5.4. , Flag Quiz
spacing
8dp
answer_size
40sp
5.4.6. activity_settings.xml
SettingsActivity (5.8),
SettingsFragment (5.7). SettingsActivity
LinearLayout, SettingsFragment. ,
.
, .
1. res layout
NewAndroid XML File. New Android
5.4. 195
XML File. layout, Layout.
2. File activity_settings.xml.
3. Root Element LinearLayout Finish,
.
4. Layouts LinearLayout Outline.
5. Choose Fragment Class.
, .
Create New, New Java Class.
6. Name SettingsFragment
Superclass android.preference.PreferenceFragment. Finish,
. Java,
.
7. activity_settings.xml.
5.4.7. activity_main.xml
MainActivity ( 5.5), . 5.4.9.
( QuizFragment 5.6),
.
1. activity_main.xml res/layout.
2. Fragment Layouts RelativeLayout
Outline.
3. Choose Fragment Class Create New,
New Java Class.
4. Name QuizFragment Finish, .
Java,
.
5. activity_main.xml QuizFragment Outline. Id
@+id/quizFragment, Width Height Layout Parameters match_parent.
6. activity_main.xml.
196 5 FlagQuiz
5.4.8. fragment_quiz.xml
. (-) res/layout XML , .
SettingsFragment ,
PreferenceFragment.
QuizFragment (fragment_quiz.xml).
res/layout ,
. .5.8
QuizFragment.
fragment_quiz.xml
fragment_quiz.xml, .
1. res layout NewAndroid XML File. New
Android XML File.
2. File fragment_quiz.xml.
3. Root Element LinearLayout (Vertical) Finish,
.
5.4. 197
4. Outline ,
. 5.9. ID. questionNumberTextView
guessCountryTextView Medium Text
Form Widgets . Small Button, , .
. 5.9. Outline
fragment_quiz.xml
questionNumberTextView
Layout Parameters
Width
Height
Gravity
wrap_content
wrap_content
center_horizontal
Other Properties
Text
@string/question
198 5 FlagQuiz
5.5 ()
GUI
flagImageView
Layout Parameters
Width
Height
Gravity
Weight
Margins
Left/Right
Top/Bottom
guessCountryTextView
LinearLayout ()
wrap_content
0dp
center
1
@dimen/activity_horizontal_margin
@dimen/activity_vertical_margin
Other Properties
Adjust View Bounds
Content Description
Scale Type
true
@string/image_description
fitCenter
Layout Parameters
Width
Height
Gravity
wrap_content
wrap_content
center_horizontal
Other Properties
Text
@string/guess_country
Layout Parameters
Width
Height
Margins
Bottom
match_parent
wrap_content
@dimen_spacing
Button ()
Layout Parameters
Width
Height
Weight
0dp
fill_parent
1
answerTextView
Layout Parameters
Width
Height
Gravity
wrap_content
wrap_content
center|bottom
Other Properties
Gravity
Text Size
Text Style
center_horizontal
@dimen/answer_size
bold
5.4.9. activity_main.xml
5.4.7 MainActivity ,
QuizFragment.
5.4. 199
MainActivity ,
SettingsFragment, QuizFragment.
.
1. res
NewFolder. Folder layout-large-land Finish.
large land , ,
, ,
.
2. layout-large-land
NewAndroid XML File. New Android XML File.
File activity_main.xml. Root Element
LinearLayout (Horizontal) Finish, .
3. LineerLayout Base Aligned
false.
4. Fragment Layouts
LinearLayout Outline. Choose Fragment Class
SettingsFragment OK.
5. 4 QuizFragment, OK.
6. SettingsFragment Outline. Layout Parameters
Width 0dp, Height match_parent,
Weight 1.
7. QuizFragment Outline. Layout Parameters
Width 0dp, Height match_parent,
Weight 2.
(Weight) QuizFragment SettingsFragment 2 1 , QuizFragment 2/3 .
5.4.10.
preferences.xml
preferences.xml, Settings
Fragment . :
1. res
NewFolder. Folder xml Finish.
2. xml NewAndroid
XML File. New Android XML File.
3. File preferences.xml.
200 5 FlagQuiz
4. , Resource Type Preference,
Root Element PreferenceScreen,
.
5. Finish, . XML, Structure .
6. PreferenceScreen Add.
7. ListPreference OK.
.
8. PreferenceScreen Add.
9. MultiSelectListPreference
OK. .
.
10. ListPreference .5.6.
11. MultiSelectListPreference
.5.7.
12. preferences.xml.
5.6. ListPreference
Entries
@array/guesses_list
Entry values
@array/guesses_list
,
Entries
.
SharedPreferences
Key
pref_numberOfChoices
,
SharedPreferences
Title
@string/number_of_choices
,
GUI
Summary
@string/number_of_choices_description
Persistent
true
true
, PreferenceFragment
Default value
Entries
,
5.4. 201
5.7. MultiSelectListPreference
Entries
@array/regions_list_for_
settings
Entry values
@array/regions_list
,
Entries
.
SharedPreferences
Key
pref_regionsToInclude
,
SharedPreferences
Title
@string/world_regions
, GUI
Summary
@string/world_regions_description
Persistent
true
Default value
@array/regions_list
5.4.11.
,
. 5.6.9 , .
.
1. res NewFolder, Folder name anim
Finish.
2. anim NewAndroid
XML File New Android XML File.
3. File incorrect_shake.xml.
4. , Resource Type is Tween Animation Root Element
.
5. Finish, .
XML.
6. , , XML
5.1.
202 5 FlagQuiz
5.1. (incorrect_shake.xml),
1 <?xml version="1.0" encoding="utf-8"?>
2
3 <set xmlns:android="http://schemas.android.com/apk/res/android"
4
android:interpolator="@android:anim/decelerate_interpolator">
5
6
<translate android:fromXDelta="0" android:toXDelta="-5%p"
7
android:duration="100"/>
8
9
<translate android:fromXDelta="-5%p" android:toXDelta="5%p"
10
android:duration="100" android:startOffset="100"/>
11
12
<translate android:fromXDelta="5%p" android:toXDelta="-5%p"
13
android:duration="100" android:startOffset="200"/>
14 </set>
View . ,
( 314) ,
. alpha (), scale ( ), translate
() rotate ().
translate. translate View
. Android , .
translate ( 67) View
. android:fromXDelta
View ( ),
android:toXDelta View .
:
( );
View;
View.
android:fromXDelta 0.
android:toXDelta -5%p, , View ( ) 5% ( p).
, 5% View, p .
android:duration ( ).
, , 67,
View 5%
100.
5.5. MainActivity203
( 910) ,
. View , -5%p,
, %5p, 100 .
, , ,
android:startOffset ( )
. .
100 . ( 1213)
,
200 .
5.5. MainActivity
MainActivity ( 5.25.7) QuizFragment SettingsFragment
QuizFragment .
204 5 FlagQuiz
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import
import
import
import
android.view.Menu;
android.view.MenuItem;
android.view.WindowManager;
android.widget.Toast;
2627 ,
5.4.10.
. phoneDevice (29) ,
, , . preferencesChanged
( 30) , , ,
onStart MainActivity (5.5.3) updateGuessRows ( 5.6.4) updateRegions ( 5.6.5) QuizFragment
. true,
.
5.5.2. onCreate
onCreate Activity (5.3)
setContentView ( 36) MainActivity.
Android activity_main.xml res/layout, , res/layout-large-land,
.
5.3. onCreate MainActivity
32
33
34
35
36
37
38
39
40
41
42
43
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// SharedPreferences
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
// SharedPreferences
PreferenceManager.getDefaultSharedPreferences(this).
registerOnSharedPreferenceChangeListener(
5.5. MainActivity205
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
preferenceChangeListener);
//
int screenSize = getResources().getConfiguration().screenLayout &
Configuration.SCREENLAYOUT_SIZE_MASK;
// phoneDevice false
if (screenSize == Configuration.SCREENLAYOUT_SIZE_LARGE ||
screenSize == Configuration.SCREENLAYOUT_SIZE_XLARGE )
phoneDevice = false; //
//
if (phoneDevice)
setRequestedOrientation(
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} // onCreate
39 ,
setDefaultValues PreferenceManager
SharedPreferences , ,
preferences.xml. .
(this), .
XML- (R.xml.preferences), -
5.4.10.
, ,
setDefaultValues, false
,
.
, ,
MainActivity updateGuessRows updateRegions
QuizFragment ( , ). MainActivity OnSharedPreferenceChangedListener (4244), . getDefaultSharedPreferences
PreferenceManager SharedPreferences, , registerOnSharedPreferenc
eChangeListener SharedPreferences ,
5.5.6.
4753 , :
? getResources
Resources ( android.content.res),
206 5 FlagQuiz
. getConfiguration Resources Configuration (
android.content.res) (public) screenLayout,
. screenLayout Configuration.SCREENLAYOUT_SIZE_MASK
(&). SCREENLAYOUT_SIZE_LARGE SCREENLAYOUT_SIZE_XLARGE Configuration
( 5152). ,
. ,
, 5758 Activity
setRequestedOrientation, MainActivity
.
5.5.3. onStart
onStart ( 5.4) .
onStart onCreate.
onStart ,
.
, -
SettingsActivity, MainActivity
SettingsActivity. MainActivity,
onStart.
, .
, preferencesChanged true, onStart updateGuessRows ( 5.6.4) updateRegions (5.6.5)
QuizFragment .
QuizFragment , 7172
Activity getFragmentManager FragmentManager,
findFragmentById. 7376
updateGuessRows updateRegions QuizFragment,
SharedPreferences ,
. 77 .
5.4. onStart MainActivity
61
62
63
64
// onCreate
@Override
protected void onStart()
{
5.5. MainActivity207
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
super.onStart();
if (preferencesChanged)
{
// , ,
// QuizFragment
QuizFragment quizFragment = (QuizFragment)
getFragmentManager().findFragmentById(R.id.quizFragment);
quizFragment.updateGuessRows(
PreferenceManager.getDefaultSharedPreferences(this));
quizFragment.updateRegions(
PreferenceManager.getDefaultSharedPreferences(this));
quizFragment.resetQuiz();
preferencesChanged = false;
}
} // onStart
5.5.4. onCreateOptionsMenu
onCreateOptionsMenu (5.5) . Menu, .
. 8788 WindowManager
Display
, .
, .
89 Point ,
90 Display getRealSize, x y Point.
( 93), 95 menu.xml
, .
getMenuInflater, Activity, MenuInflater,
inflate
, , Menu,
. onCreateOptionsMenu true,
, .
5.5. onCreateOptionsMenu MainActivity
82
83
84
85
86
87
88
89
//
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Display
Display display = ((WindowManager)
getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
Point screenSize = new Point(); //
208 5 FlagQuiz
90
91
92
93
94
95
96
97
98
99
100
101
display.getRealSize(screenSize); // screenSize
//
if (screenSize.x < screenSize.y) // x - , y -
{
getMenuInflater().inflate(R.menu.main, menu); //
return true;
}
else
return false;
} // onCreateOptionsMenu
5.5.5. onOptionsItemSelected
onOptionsItemSelected (5.6) .
,
, Settings; ,
, Settings. 106
SettingsActivity. Intent
, , ,
(SettingsActivity.class).
startActivity .
5.6. onOptionsItemSelected MainActivity
102
103
104
105
106
107
108
109
110
// SettingsActivity
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
Intent preferencesIntent = new Intent(this, SettingsActivity.class);
startActivity(preferencesIntent);
return super.onOptionsItemSelected(item);
}
5.5.6. ,
OnSharedPreferenceChangeListener
preferenceChangeListener (5.7)
, OnSharedPreferenceChangeListener.
onCreate
SharedPreferences . ,
onSharedPreferenceChanged preferencesChanged true( 120), QuizFragment (122123)
5.5. MainActivity209
. CHOICES, 127128
updateGuessRows resetQuiz QuizFragment.
5.7. ,
OnSharedPreferenceChangeListener
111
// SharedPreferences
112
private OnSharedPreferenceChangeListener preferenceChangeListener =
113
new OnSharedPreferenceChangeListener()
114
{
115
//
116
@Override
117
public void onSharedPreferenceChanged(
118
SharedPreferences sharedPreferences, String key)
119
{
120
preferencesChanged = true; //
121
122
QuizFragment quizFragment = (QuizFragment)
123
getFragmentManager().findFragmentById(R.id.quizFragment);
124
125
if (key.equals(CHOICES)) //
126
{
127
quizFragment.updateGuessRows(sharedPreferences);
128
quizFragment.resetQuiz();
129
}
130
else if (key.equals(REGIONS)) //
131
{
132
Set<String> regions =
133
sharedPreferences.getStringSet(REGIONS, null);
134
135
if (regions != null && regions.size() > 0)
136
{
137
quizFragment.updateRegions(sharedPreferences);
138
quizFragment.resetQuiz();
139
}
140
else //
141
{
// ( )
142
SharedPreferences.Editor editor = sharedPreferences.edit();
143
regions.add(
144
getResources().getString(R.string.default_region));
145
editor.putStringSet(REGIONS, regions);
146
editor.commit();
147
Toast.makeText(MainActivity.this,
148
R.string.default_region_message,
149
Toast.LENGTH_SHORT).show();
150
}
151
}
152
153
Toast.makeText(MainActivity.this,
154
R.string.restarting_quiz, Toast.LENGTH_SHORT).show();
155
} // onSharedPreferenceChanged
156
}; //
157 } // MainActivity
210 5 FlagQuiz
REGIONS , 132133
Set<String> . getStringSet SharedPreferences
Set<String> .
, Set<String> , 137138
updateRegions resetQuiz QuizFragment.
142146 REGIONS
, 147149
. makeText Toast ,
Toast, . show Toast.
, , 153154
, .
Toast,
, . 5.10.
. 5.10. ,
5.6. QuizFragment
QuizFragment (5.85.16) .
// QuizFragment.java
// Flag Quiz
package com.deitel.flagquiz;
import
import
import
import
import
import
java.io.IOException;
java.io.InputStream;
java.security.SecureRandom;
java.util.ArrayList;
java.util.Collections;
java.util.List;
5.6. QuizFragment211
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import java.util.Set;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
android.app.AlertDialog;
android.app.Dialog;
android.app.DialogFragment;
android.app.Fragment;
android.content.DialogInterface;
android.content.SharedPreferences;
android.content.res.AssetManager;
android.graphics.drawable.Drawable;
android.os.Bundle;
android.os.Handler;
android.util.Log;
android.view.LayoutInflater;
android.view.View;
android.view.View.OnClickListener;
android.view.ViewGroup;
android.view.animation.Animation;
android.view.animation.AnimationUtils;
android.widget.Button;
android.widget.ImageView;
android.widget.LinearLayout;
android.widget.TextView;
5.6.2.
5.9
QuizFragment. TAG ( 38)
Log (5.13),
, .
FLAGS_IN_QUIZ (40) .
5.9. QuizFragment
35 public class QuizFragment extends Fragment
36 {
37
// ,
38
private static final String TAG = "FlagQuiz Activity";
39
40
private static final int FLAGS_IN_QUIZ = 10;
41
42
private List<String> fileNameList; //
43
private List<String> quizCountriesList; //
44
private Set<String> regionsSet; //
45
private String correctAnswer; //
46
private int totalGuesses; //
47
private int correctAnswers; //
48
private int guessRows; //
49
private SecureRandom random; //
50
private Handler handler; //
51
private Animation shakeAnimation; //
52
212 5 FlagQuiz
53
54
55
56
57
private
private
private
private
TextView questionNumberTextView; //
ImageView flagImageView; //
LinearLayout[] guessLinearLayouts; //
TextView answerTextView; // Correct! Incorrect!
fileNameList (42)
. quizCountriesList
(43) ,
. regionsSet (44) .
correctAnswer ( 45) . totalGuesses (46)
.
correctAnswers (47) ;
, FLAGS_IN_QUIZ.
guessRows ( 48) LinearLayout
c , .
random (49) , , ,
LinearLayout. ,
, Handler (50)
.
shakeAnimation (51)
, ,
. 5356 ,
GUI
.
5.6.3. onCreateView
onCreateView QuizFragment (5.10) GUI QuizFragment guessRows
regionsSet , MainActivity updateGuessRows
updateRegions QuizFragment. onCreateView
(63) QuizFragment (6465),
LayoutInflater, onCreateView .
inflate LayoutInflater :
, ;
ViewGroup ( ), ; -
onCreateView;
, ,
ViewGroup ,
5.6. QuizFragment213
false , ,
true
// QuizFragment
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
super.onCreateView(inflater, container, savedInstanceState);
View view =
inflater.inflate(R.layout.fragment_quiz, container, false);
fileNameList = new ArrayList<String>();
quizCountriesList = new ArrayList<String>();
random = new SecureRandom();
handler = new Handler();
//
shakeAnimation = AnimationUtils.loadAnimation(getActivity(),
R.anim.incorrect_shake);
shakeAnimation.setRepeatCount(3); // 3
// GUI
questionNumberTextView =
(TextView) view.findViewById(R.id.questionNumberTextView);
flagImageView = (ImageView) view.findViewById(R.id.flagImageView);
guessLinearLayouts = new LinearLayout[3];
guessLinearLayouts[0] =
(LinearLayout) view.findViewById(R.id.row1LinearLayout);
guessLinearLayouts[1] =
(LinearLayout) view.findViewById(R.id.row2LinearLayout);
guessLinearLayouts[2] =
(LinearLayout) view.findViewById(R.id.row3LinearLayout);
answerTextView = (TextView) view.findViewById(R.id.answerTextView);
//
for (LinearLayout row : guessLinearLayouts)
{
for (int column = 0; column < row.getChildCount(); column++)
{
Button button = (Button) row.getChildAt(column);
button.setOnClickListener(guessButtonListener);
}
}
// questionNumberTextView
214 5 FlagQuiz
101
102
103
104
105
questionNumberTextView.setText(
getResources().getString(R.string.question, 1, FLAGS_IN_QUIZ));
return view; //
} // onCreateView
6768 ArrayList<String>,
. 69 SecureRandom . 70
- Handler,
,
.
7374 ,
. loadAnimation AnimationUtils
XML-, R.anim.incorrect_
shake. Context, ,
, getActivity
Activity, Fragment. Activity Context. 75 setRepeatCount Animation
.
7888 GUI,
. 9198
gue]ssLinearLayout
guessButtonListener ( 5.6.9) OnClickListener.
101102 questionNumberTextView ,
format String. format
R.string.question
( 5.4.2). Fragment
getResources Resources ( android.content.res),
. getString
R.string.question, Question
%1$d of %2$d.
103 QuizFragment.
5.6.4. updateGuessRows
updateGuessRows (5.11) MainActivity , ,
, . 110111 SharedPreferences ,
MainActivity.CHOICES, , SettingsFragment
. 112
5.6. QuizFragment215
// guessRows SharedPreferences
public void updateGuessRows(SharedPreferences sharedPreferences)
{
//
String choices =
sharedPreferences.getString(MainActivity.CHOICES, null);
guessRows = Integer.parseInt(choices) / 3;
// LinearLayout
for (LinearLayout layout : guessLinearLayouts)
layout.setVisibility(View.INVISIBLE);
// LinearLayout
for (int row = 0; row < guessRows; row++)
guessLinearLayouts[row].setVisibility(View.VISIBLE);
5.6.5. updateRegions
updateRegions (5.12) MainActivity
, , .
126127 SharedPreferences
Set<String>. MainActivity.
REGIONS , SettingsFragment
.
5.12. updateregions QuizFragment
123
124
125
126
127
128
129
// SharedPreferences
public void updateRegions(SharedPreferences sharedPreferences)
{
regionsSet =
sharedPreferences.getStringSet(MainActivity.REGIONS, null);
}
5.6.6. resetQuiz
resetQuiz (5.13) . ,
, , assets .
216 5 FlagQuiz
, AssetManager ( 134) getAssets .
135 fileNameList,
, .
140147 . list AssetManager (143)
, paths.
145146 .png,
fileNameList. list AssetManager
IOException, (
). - , assets, 149152
Android. e Log
. Log
http://developer.android.com/reference/android/util/Log.html
5.13. resetQuiz QuizFragment
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
//
public void resetQuiz()
{
// AssetManager
AssetManager assets = getActivity().getAssets();
fileNameList.clear(); //
try
{
//
for (String region : regionsSet)
{
//
String[] paths = assets.list(region);
for (String path : paths)
fileNameList.add(path.replace(".png", ""));
}
}
catch (IOException exception)
{
Log.e(TAG, Error loading image file names, exception);
}
correctAnswers = 0; //
totalGuesses = 0; //
quizCountriesList.clear(); //
int flagCounter = 1;
int numberOfFlags = fileNameList.size();
// FLAGS_IN_QUIZ quizCountriesList
5.6. QuizFragment217
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
// ,
if (!quizCountriesList.contains(fileName))
{
quizCountriesList.add(fileName); //
++flagCounter;
}
loadNextFlag(); //
} // resetQuiz
154156 ,
(correctAnswers), (totalGuesses),
quizCountriesList.
162175 quizCountriesList FLAGS_IN_QUIZ (10) . ,
0 ,
1.
fileNamesList. quizCountriesList ,
quizCountriesList flagCounter.
, FLAGS_IN_QUIZ . 177 loadNextFlag (5.14) .
5.6.7. loadNextFlag
loadNextFlag (5.14) . quizCountriesList
-
.png. regionName countryName ,
(_).
5.14. loadNextFlag QuizFragment
180
181
182
183
184
//
private void loadNextFlag()
{
//
String nextImage = quizCountriesList.remove(0);
218 5 FlagQuiz
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
correctAnswer = nextImage; //
answerTextView.setText(""); // answerTextView
//
questionNumberTextView.setText(
getResources().getString(R.string.question,
(correctAnswers + 1), FLAGS_IN_QUIZ));
//
String region = nextImage.substring(0, nextImage.indexOf('-'));
// AssetManager
AssetManager assets = getActivity().getAssets();
try
{
// InputStream
InputStream stream =
assets.open(region + / + nextImage + .png);
// Drawable flagImageView
Drawable flag = Drawable.createFromStream(stream, nextImage);
flagImageView.setImageDrawable(flag);
}
catch (IOException exception)
{
Log.e(TAG, "Error loading " + nextImage, exception);
}
Collections.shuffle(fileNameList); //
// fileNameList
int correct = fileNameList.indexOf(correctAnswer);
fileNameList.add(fileNameList.remove(correct));
// 3, 6 9 guessRows
for (int row = 0; row < guessRows; row++)
{
// currentTableRow
for (int column = 0;
column < guessLinearLayouts[row].getChildCount(); column++)
{
// Button
Button newGuessButton =
(Button) guessLinearLayouts[row].getChildAt(column);
newGuessButton.setEnabled(true);
// newGuessButton
String fileName = fileNameList.get((row * 3) + column);
newGuessButton.setText(getCountryName(fileName));
//
int row = random.nextInt(guessRows); //
5.6. QuizFragment219
240
241
242
243
244
245
239243 (
guessRows) , .
5.6.8. getCountryName
getCountryName (5.15)
. , ,
. replace
String (_) .
220 5 FlagQuiz
5.15. getCountryName QuizFragment
246
247
248
249
250
251
//
private String getCountryName(String name)
{
return name.substring(name.indexOf('-') + 1).replace('_', ' ');
}
5.6.9. ,
OnClickListener
9198 (5.10) guessButtonListener ( 5.16)
. guessButtonListener
, OnClickListener
. v.
( 259) ( 260),
totalGuesses.
( 263), correctAnswers.
answerTextView ,
, R.color.correct_answer
(). disableButtons (5.6.10), .
5.16. , OnClickListener
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
//
private OnClickListener guessButtonListener = new OnClickListener()
{
@Override
public void onClick(View v)
{
Button guessButton = ((Button) v);
String guess = guessButton.getText().toString();
String answer = getCountryName(correctAnswer);
++totalGuesses; //
if (guess.equals(answer)) //
{
++correctAnswers; //
//
answerTextView.setText(answer + "!");
answerTextView.setTextColor(
getResources().getColor(R.color.correct_answer));
disableButtons(); //
5.6. QuizFragment221
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
// FLAGS_IN_QUIZ
if (correctAnswers == FLAGS_IN_QUIZ)
{
// DialogFragment
DialogFragment quizResults =
new DialogFragment()
{
// AlertDialog
@Override
public Dialog onCreateDialog(Bundle bundle)
{
AlertDialog.Builder builder =
new AlertDialog.Builder(getActivity());
builder.setCancelable(false);
builder.setMessage(
getResources().getString(R.string.results,
totalGuesses, (1000 / (double) totalGuesses)));
// "Reset Quiz"
builder.setPositiveButton(R.string.reset_quiz,
new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog,
int id)
{
resetQuiz();
}
} //
); // setPositiveButton
return builder.create(); // AlertDialog
} // onCreateDialog
}; // DialogFragment
// FragmentManager DialogFragment
quizResults.show(getFragmentManager(), quiz results);
}
else // ,
{
//
handler.postDelayed(
new Runnable()
{
@Override
public void run()
{
loadNextFlag();
}
}, 2000); // (2000 )
}
}
else //
{
flagImageView.startAnimation(shakeAnimation); //
222 5 FlagQuiz
329
330
331
332
333
334
335
336
337
338
// "Incorrect!"
answerTextView.setText(R.string.incorrect_answer);
answerTextView.setTextColor(
getResources().getColor(R.color.incorrect_answer));
guessButton.setEnabled(false); //
}
}
}; // guessButtonListener
5.6.10. disableButtons
disableButtons (5.17)
.
5.17. disableButtons QuizFragment
339
340
341
342
343
344
// ,
private void disableButtons()
{
for (int row = 0; row < guessRows; row++)
{
LinearLayout guessRow = guessLinearLayouts[row];
5.8. SettingsActivity223
345
for (int i = 0; i < guessRow.getChildCount(); i++)
346
guessRow.getChildAt(i).setEnabled(false);
347
}
348
}
349 } // FlagQuiz
5.7. SettingsFragment
SettingsFragment (5.18) PreferenceFragment, .
onCreate ( 1116) SettingsFragment
SettingsActivity , MainActivity .
15 PreferenceFragment addPreferencesFromResource
.
preferences.xml,
5.4.10.
5.18. PreferenceFragment
1 // SettingsFragment.java
2 // PreferenceFragment
3 package com.deitel.flagquiz;
4
5 import android.os.Bundle;
6 import android.preference.PreferenceFragment;
7
8 public class SettingsFragment extends PreferenceFragment
9 {
10
// GUI preferences.xml res/xml
11
@Override
12
public void onCreate(Bundle savedInstanceState)
13
{
14
super.onCreate(savedInstanceState);
15
addPreferencesFromResource(R.xml.preferences); // XML
16
}
17 } // SettingsFragment
5.8. SettingsActivity
SettingsActivity (5.19) SettingsFragment
. ,
(com.deitel.flagquiz) NewClass,
New Java Class. Name
SettingsActivity, Superclass android.app.Activity
Finish.
224 5 FlagQuiz
onCreate (1116) setContentView
Activity, ,
activity_settings.xml ( 5.4.6), R.layout.activity_
settings.
5.19. SettingsFragment
1 // SettingsActivity.java
2 // SettingsFragment
3 package com.deitel.flagquiz;
4
5 import android.app.Activity;
6 import android.os.Bundle;
7
8 public class SettingsActivity extends Activity
9 {
10
// FragmentManager SettingsFragment
11
@Override
12
protected void onCreate(Bundle savedInstanceState)
13
{
14
super.onCreate(savedInstanceState);
15
setContentView(R.layout.activity_settings);
16
}
17 } // SettingsActivity
5.9. AndroidManifest.xml
AndroidManifest.
xml ; Android ,
, .
MainActivity AndroidManifest.xml. SettingsActivity, .
1. AndroidManifest.xml Application
.
2. Application Nodes Add,
Activity OK.
3. Application Nodes ,
Attributes for Activity.
4. Name .SettingsActivity. (.) SettingsActivity
(com.deitel.
flagquiz).
5. Label @string/settings_activity SettingsActivity.
5.10. 225
http://developer.android.com/guide/topics/manifest/manifest-intro.html
5.10.
Flag Quiz .
.
QuizFragment SettingsFragment
. PreferenceFragment
,
DialogFragment AlertDialog.
Fragment , FragmentManager
.
SettingsActivity, SettingsFragment.
SettingsActivity .
, Android WindowManager
Display, , . ,
SettingsFragment .
, assets
AssetManager. Drawable
, InputStream,
Drawable ImageView.
res menu
, anim xml
XML. ,
,
.
Toast
, . ,
Handler, Runnable . , Runnable
, Handler (UI- ).
226 5 FlagQuiz
XML ImageView
, . Android Log.
java.util, List, ArrayList,
Collections Set.
6 Cannon Game. , .
, ,
,
. .
CannonGame
, ,
, , ,
SurfaceView SurfaceHolder
,
SurfaceView
Paints Canvas
onTouchEvent View
SoundPool
AudioManager
onPause onDestroy
Fragment
228 6 CannonGame
6.1.
Cannon Game 10 , (. 6.1).
, , , ,
. , .
, ,
.
AlertDialog, , ,
(. 6.2).
10 .
,
. , .
, .
.
. , .
, , .
. ,
.
[: - Android
.]
230 6 CannonGame
3. Cannon Game. Eclipse
CannonGame Package Explorer,
Run AsAndroid Application.
, .
, .
AVD, . . ,
.
6.3.
,
Cannon Game.
.
6.3.1.
, View
, CannonView ( 6.8),
SurfaceView (. ). XML-
, ( ), View ,
.
CannonView 6.4.3.
6.3.2. raw
(, ), Cannon Game, res/raw. , ,
6.4.5; .
6.3.3.
, 5
( ),
.
6.3. 231
6.3.5. SoundPool
AudioManager
SoundPool
( android.media), ,
232 6 CannonGame
.
Android, , , , , .. Android
. setVolumeControlStream Activity
. AudioManager (
android.media),
.
6.3.6. ,
SurfaceView SurfaceHolder
, . Thread run, CannonView
, .
run .
, GUI. Android
, GUI, ,
ANR (Application Not Responding). , ,
. Android
SurfaceView View,
, , GUI-.
SurfaceView SurfaceHolder,
Canvas, .
SurfaceHolder ,
Canvas , SurfaceView
. SurfaceView
SurfaceHolder.Callback, ,
, ( )
SurfaceView.
6.3.7.
CannonView
- CannonView, . 6.8. ,
,
6.4. 233
.
.
6.4.
main.xml.
6.4.1.
Android CannonGame.
New Android Project .
Application name: Cannon Game
Project Name: Cannon Game
Package name: com.deitel.cannongame
Minimum Required SDK: API18: Android 4.3
Target SDK: API19: Android 4.4
Compile With: API19: Android 4.4
Theme: Holo Light with Dark Action Bar
234 6 CannonGame
.
, 3.6,
.
6.4.2. strings.xml
,
(. 6.1). strings.xml res/values,
.
6.1. , Cannon Game
results_format
reset_game
Reset Game
win
You win!
lose
You lose!
time_remaining_format
6.4.3. fragment_game.xml
fragment_game.xml CannonGameFragment
FrameLayout CannonView. FrameLayout
CannonView.
CannonGameFragment CannonView.
fragment_game.xml, .
1. res/layout Package Explorer.
2. values NewAndroid
XML File. New Android XML File.
3. File fragment_game.xml Finish,
.
4. Root Element FrameLayout Finish.
5. Advanced view ( v)
.
6. Choose Custom View Class. Create New, New Java Class.
6.4. 235
6.4.4. activity_main.xml
activity_main.xml MainActivity
CannonGameFragment .
, .
1. activity_main.xml .
2. Layouts
RelativeLayout Outline.
3. Choose Fragment Class. Create New,
New Java Class.
4. Name CannonGameFragment
Superclass android.app.Fragment. Finish, .
Java, .
5. activity_main.xml.
6.4.5.
, res/raw .
blocker_hit.wav, target_hit.
wav cannon_fire.wav, sounds .
, .
1. res
NewFolder.
2. raw Finish, .
3. res/raw.
236 6 CannonGame
6.5. Line
:
Line (6.1);
MainActivity ( Activity; 6.6);
CannonGameFragment ( 6.7);
CannonView ( 6.8).
Line,
( Point).
. Line , .
1. src Package Explorer.
2. (com.deitel.cannongame) NewClass
New Java Class.
3. Name Line Finish.
4. , 6.4, Line.java. Point
x y Point .
6.1. Line
1
2
3
4
5
6
7
8
9
10
11
// Line.java
// Line .
package com.deitel.cannongame;
import android.graphics.Point;
public class Line
{
public Point start = new Point(); // --(0,0)
public Point end = new Point(); // --(0,0)
} // Line
6.6. MainActivity
MainActivity (6.2) CannonGameFragment Cannon Game. onCreate
Activity, .
6.2. MainActivity CannonGameFragment
1 // MainActivity.java
2 // MainActivity CannonGameFragment
3 package com.deitel.cannongame;
6.7. CannonGameFragment237
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity
{
//
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState); // onCreate
setContentView(R.layout.activity_main); //
}
} // MainActivity
6.7. CannonGameFragment
CannonGameFragment (6.3) Fragment:
onCreateView ( 1728) 5.3.3,
onCreate Fragment
View, . 2223
. 26
CannonView CannonGameFragment, ;
onActivityCreated (3138) -
. 37 setVolumeControlStream
Activity,
;
, ) onPause CannonGameFragment.
45 stopGame CannonView (6.8.11)
;
6.3. CannonGameFragment
CannonView
1
2
3
4
5
6
7
// CannonGameFragment.java
// CannonGameFragment CannonView
package com.deitel.cannongame;
import android.app.Fragment;
import android.media.AudioManager;
import android.os.Bundle;
238 6 CannonGame
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
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class CannonGameFragment extends Fragment
{
private CannonView cannonView; //
//
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
super.onCreateView(inflater, container, savedInstanceState);
View view =
inflater.inflate(R.layout.fragment_game, container, false);
// CannonView
cannonView = (CannonView) view.findViewById(R.id.cannonView);
return view;
//
@Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
//
getActivity().setVolumeControlStream(AudioManager.STREAM_MUSIC);
// MainActivity
@Override
public void onPause()
{
super.onPause();
cannonView.stopGame(); //
}
// MainActivity
@Override
public void onDestroy()
{
super.onDestroy();
cannonView.releaseResources();
}
} // CannonGameFragment
6.8. CannonView
CannonView ( 6.46.17), View,
Cannon Game .
6.8. CannonView239
// CannonView.java
// Cannon Game
package com.deitel.cannongame;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
android.app.Activity;
android.app.AlertDialog;
android.app.Dialog;
android.app.DialogFragment;
android.content.Context;
android.content.DialogInterface;
android.graphics.Canvas;
android.graphics.Color;
android.graphics.Paint;
android.graphics.Point;
android.media.AudioManager;
android.media.SoundPool;
android.os.Bundle;
android.util.AttributeSet;
android.util.Log;
android.util.SparseIntArray;
android.view.MotionEvent;
android.view.SurfaceHolder;
android.view.SurfaceView;
6.8.2.
6.5
CannonView. ,
.
6.5. CannonView
25 public class CannonView extends SurfaceView
26
implements SurfaceHolder.Callback
27 {
28
private static final String TAG = "CannonView"; //
29
30
private CannonThread cannonThread; //
31
private Activity activity; // GUI
32
private boolean dialogIsDisplayed = false;
33
34
// ,
35
public static final int TARGET_PIECES = 7; //
36
public static final int MISS_PENALTY = 2; // (.)
240 6 CannonGame
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
Line target; //
int targetDistance; //
int targetBeginning; //
double pieceLength; //
int targetEnd; //
int initialTargetVelocity; //
float targetVelocity; //
Paint
textPaint; //
cannonballPaint; //
cannonPaint; //
blockerPaint; //
targetPaint; //
backgroundPaint; //
6.8. CannonView241
6.8.3.
6.6 CannonView. View ,
Context AttributeSet. ,
CannonGameFragment CannonView, ( android.util)
CannonView, XML- . ( 96),
View,
XML- . 97 MainActivity, AlertDialog GUI- .
6.6. CannonView
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
//
public CannonView(Context context, AttributeSet attrs)
{
super(context, attrs); //
activity = (Activity) context; // MainActivity
// SurfaceHolder.Callback
getHolder().addCallback(this);
// Line Point
blocker = new Line(); // blocker Line
target = new Line(); // target Line
cannonball = new Point(); // cannonball Point
// hitStates
hitStates = new boolean[TARGET_PIECES];
// SoundPool
soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
// Map
soundMap = new SparseIntArray(3); // SparseIntArray
soundMap.put(TARGET_SOUND_ID,
soundPool.load(context, R.raw.target_hit, 1));
soundMap.put(CANNON_SOUND_ID,
soundPool.load(context, R.raw.cannon_fire, 1));
soundMap.put(BLOCKER_SOUND_ID,
soundPool.load(context, R.raw.blocker_hit, 1));
// Paint , ,
// , ;
// onSizeChanged
textPaint = new Paint();
cannonPaint = new Paint();
cannonballPaint = new Paint();
blockerPaint = new Paint();
targetPaint = new Paint();
backgroundPaint = new Paint();
} // CannonView
242 6 CannonGame
SurfaceHolder.Callback
100 this ( CannonView) , SurfaceHolder.Callback ,
, SurfaceView. SurfaceView
getHolder SurfaceHolder SurfaceView, addCallback SurfaceHolder ,
SurfaceHolder.Callback.
,
103105 (blocker) (target) Line,
(cannonball) Point. hitStates , ( , ).
SoundPool
111120 , . SoundPool ,
, .
, .
, 1.
, . ,
AudioManager, SoundPool
(AudioManager.STREAM_MUSIC). ,
,
( 0).
114 SparseIntArray ( soundMap),
. SparseIntArray
HashMap<Integer,Integer>,
/. (. 6.5, 7981)
, load SoundPool ( 6.6,
116, 118 120).
( ). load SoundPool
(Context) ; ; . ,
, ,
1.
Paint,
124129 Paint,
. onSizeChanged ( 6.8.4),
6.8. CannonView243
Paint
, .
244 6 CannonGame
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
targetDistance = w * 7 / 8; // 7/8
targetBeginning = h / 8; //
// 1/8
targetEnd = h * 7 / 8; // - 7/8
pieceLength = (targetEnd - targetBeginning) / TARGET_PIECES;
initialTargetVelocity = -h / 4; //
target.start = new Point(targetDistance, targetBeginning);
target.end = new Point(targetDistance, targetEnd);
//
barrelEnd = new Point(cannonLength, h / 2);
// Paint
textPaint.setTextSize(w / 20); // 1/20
textPaint.setAntiAlias(true); //
cannonPaint.setStrokeWidth(lineWidth * 1.5f); //
blockerPaint.setStrokeWidth(lineWidth); //
targetPaint.setStrokeWidth(lineWidth); //
backgroundPaint.setColor(Color.WHITE); //
newGame(); //
} // onSizeChanged
6.8.5. newGame
newGame (6.8) ,
. gameOver true (
), 203 gameOver, 204205
CannonThread ,
. 6.8.14.
6.8. newGame CannonView
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
//
public void newGame()
{
// hitStates false ( )
for (int i = 0; i < TARGET_PIECES; i++)
hitStates[i] = false;
targetPiecesHit = 0; //
blockerVelocity = initialBlockerVelocity; //
targetVelocity = initialTargetVelocity; //
timeLeft = 10; // 10
cannonballOnScreen = false; //
shotsFired = 0; //
totalElapsedTime = 0.0; //
//
blocker.start.set(blockerDistance, blockerBeginning);
blocker.end.set(blockerDistance, blockerEnd);
target.start.set(targetDistance, targetBeginning);
6.8. CannonView245
199
200
201
202
203
204
205
206
207
208
target.end.set(targetDistance, targetEnd);
if (gameOver) //
{
gameOver = false; //
cannonThread = new CannonThread(getHolder()); //
cannonThread.start(); //
} // if
} // newGame
6.8.6. updatePositions
updatePositions (6.9) run CannonThread
( 6.8.14) .
(),
. ,
,
. 6.8.14.
6.9. updatePositions CannonView
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
// CannonThread
private void updatePositions(double elapsedTimeMS)
{
double interval = elapsedTimeMS / 1000.0; //
if (cannonballOnScreen) //
{
//
cannonball.x += interval * cannonballVelocityX;
cannonball.y += interval * cannonballVelocityY;
//
if (cannonball.x + cannonballRadius > blockerDistance &&
cannonball.x - cannonballRadius < blockerDistance &&
cannonball.y + cannonballRadius > blocker.start.y &&
cannonball.y - cannonballRadius < blocker.end.y)
{
cannonballVelocityX *= -1; //
timeLeft -= MISS_PENALTY; //
//
soundPool.play(soundMap.get(BLOCKER_SOUND_ID), 1, 1, 1, 0, 1f);
}
//
else if (cannonball.x + cannonballRadius > screenWidth ||
cannonball.x - cannonballRadius < 0)
{
246 6 CannonGame
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
cannonballOnScreen = false; //
}
//
else if (cannonball.y + cannonballRadius > screenHeight ||
cannonball.y - cannonballRadius < 0)
{
cannonballOnScreen = false; //
}
//
else if (cannonball.x + cannonballRadius > targetDistance &&
cannonball.x - cannonballRadius < targetDistance &&
cannonball.y + cannonballRadius > target.start.y &&
cannonball.y - cannonballRadius < target.end.y)
{
// (0 - )
int section =
(int) ((cannonball.y - target.start.y) / pieceLength);
// ,
if ((section >= 0 && section < TARGET_PIECES) &&
!hitStates[section])
{
hitStates[section] = true; //
cannonballOnScreen = false; //
timeLeft += HIT_REWARD; //
//
soundPool.play(soundMap.get(TARGET_SOUND_ID), 1,
1, 1, 0, 1f);
//
if (++targetPiecesHit == TARGET_PIECES)
{
cannonThread.setRunning(false); //
showGameOverDialog(R.string.win); //
gameOver = true;
}
//
double blockerUpdate = interval * blockerVelocity;
blocker.start.y += blockerUpdate;
blocker.end.y += blockerUpdate;
//
double targetUpdate = interval * targetVelocity;
target.start.y += targetUpdate;
target.end.y += targetUpdate;
// ,
if (blocker.start.y < 0 || blocker.end.y > screenHeight)
blockerVelocity *= -1;
6.8. CannonView247
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
// ,
if (target.start.y < 0 || target.end.y > screenHeight)
targetVelocity *= -1;
timeLeft -= interval; //
//
if (timeLeft <= 0.0)
{
timeLeft = 0.0;
gameOver = true; //
cannonThread.setRunning(false); //
showGameOverDialog(R.string.lose); //
}
} // updatePositions
206 , ( ).
.
214 , .
, ,
.
( 217218). 221224 , .
, .
.
x ,
(blockerDistance), 221.
, , ,
.
x ,
( 222). ,
.
, ( 223).
, ( 224).
,
( 226),
( timeLeft MISS_PENALTY), play
soundPool , .
SoundPool soundMap
BLOCKER_SOUND_ID.
248 6 CannonGame
.
233237 , ,
. 233235
.
( 245248).
, .
, ,
. 251252 , , .
0 ( ) 6 (
).
hitStates ( 256).
hitStates true,
. HIT_REWARD
timeLeft, ,
(TARGET_SOUND_ID).
targetPiecesHit, , TARGET_PIECES
( 267). , ; CannonThread setRunning false,
showGameOverDialog , gameOver true.
, ,
. 278280 blockerVelocity , ;
x y. 283285
. ,
1 (
288289). 292293 ,
, , .
timeLeft ,
. timeLeft
, . timeLeft
0.0 ( ,
). gameOver true,
CannonThread setRunning false,
showGameOverDialog ,
.
6.8. CannonView249
//
public void fireCannonball(MotionEvent event)
{
if (cannonballOnScreen) //
return; //
double angle = alignCannon(event); //
//
cannonball.x = cannonballRadius; // x
cannonball.y = screenHeight / 2; //
// x
cannonballVelocityX = (int) (cannonballSpeed * Math.sin(angle));
// y
cannonballVelocityY = (int) (-cannonballSpeed * Math.cos(angle));
cannonballOnScreen = true; //
++shotsFired; // shotsFired
//
soundPool.play(soundMap.get(CANNON_SOUND_ID), 1, 1, 1, 0, 1f);
} // fireCannonball
6.8.8. alignCannon
alignCannon (6.11) . 335
x y MotionEvent,
.
,
( 345).
250 6 CannonGame
, Math.PI ( 349).
cannonLength angle x y
.
.
6.11. alignCannon CannonView
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
//
public double alignCannon(MotionEvent event)
{
//
Point touchPoint = new Point((int) event.getX(), (int) event.getY());
//
// y
double centerMinusY = (screenHeight / 2 - touchPoint.y);
double angle = 0; // angle 0
//
if (centerMinusY != 0) // 0
angle = Math.atan((double) touchPoint.x / centerMinusY);
//
if (touchPoint.y > screenHeight / 2)
angle += Math.PI; //
//
barrelEnd.x = (int) (cannonLength * Math.sin(angle));
barrelEnd.y =
(int) (-cannonLength * Math.cos(angle) + screenHeight / 2);
return angle; //
} // alignCannon
6.8.9. drawGameElements
drawGameElements ( 6.12) , , SurfaceView. Canvas,
CannonThread ( 6.8.14) SurfaceHolder
SurfaceView.
6.12. drawGameElements CannonView
359
360
361
362
363
364
//
public void drawGameElements(Canvas canvas)
{
//
canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(),
backgroundPaint);
6.8. CannonView251
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
//
canvas.drawText(getResources().getString(
R.string.time_remaining_format, timeLeft), 30, 50, textPaint);
// ,
if (cannonballOnScreen)
canvas.drawCircle(cannonball.x, cannonball.y, cannonballRadius,
cannonballPaint);
//
canvas.drawLine(0, screenHeight / 2, barrelEnd.x, barrelEnd.y,
cannonPaint);
//
canvas.drawCircle(0, (int) screenHeight / 2,
(int) cannonBaseRadius, cannonPaint);
//
canvas.drawLine(blocker.start.x, blocker.start.y, blocker.end.x,
blocker.end.y, blockerPaint);
Point currentPoint = new Point(); //
// currentPoint
currentPoint.x = target.start.x;
currentPoint.y = target.start.y;
//
for (int i = 0; i < TARGET_PIECES; i++)
{
// ,
if (!hitStates[i])
{
//
if (i % 2 != 0)
targetPaint.setColor(Color.BLUE);
else
targetPaint.setColor(Color.YELLOW);
// currentPoint
currentPoint.y += pieceLength;
}
} // drawGameElements
Canvas drawRect
drawRect Canvas ( 363364), Canvas,
.
252 6 CannonGame
, Paint,
(backgroundPaint
).
drawText Canvas
drawText Canvas ( 367368) .
, x y textPaint (
170171), ( ,
).
drawCircle Canvas
, 372373
drawCircle Canvas .
, . Paint,
.
, drawLine Canvas
drawLine Canvas (376
377), ( 384385) ( 405406).
, Paint,
(, ).
drawCircle Canvas
380381 drawCircle Canvas
. ,
.
SurfaceView.
drawLine Canvas
390411 . , ( ,
). ,
.
6.8.10. showGameOverDialog
showGameOverDialog ( 6.13) DialogFragment (. 5.6.9) AlertDialog,
/,
. setPositiveButton ( 433444)
.
6.8. CannonView253
// AlertDialog
private void showGameOverDialog(final int messageId)
{
// DialogFragment
final DialogFragment gameResult =
new DialogFragment()
{
// AlertDialog
@Override
public Dialog onCreateDialog(Bundle bundle)
{
// messageId
AlertDialog.Builder builder =
new AlertDialog.Builder(getActivity());
builder.setTitle(getResources().getString(messageId));
//
builder.setMessage(getResources().getString(
R.string.results_format, shotsFired, totalElapsedTime));
builder.setPositiveButton(R.string.reset_game,
new DialogInterface.OnClickListener()
{
// "Reset Game"
@Override
public void onClick(DialogInterface dialog, int which)
{
dialogIsDisplayed = false;
newGame(); //
}
} //
); // setPositiveButton
return builder.create(); // AlertDialog
} // onCreateDialog
}; // DialogFragment
// UI- FragmentManager DialogFragment
activity.runOnUiThread (
new Runnable() {
public void run()
{
dialogIsDisplayed = true;
gameResult.setCancelable(false); //
gameResult.show(activity.getFragmentManager(), "results");
}
} // Runnable
); // runOnUiThread
} // showGameOverDialog
onClick ,
, newGame .
GUI, 451460
254 6 CannonGame
runOnUiThread Activity Runnable,
GUI . , Runnable.
// ; onPause CannonGameFragment
public void stopGame()
{
if (cannonThread != null)
cannonThread.setRunning(false); //
}
// ; onDestroy CannonGame
public void releaseResources()
{
soundPool.release(); // , SoundPool
soundPool = null;
}
6.8.12. SurfaceHolder.Callback
6.15 surfaceChanged, surfaceCreated
surfaceDestroyed SurfaceHolder.Callback. surfaceChanged
, .
SurfaceView
. surfaceCreated (485494)
SurfaceView ,
. surfaceCreated CannonThread,
. surfaceDestroyed ( 497515)
SurfaceView , .
CannonThread. 502
setRunning CannonThread false, ,
6.8. CannonView255
, 504515
. SurfaceView
surfaceDestroyed.
6.15. SurfaceHolder.Callback
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
//
@Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height)
{
}
//
@Override
public void surfaceCreated(SurfaceHolder holder)
{
if (!dialogIsDisplayed)
{
cannonThread = new CannonThread(holder); //
cannonThread.setRunning(true); //
cannonThread.start(); //
}
}
//
@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
//
boolean retry = true;
cannonThread.setRunning(false); // cannonThread
while (retry)
{
try
{
cannonThread.join(); // cannonThread
retry = false;
}
catch (InterruptedException e)
{
Log.e(TAG, "Thread interrupted", e);
}
}
} // surfaceDestroyed
6.8.13. onTouchEvent
onTouchEvent View (6.16)
. MotionEvent
. 523 getAction
256 6 CannonGame
MotionEvent .
526527 , (MotionEvent.
ACTION_DOWN) (MotionEvent.ACTION_MOVE).
529 fireCannonball cannonView
. 532 true , .
6.16. onTouchEvent View
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
//
@Override
public boolean onTouchEvent(MotionEvent e)
{
// ,
int action = e.getAction();
//
if (action == MotionEvent.ACTION_DOWN ||
action == MotionEvent.ACTION_MOVE)
{
fireCannonball(e); //
}
return true;
} // onTouchEvent
6.8.14. CannonThread:
6.17 Thread,
. SurfaceHolder SurfaceView (
538) , , .
run ( 556587) ( ).
, .
559 ,
. 561586
, threadIsRunning false.
6.17. Runnable,
TIME_INTERVAL
535
536
537
538
539
540
// Thread,
private class CannonThread extends Thread
{
private SurfaceHolder surfaceHolder; // Canvas
private boolean threadIsRunning = true; //
6.8. CannonView257
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
// SurfaceHolder
public CannonThread(SurfaceHolder holder)
{
surfaceHolder = holder;
setName("CannonThread");
}
//
public void setRunning(boolean running)
{
threadIsRunning = running;
}
//
@Override
public void run()
{
Canvas canvas = null; //
long previousFrameTime = System.currentTimeMillis();
while (threadIsRunning)
{
try
{
// Canvas
canvas = surfaceHolder.lockCanvas(null);
// surfaceHolder
synchronized(surfaceHolder)
{
long currentTime = System.currentTimeMillis();
double elapsedTimeMS = currentTime - previousFrameTime;
totalElapsedTime += elapsedTimeMS / 1000.0;
updatePositions(elapsedTimeMS); //
drawGameElements(canvas); //
previousFrameTime = currentTime; //
//
}
577
578
}
579
finally
580
{
581
// Canvas CannonView
582
// Canvas
583
if (canvas != null)
584
surfaceHolder.unlockCanvasAndPost(canvas);
585
}
586
} // while
587
} // run
588
} // CannonThread
589 } // CannonView
Canvas, SurfaceView,
lockCanvas SurfaceHolder ( 566). SurfaceView ,
258 6 CannonGame
SurfaceHolder. (),
. 574
updatePositions, ;
.
. (
),
.
( ),
. ,
575 Canvas SurfaceView,
576 currentTime previousFrameTime
.
6.9.
Cannon Game, 10- .
, .
,
SurfaceView. , XML,
.
Activity: onPause ,
, onDestroy
. onTouchEvent Activity
. res/
raw SoundPool,
AudioManager
.
,
SurfaceView . Thread
run,
Canvas. SurfaceHolder SurfaceView
Canvas, ,
, .
.
7 Doodlz,
Android .
, Android 4.4, .
Doodlz
, Canvas Bitmap, ,
SensorManager, ,
MediaStore, ,
, ,
SensorManager
Paint
Path , Canvas Bitmap
Android 4.4
260 7 Doodlz
7.1.
Doodlz
(.7.1). Android 4.4, ,
.
. 7.1. Doodlz
.
Choose Color (. 7.2, ) SeekBar ()
- (), , ,
ARGB (. 1.9).
SeekBar SeekBar
. Choose Line Width,
.7.2,, SeekBar . (. 7.3) (Eraser),
(Clear), (Save)
Android 4.4 .
, .
7.2. 261
, .
1.9, .
AVD,
. [: - Gallery,
,
Doodlz .]
. 7.2. Doodlz:
a ;
. 7.3. Doodlz
Android 4.4
7.2.
,
Doodlz.
262 7 Doodlz
7.2.1. SensorManager
, ,
. Android ,
.
Android , , , , , , ,
, . Sensor, ,
http://developer.android.com/reference/android/hardware/Sensor.html
7.5.
Android
http://developer.android.com/guide/topics/sensors/sensors_overview.html
7.2.2. DialogFragment
( ) AlertDialog
DialogFragment . AlertDialog , ,
, DialogFragment
. AlertDialog
.
DialogFragment.
ColorDialogFragment ( 7.7) AlertDialog
, GUI
ARGB.
, GUI
.
ColorDialogFragment EraseImageDialog
Fragment . DialogFragment
Fragment.
onAttach , -
7.2. 263
onDetach ,
, . , onAttach
onDetach , ,
. , .
7.2.4.
Path
,
. Path
( android.graphics), .
onTouchEvent View ( 7.6). MotionEvent
( android.view )
, .
Path.
,
, .
264 7 Doodlz
7.2.7.
Save . ContentResolver
( android.content) , . ContentResolver (7.6)
insertImage MediaStore.Images.Media
. MediaStore ,
, .
7.3.
,
Doodlz.
7.3. 265
7.3.1.
Android Doodlz.
New Android Project , Finish.
Application name: Doodlz
Project Name: Doodlz
Package Name: com.deitel.doodlz
Minimum Required SDK: API18: Android 4.3
Target SDK: API19: Android 4.4
Compile With: API19: Android 4.4
Theme: Holo Light with Dark Action Bar
7.3.2. strings.xml
,
(. 7.1). strings.xml res/values,
.
7.1. , Doodlz
app_name
Doodlz
button_erase
Erase Image
button_cancel
Cancel
266 7 Doodlz
7.1 ()
button_set_color
Set Color
button_set_line_width
line_imageview_description
label_alpha
Alpha
label_red
Red
label_green
Green
label_blue
Blue
menuitem_clear
Clear
menuitem_color
Color
menuitem_eraser
Eraser
menuitem_line_width
Line Width
menuitem_save
Save
menuitem_print
message_erase
message_error_saving
message_saved
message_error_printing
title_color_dialog
Choose Color
title_line_width_dialog
7.3.3. dimens.xml
.7.2 ,
dimens.xml. dimens.xml res/values,
. line_imageview_height ImageView LineWidthDialogFragment,
color_view_height View
ColorDialogFragment.
7.2. , Doodlz
line_imageview_height
50dp
color_view_height
80dp
7.3. 267
7.3.4. DoodleFragment
5 Settings Flag Quiz , .
, main.xml
res/menu . DoodleFragment.
Android
DoodleFragment Android4.3
Android 4.4 .
Android 4.4 , Print
. res/menu,
res/menu-v19 (19 Android API, Android4.4).
Android res/menu-v19
Android 4.4 . res/menu-v19,
res, NewFolder,
menu-v19 Finish.
Android 4.3
Android 4.3 ,
.
1. res/menu New
Android XML File.
2. doodle_fragment_menu.xml
Finish. .
3. Add, Layout ,
Item OK.
.
4. Id @+id/color, Title @string/
menuitem_color, Show as action ifRoom. ifRoom
,
;
. Show as
action
http://developer.android.com/guide/topics/resources/menu-resource.html
5. 3 4 lineWidth, eraser, clear save (.7.3). : Add
, Create a new element at the top level in Menu.
6. doodle_fragment_menu.xml.
268 7 Doodlz
7.3. DoodleFragment
@+id/lineWidth
@string/menuitem_line_width
@+id/eraser
@string/menuitem_eraser
@+id/clear
@string/menuitem_clear
@+id/save
@string/menuitem_save
Android 4.4
Android 4.4 , .
1. doodle_fragment_menu.xml res/menu,
res/menu-v19 .
2. Add, Create a new element at the
top level in Menu, Item OK.
3. Id @+id/print, Title @string/menuitem_print, Show as action ifRoom.
7.3. 269
7.3.6. fragment_doodle.xml
DoodleFragment
fragment_doodle.xml DoodleFragment
FrameLayout, DoodleView.
DoodleFragment DoodleView. fragment_
doodle.xml, .
1. res/layout Package Explorer.
2. res/layout
NewAndroid XML File. New Android XML File.
3. File fragment_doodle.xml.
4. Root Element FrameLayout Finish.
5. Advanced view ( v)
.
6. Choose Custom View Class. Create
New, New Java Class.
7. Name DoodleView. , Constructors
from superclass , Finish. DoodleView.java.
, .
DoodleView.java.
8. fragment_doodle.xml view1 Outline.
Layout Parameters Properties Width Height match_
parent.
9. Outline view1,
Edit ID, view1 doodleView OK.
10. fragment_doodle.xml.
7.3.7. fragment_color.xml
ColorDialogFragment
fragment_color.xml ColorDialogFragment
GridLayout
. ColorDialogFragment
ColorDialogFragment. fragment_color.xml,
.
270 7 Doodlz
1. res/layout Package Explorer.
2. res/layout New
Android XML File. New Android XML File.
3. File fragment_color.xml.
4. Root Element GridLayout Finish.
5. Outline GridLayout
Id @+id/colorDialogGridLayout.
6. , TextView,
SeekBar View colorDialogGridLayout Outline.
.7.4;
.
7. 6 GUI
.7.4. fragment_color.xml.
7.4. GUI fragment_color.xml
colorDialogGridLayout
Column Count
Orientation
Use Default Margins
2
vertical
true
alphaTextView
Layout Parameters
Column
Gravity
Row
Other Properties
Text
alphaSeekBar
Layout Parameters
Column
Gravity
Row
Other Properties
Max
0
right|center_vertical
0
@string/label_alpha
1
fill_horizontal
0
255
7.3. 271
redTextView
Layout Parameters
Column
Gravity
Row
Other Properties
Text
redSeekBar
greenTextView
greenSeekBar
blueTextView
blueSeekBar
colorView
Layout Parameters
Column
Gravity
Row
Other Properties
Max
Layout Parameters
Column
Gravity
Row
Other Properties
Text
Layout Parameters
Column
Gravity
Row
Other Properties
Max
Layout Parameters
Column
Gravity
Row
Other Properties
Text
Layout Parameters
Column
Gravity
Row
Other Properties
Max
Layout Parameters
Height
Column
Column Span
Gravity
0
right|center_vertical
1
@string/label_red
1
fill_horizontal
1
255
0
right|center_vertical
2
@string/label_red
1
fill_horizontal
2
255
0
right|center_vertical
3
@string/label_red
1
fill_horizontal
3
255
@dimen/color_view_height
0
2
fill_horizontal
272 7 Doodlz
ColorDialogFragment
ColorDialogFragment , .
1. com.deitel.doodlz src NewClass. New Java Class.
2. Name ColorDialogFragment.
3. Superclass android.app.DialogFragment.
4. Finish, .
7.3.8. fragment_line_width.xml
LineWidthDialogFragment
fragment_line_width.xml LineWidthDialogFragment GridLayout
. LineWidthDialogFragment
LineWidthDialogFragment. fragment_line_width.xml,
.
1. res/layout Package Explorer.
2. layout NewAndroid
XML File. New Android XML File.
3. File fragment_line_width.xml.
4. Root Element GridLayout Finish.
5. Outline GridLayout Id @+id/lineWidthDialogGridLayout.
6. , ImageView
SeekBar lineWidthDialogGridLayout Outline. , . 7.5. .
. 7.5. Outline
fragment_line_width.xml
7. 6 GUI
.7.5. fragment_line_width.xml.
7.3. 273
lineWidthDialogGridLayout
Column Count
Orientation
Use Default Margins
1
vertical
true
widthImageView
Layout Parameters
Height
Gravity
Other Properties
Content Description
widthSeekBar
Layout Parameters
Gravity
Other Properties
Max
@dimen/line_imageview_height
fill_horizontal
@string/line_imageview_description
fill_horizontal
50
LineWidthDialogFragment
LineWidthDialogFragment ,
.
1. com.deitel.doodlz src
NewClass. New
Java Class.
2. Name LineWidthDialogFragment.
3. Superclass android.app.DialogFragment.
4. Finish, .
7.3.9. EraseImageDialogFragment
EraseImageDialogFragment ,
AlertDialog . EraseImageDialog
Fragment, .
1. com.deitel.doodlz src
NewClass. New Java
Class.
2. Name EraseImageDialogFragment.
3. Superclass android.app.DialogFragment.
4. Finish, .
274 7 Doodlz
7.4. MainActivity
.
MainActivity (7.1)
DoodleView ( 7.6) , -
COLOR .
LINE WIDTH .
CLEAR
.
7.5. DoodleFragment275
21
Configuration.SCREENLAYOUT_SIZE_MASK;
22
// ,
23
// .
24
if (screenSize == Configuration.SCREENLAYOUT_SIZE_XLARGE)
25
setRequestedOrientation(
26
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
27
else
28
setRequestedOrientation(
29
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
30
}
31 } // MainActivity
7.5. DoodleFragment
DoodleFragment (7.27.9) DoodleView ( 7.6), ,
.
package, import
7.2 ,
DoodleFragment. 7.2.
doodleView DoodleView ( 22) . , 2325,
(
, ). 29 ,
,
. 26 , false;
. ,
, Choose
Color, .
7.2. DoodleFragment: package, import
1
2
3
4
5
6
7
8
9
10
11
12
// DoodleFragment.java
// , DoodleView
package com.deitel.doodlz;
import
import
import
import
import
import
import
import
android.app.Fragment;
android.content.Context;
android.graphics.Color;
android.hardware.Sensor;
android.hardware.SensorEvent;
android.hardware.SensorEventListener;
android.hardware.SensorManager;
android.os.Bundle;
276 7 Doodlz
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import
import
import
import
import
import
android.view.LayoutInflater;
android.view.Menu;
android.view.MenuInflater;
android.view.MenuItem;
android.view.View;
android.view.ViewGroup;
onCreateView
onCreateView (7.3) DoodleFragment
. , ,
.
setHasOptionsMenu true. ,
(
).
7.3. onCreateView
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
//
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
super.onCreateView(inflater, container, savedInstanceState);
View view =
inflater.inflate(R.layout.fragment_doodle, container, false);
setHasOptionsMenu(true); //
// DoodleView
doodleView = (DoodleView) view.findViewById(R.id.doodleView);
//
acceleration = 0.00f;
currentAcceleration = SensorManager.GRAVITY_EARTH;
lastAcceleration = SensorManager.GRAVITY_EARTH;
return view;
7.5. DoodleFragment277
43 DoodleView, 4648 ,
, . currentAcceleration lastAcceleration
GRAVITY_EARTH SensorManager, ,
. SensorManager
;
http://developer.android.com/reference/android/hardware/SensorManager.html
onStart enableAccelerometerListening
, DoodleFragment .
onStart ( 7.4, 5358),
enableAccelerometerListening (6172)
. SensorManager
.
7.4. onStart enableAccelerometerListening
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//
@Override
public void onStart()
{
super.onStart();
enableAccelerometerListening(); //
}
//
public void enableAccelerometerListening()
{
// SensorManager
SensorManager sensorManager =
(SensorManager) getActivity().getSystemService(
Context.SENSOR_SERVICE);
//
sensorManager.registerListener(sensorEventListener,
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL);
enableAccelerometerListening getSystemService
SensorManager, . 6971
,
registerListener SensorManager, :
278 7 Doodlz
SensorEventListener, ( -
7.6).
Sensor, , -
, getDefaultSensor
SensorManager (Sensor.TYPE_ACCELEROMETER
).
. SENSOR_DELAY_
NORMAL
, .
onPause disableAccelerometerListening
,
DoodleFragment , onPause ( 7.5; 7580),
disableAccelerometerListening ( 8393). disableAccelerometerListening
unregisterListener SensorManager .
7.5. enableAccelerometerListening disableAccelerometerListening
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
//
@Override
public void onPause()
{
super.onPause();
disableAccelerometerListening(); //
}
//
//
public void disableAccelerometerListening()
{
// SensorManager
SensorManager sensorManager =
(SensorManager) getActivity().getSystemService(
Context.SENSOR_SERVICE);
//
sensorManager.unregisterListener(sensorEventListener,
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER));
, SensorEventListener
7.6 onSensorChanged SensorEventListener
( 100125), .
,
7.5. DoodleFragment279
. ,
123 confirmErase ( 7.7),
EraseImageDialogFragment ( 7.9)
. SensorEventListener onAccuracyChanged
( 128131). ,
.
7.6. ,
SensorEventListener
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
//
private SensorEventListener sensorEventListener =
new SensorEventListener()
{
//
@Override
public void onSensorChanged(SensorEvent event)
{
//
if (!dialogOnScreen)
{
// x, y z SensorEvent
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
//
lastAcceleration = currentAcceleration;
//
currentAcceleration = x * x + y * y + z * z;
//
acceleration = currentAcceleration *
(currentAcceleration - lastAcceleration);
//
if (acceleration > ACCELERATION_THRESHOLD)
confirmErase();
}
} // onSensorChanged
// SensorEventListener
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy)
{
}
}; //
,
. onSensorChanged
, ( 104).
280 7 Doodlz
,
, .
.
SensorEvent
.
,
( /2) x (/), y (/) z (/
). , API SensorEvent,
:
developer.android.com/reference/android/hardware/SensorEvent.html
x, y z SensorEvent
.
107109. (
), . currentAcceleration 112.
115 x, y z,
currentAcceleration. currentAcceleration
lastAcceleration acceleration, ACCELERATION_THRESHOLD. , ,
. confirmErase.
confirmErase
confirmErase ( 7.7) EraseImageDialogFragment
( 7.9) show DialogFragment .
7.7. confirmErase EraseImageDialogFragment
134
135
136
137
138
139
140
//
private void confirmErase()
{
EraseImageDialogFragment fragment = new EraseImageDialogFragment();
fragment.show(getFragmentManager(), "erase dialog");
}
onCreateOptionsMenu onOptionsItemSelected
7.8 onCreateOptionsMenu Fragment
( 142147), Menu
MenuInflater . ,
onOptionsItemSelected ( 150180) .
7.5. DoodleFragment281
7.8. onCreateOptionsMenu
onOptionsItemSelected
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
//
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
{
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.doodle_fragment_menu, menu);
}
//
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
// MenuItem
switch (item.getItemId())
{
case R.id.color:
ColorDialogFragment colorDialog = new ColorDialogFragment();
colorDialog.show(getFragmentManager(), "color dialog");
return true; //
case R.id.lineWidth:
LineWidthDialogFragment widthdialog =
new LineWidthDialogFragment();
widthdialog.show(getFragmentManager(), "line width dialog");
return true; //
case R.id.eraser:
doodleView.setDrawingColor(Color.WHITE); //
return true; //
case R.id.clear:
confirmErase(); //
return true; //
case R.id.save:
doodleView.saveImage(); //
return true; //
case R.id.print:
doodleView.printImage(); //
return true; //
} // switch
return super.onOptionsItemSelected(item); //
} // onOptionsItemSelected
282 7 Doodlz
R.id.lineWidth 161163
LineWidthDialogFragment (7.8), -
EraseImageDialogFragment ( 7.9) .
printImage, PDF
getDoodleView setDialogOnScreen
getDoodleView setDialogOnScreen (7.9) DialogFragment, . getDoodleView
DoodleView ,
DialogFragment .
setDialogOnScreen
DialogFragment ; .
7.9. getDoodleView setDialogOnScreen
182
183
184
185
186
187
188
189
190
191
192
193 }
// DoodleView
public DoodleView getDoodleView()
{
return doodleView;
}
//
public void setDialogOnScreen(boolean visible)
{
dialogOnScreen = visible;
}
7.6. DoodleView
DoodleView (7.107.23)
.
7.6. DoodleView283
package import
7.10 package import, DoodleView.
.
7.2,
DoodleView.
7.10. package import DoodleView
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
// DoodleView.java
// Doodlz.
package com.deitel.doodlz;
import java.util.HashMap;
import java.util.Map;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
android.content.Context;
android.graphics.Bitmap;
android.graphics.Canvas;
android.graphics.Color;
android.graphics.Paint;
android.graphics.Path;
android.graphics.Point;
android.os.Build;
android.provider.MediaStore;
android.support.v4.print.PrintHelper;
android.util.AttributeSet;
android.view.GestureDetector;
android.view.GestureDetector.SimpleOnGestureListener;
android.view.Gravity;
android.view.MotionEvent;
android.view.View;
android.widget.Toast;
DoodleView
DoodleView ( 7.11, 3043) , ,
. 38 pathMap,
( ) c Path .
3940 previousPointMap,
, .
DoodleView.
7.11.
DoodleView
26 // ,
27 public class DoodleView extends View
28 {
284 7 Doodlz
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// ,
private static final float TOUCH_TOLERANCE = 10;
private
private
private
private
Bitmap bitmap; //
Canvas bitmapCanvas; // Bitmap
final Paint paintScreen; // Bitmap
final Paint paintLine; // Bitmap
// Path
private final Map<Integer, Path> pathMap = new HashMap<Integer, Path>();
private final Map<Integer, Point> previousPointMap =
new HashMap<Integer, Point>();
// /
private GestureDetector singleTapDetector;
doodleview
(7.12)
Map 7.11.
49 paintScreen Paint,
, 52 paintLine Paint, , .
paintLine 5357. setAntiAlias Paint
true .
, setStyle Paint Paint Paint.
Style.STROKE. STROKE, FILL FILL_AND_STROKE,
,
. , Paint.Style.FILL.
setStrokeWidth Paint. 5 .
setStrokeCap Paint (Paint.
Cap.ROUND). 6061 GestureDetector,
singleTapListener .
7.12. DoodleView
45
46
47
48
49
50
51
52
53
54
55
56
57
// DoodleView DoodleView
public DoodleView(Context context, AttributeSet attrs)
{
super(context, attrs); // View
paintScreen = new Paint(); //
//
paintLine = new Paint();
paintLine.setAntiAlias(true); //
paintLine.setColor(Color.BLACK); //
paintLine.setStyle(Paint.Style.STROKE); //
paintLine.setStrokeWidth(5); //
paintLine.setStrokeCap(Paint.Cap.ROUND); //
7.6. DoodleView285
58
59
60
61
62
63
// GestureDetector
singleTapDetector =
new GestureDetector(getContext(), singleTapListener);
onSizeChanged
DoodleView , MainActivity; ,
Bitmap, , onCreate .
onSizeChanged View (7.13),
DoodleView , .
onSizeChanged
Doodlz,
.
7.13. onSizeChanged
64
65
66
67
68
69
70
71
72
73
286 7 Doodlz
View invalidate, View. ,
onDraw View. setDrawingColor
, paintLine. setColor Paint
int, ARGB. getDrawingColor
, ColorDialogFragment.
setLineWidth paintLine . getLineWidth , LineWidthDialogFragment.
7.14. clear, setDrawingColor, getDrawingColor, setLineWidth
getLineWidth DoodleView
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
//
public void clear()
{
pathMap.clear(); //
previousPointMap.clear(); //
bitmap.eraseColor(Color.WHITE); //
invalidate(); //
}
//
public void setDrawingColor(int color)
{
paintLine.setColor(color);
}
//
public int getDrawingColor()
{
return paintLine.getColor();
}
//
public void setLineWidth(int width)
{
paintLine.setStrokeWidth(width);
}
//
public int getLineWidth()
{
return (int) paintLine.getStrokeWidth();
}
onDraw
, onDraw. 7.15 onDraw Bitmap ( ) DoodleView, drawBitmap
Canvas. Bitmap,
7.6. DoodleView287
x y Bitmap , Paint
. 115116
Path .
pathMap Path drawPath Canvas
paintLine,
.
7.15. onDraw View
107
108
109
110
111
112
113
114
115
116
117
118
//
@Override
protected void onDraw(Canvas canvas)
{
//
canvas.drawBitmap(bitmap, 0, 0, paintScreen);
//
for (Integer key : pathMap.keySet())
canvas.drawPath(pathMap.get(key), paintLine); //
288 7 Doodlz
7.16. hideSystemBars showSystemBars DoodleView
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
//
public void hideSystemBars()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_FULLSCREEN |
View.SYSTEM_UI_FLAG_IMMERSIVE);
}
//
public void showSystemBars()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
,
SimpleOnGestureListener
7.17 SimpleOnGestureListener
singleTapListener, 6061 ( 7.4) GestureDetector. , SimpleOnGestureListener -,
OnGestureListener OnDoubleTapListener.
false , . onSingleTap (146155),
. ,
( 149150), getSystemUiVisibilty View
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION.
0, , hideSystemBars;
showSystemBars. true ,
.
7.17. ,
SimpleOnGestureListener
142
143
144
145
146
7.6. DoodleView289
147
148
149
150
151
152
153
154
155
156
157
};
onTouchEvent View
onTouchEvent (7.18) . Android ,
. .
,
. Path,
, . Path
pathMap.
7.18. onTouchEvent View
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
//
@Override
public boolean onTouchEvent(MotionEvent event)
{
// ,
// KitKat
if (singleTapDetector.onTouchEvent(event))
return true;
int action = event.getActionMasked(); //
int actionIndex = event.getActionIndex(); // ()
// , : ,
// ,
if (action == MotionEvent.ACTION_DOWN ||
action == MotionEvent.ACTION_POINTER_DOWN)
{
touchStarted( event.getX(actionIndex), event.getY(actionIndex),
event.getPointerId(actionIndex));
}
else if (action == MotionEvent.ACTION_UP ||
action == MotionEvent.ACTION_POINTER_UP)
{
touchEnded(event.getPointerId(actionIndex));
}
else
{
touchMoved(event);
290 7 Doodlz
185
186
187
188
189
190
}
invalidate(); //
return true;
} // onTouchEvent
7.6. DoodleView291
//
private void touchStarted(float x, float y, int lineID)
{
Path path; //
Point point; //
// lineID Path
if (pathMap.containsKey(lineID))
{
path = pathMap.get(lineID); // Path
path.reset(); // Path
point = previousPointMap.get(lineID); // Path
}
else
{
path = new Path();
pathMap.put(lineID, path); // Path Map
point = new Point(); // Point
previousPointMap.put(lineID, point); // Point Map
}
//
path.moveTo(x, y);
point.x = (int) x;
point.y = (int) y;
} // touchStarted
touchMoved DoodleView
touchMoved ( 7.20)
. MotionEvent, onTouchEvent,
,
. getPointerCount MotionEvent (222)
, MotionEvent.
pointerID ( 225),
MotionEvent (226) pointerIndex.
Path pathMap (229).
, getX getY MotionEvent
pointerIndex. Path Point
pointerID HashMap,
Path
, TOUCH_TOLERANCE.
,
MotionEvent ,
.
, TOUCH_TOLERANCE, quadTo
Path ( 248249) (
292 7 Doodlz
) ,
.
7.20. touchMoved DoodleView
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
//
private void touchMoved(MotionEvent event)
{
// () MotionEvent
for (int i = 0; i < event.getPointerCount() ; i++)
{
//
int pointerID = event.getPointerId(i);
int pointerIndex = event.findPointerIndex(pointerID);
// Path,
if (pathMap.containsKey(pointerID))
{
//
float newX = event.getX(pointerIndex);
float newY = event.getY(pointerIndex);
// Path Point,
//
Path path = pathMap.get(pointerID);
Point point = previousPointMap.get(pointerID);
//
float deltaX = Math.abs(newX - point.x);
float deltaY = Math.abs(newY - point.y);
//
if (deltaX >= TOUCH_TOLERANCE || deltaY >= TOUCH_TOLERANCE)
{
//
path.quadTo(point.x, point.y, (newX + point.x) / 2,
(newY + point.y) / 2);
//
point.x = (int) newX;
point.y = (int) newY;
}
} // touchMoved
touchEnded DoodleView
touchEnded ( 7.21) ,
. (lineID),
. 262
Path. 263 drawPath bitmapCanvas Path
7.6. DoodleView293
//
private void touchEnded(int lineID)
{
Path path = pathMap.get(lineID); // Path
bitmapCanvas.drawPath(path, paintLine); // bitmapCanvas
path.reset(); // Path
}
saveImage DoodleView
saveImage (7.22) ,
. 271 ,
274276 , insertImage
MediaStore.Images.Media. :
ContentResolver,
Bitmap ;
;
.
insertImage ,
, null, . 278295
, , Toast.
7.22. saveImage DoodleView
267
268
269
270
271
272
273
274
275
276
277
278
279
280
//
public void saveImage()
{
// "Doodlz"
String name = "Doodlz" + System.currentTimeMillis() + ".jpg";
//
String location = MediaStore.Images.Media.insertImage(
getContext().getContentResolver(), bitmap, name,
Doodlz Drawing);
if (location != null) //
{
//
294 7 Doodlz
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
}
else
{
//
Toast message = Toast.makeText(getContext(),
R.string.message_error_saving, Toast.LENGTH_SHORT);
message.setGravity(Gravity.CENTER, message.getXOffset() / 2,
message.getYOffset() / 2);
message.show();
}
} // saveImage
printImage DoodleView
Android 4.4 printImage (7.23)
PrintHelper Android Support Library .
301 , .
, 304 PrintHelper. 307 PrintHelper.
SCALE_MODE_FIT ,
. PrintHelper.SCALE_
MODE_FILL, (,
). , 308 printBitmap PrintHelper,
( ) Bitmap .
Android,
PDF .
7.23. printImage DoodleView
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
//
public void printImage()
{
if (PrintHelper.systemSupportsPrint())
{
// PrintHelper
PrintHelper printHelper = new PrintHelper(getContext());
//
printHelper.setScaleMode(PrintHelper.SCALE_MODE_FIT);
printHelper.printBitmap(Doodlz Image, bitmap);
}
else
{
// ,
Toast message = Toast.makeText(getContext(),
7.7. ColorDialogFragment295
314
R.string.message_error_printing, Toast.LENGTH_SHORT);
315
message.setGravity(Gravity.CENTER, message.getXOffset() / 2,
316
message.getYOffset() / 2);
317
message.show();
318
}
319
}
320 } // DoodleView
7.7. ColorDialogFragment
ColorDialogFragment ( 7.247.28) DialogFragment AlertDialog, .
( 1924)
, ,
32- int, ARGB.
7.24. package, import
ColorDialogFragment
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
// ColorDialogFragment.java
// DoodleView
package com.deitel.doodlz;
import
import
import
import
import
import
import
import
import
import
android.app.Activity;
android.app.AlertDialog;
android.app.Dialog;
android.app.DialogFragment;
android.content.DialogInterface;
android.graphics.Color;
android.os.Bundle;
android.view.View;
android.widget.SeekBar;
android.widget.SeekBar.OnSeekBarChangeListener;
//
public class ColorDialogFragment extends DialogFragment
{
private SeekBar alphaSeekBar;
private SeekBar redSeekBar;
private SeekBar greenSeekBar;
private SeekBar blueSeekBar;
private View colorView;
private int color;
onCreateDialog DialogFragment
onCreateDialog (7.25)
(3234), fragment_color.xml
296 7 Doodlz
, AlertDialog,
setView AlertDialog.Builder ( 35). 4250
SeekBar colorView . 5356
colorChangedListener ( 7.28)
SeekBar.
7.25. onCreateDialog DialogFragment
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
// AlertDialog
@Override
public Dialog onCreateDialog(Bundle bundle)
{
AlertDialog.Builder builder =
new AlertDialog.Builder(getActivity());
View colorDialogView =
getActivity().getLayoutInflater().inflate(
R.layout.fragment_color, null);
builder.setView(colorDialogView); // GUI
// AlertDialog
builder.setTitle(R.string.title_color_dialog);
builder.setCancelable(true);
// SeekBar onChange
alphaSeekBar = (SeekBar) colorDialogView.findViewById(
R.id.alphaSeekBar);
redSeekBar = (SeekBar) colorDialogView.findViewById(
R.id.redSeekBar);
greenSeekBar = (SeekBar) colorDialogView.findViewById(
R.id.greenSeekBar);
blueSeekBar = (SeekBar) colorDialogView.findViewById(
R.id.blueSeekBar);
colorView = colorDialogView.findViewById(R.id.colorView);
// SeekBar
alphaSeekBar.setOnSeekBarChangeListener(colorChangedListener);
redSeekBar.setOnSeekBarChangeListener(colorChangedListener);
greenSeekBar.setOnSeekBarChangeListener(colorChangedListener);
blueSeekBar.setOnSeekBarChangeListener(colorChangedListener);
// SeekBar
final DoodleView doodleView = getDoodleFragment().getDoodleView();
color = doodleView.getDrawingColor();
alphaSeekBar.setProgress(Color.alpha(color));
redSeekBar.setProgress(Color.red(color));
greenSeekBar.setProgress(Color.green(color));
blueSeekBar.setProgress(Color.blue(color));
//
builder.setPositiveButton(R.string.button_set_color,
new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
7.7. ColorDialogFragment297
72
73
74
75
76
77
78
79
doodleView.setDrawingColor(color);
}
); // setPositiveButton
return builder.create(); //
} // onCreateDialog
// DoodleFragment
private DoodleFragment getDoodleFragment()
{
return (DoodleFragment) getFragmentManager().findFragmentById(
R.id.doodleFragment);
}
onAttach onDetach
ColorDialogFragment
onAttach ( 7.27, 8896). 92 DoodleFragment.
null, 95 setDialogOnScreen
DoodleFragment Choose
Color. ColorDialogFragment
onDetach ( 99107). 106 setDialogOnScreen
DoodleFragment, , Choose Color
.
7.27. onAttach onDetach
87
88
// DoodleFragment,
@Override
298 7 Doodlz
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// DoodleFragment,
@Override
public void onDetach()
{
super.onDetach();
DoodleFragment fragment = getDoodleFragment();
if (fragment != null)
fragment.setDialogOnScreen(false);
,
OnSeekBarChangeListener SeekBar
7.28 , OnSeekBarChangeListener ,
SeekBar Choose Color. SeekBar 7.25 (5356). onProgressChanged
(115123) SeekBar.
SeekBar (118),
119121. argb Color
SeekBar Color int.
setBackgroundColor View colorView , SeekBar.
7.28. ,
OnSeekBarChangeListener
SeekBar
109
110
111
112
113
114
115
116
117
118
119
120
121
// OnSeekBarChangeListener SeekBar
private OnSeekBarChangeListener colorChangedListener =
new OnSeekBarChangeListener()
{
//
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser)
{
if (fromUser) // SeekBar ( )
color = Color.argb(alphaSeekBar.getProgress(),
redSeekBar.getProgress(), greenSeekBar.getProgress(),
blueSeekBar.getProgress());
7.8. LineWidthDialogFragment299
122
colorView.setBackgroundColor(color);
123
}
124
125
@Override
126
public void onStartTrackingTouch(SeekBar seekBar) //
127
{
128
}
129
130
@Override
131
public void onStopTrackingTouch(SeekBar seekBar) //
132
{
133
}
134
}; // colorChanged
135 } // ColorDialogFragment
7.8. LineWidthDialogFragment
LineWidthDialogFragment ( 7.29) DialogFragment
AlertDialog, .
ColorDialogFragment,
. ImageView (22),
.
7.29. LineWidthDialogFragment
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
// LineWidthDialogFragment.java
// DoodleView
package com.deitel.doodlz;
import
import
import
import
import
import
import
import
import
import
import
import
import
android.app.Activity;
android.app.AlertDialog;
android.app.Dialog;
android.app.DialogFragment;
android.content.DialogInterface;
android.graphics.Bitmap;
android.graphics.Canvas;
android.graphics.Paint;
android.os.Bundle;
android.view.View;
android.widget.ImageView;
android.widget.SeekBar;
android.widget.SeekBar.OnSeekBarChangeListener;
//
public class LineWidthDialogFragment extends DialogFragment
{
private ImageView widthImageView;
// AlertDialog
@Override
public Dialog onCreateDialog(Bundle bundle)
300 7 Doodlz
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
AlertDialog.Builder builder =
new AlertDialog.Builder(getActivity());
View lineWidthDialogView = getActivity().getLayoutInflater().inflate(
R.layout.fragment_line_width, null);
builder.setView(lineWidthDialogView); // GUI
// the AlertDialog
builder.setTitle(R.string.title_line_width_dialog);
builder.setCancelable(true);
// ImageView
widthImageView = (ImageView) lineWidthDialogView.findViewById(
R.id.widthImageView);
// widthSeekBar
final DoodleView doodleView = getDoodleFragment().getDoodleView();
final SeekBar widthSeekBar = (SeekBar)
lineWidthDialogView.findViewById(R.id.widthSeekBar);
widthSeekBar.setOnSeekBarChangeListener(lineWidthChanged);
widthSeekBar.setProgress(doodleView.getLineWidth());
//
builder.setPositiveButton(R.string.button_set_line_width,
new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
doodleView.setLineWidth(widthSeekBar.getProgress());
}
}
); // setPositiveButton
return builder.create(); //
} // onCreateDialog
// DoodleFragment
private DoodleFragment getDoodleFragment()
{
return (DoodleFragment) getFragmentManager().findFragmentById(
R.id.doodleFragment);
}
// DoodleFragment,
@Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
DoodleFragment fragment = getDoodleFragment();
if (fragment != null)
fragment.setDialogOnScreen(true);
// DoodleFragment,
7.8. LineWidthDialogFragment301
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 }
@Override
public void onDetach()
{
super.onDetach();
DoodleFragment fragment = getDoodleFragment();
if (fragment != null)
fragment.setDialogOnScreen(false);
// OnSeekBarChangeListener SeekBar
private OnSeekBarChangeListener lineWidthChanged =
new OnSeekBarChangeListener()
{
Bitmap bitmap = Bitmap.createBitmap(
400, 100, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap); // Canvas
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser)
{
// Paint SeekBar
Paint p = new Paint();
p.setColor(
getDoodleFragment().getDoodleView().getDrawingColor());
p.setStrokeCap(Paint.Cap.ROUND);
p.setStrokeWidth(progress);
// Bitmap
bitmap.eraseColor(
getResources().getColor(android.R.color.transparent));
canvas.drawLine(30, 50, 370, 50, p);
widthImageView.setImageBitmap(bitmap);
@Override
public void onStartTrackingTouch(SeekBar seekBar)
//
{
}
@Override
public void onStopTrackingTouch(SeekBar seekBar)
//
{
}
}; // lineWidthChanged
onCreateDialog
onCreateDialog (2561)
( 3031), fragment_line_width.xml ,
302 7 Doodlz
AlertDialog, setView AlertDialog.Builder ( 32). 3940 ImageView,
. 4347 widthSeekBar,
lineWidthChanged ( 93127) SeekBar SeekBar. 5058 -
,
Set Line Width setLineWidth DoodleView. 60
AlertDialog .
,
OnSeekBarChangeListener widthSeekBar
93127 OnSeekBarChangeListener
lineWidthChanged, SeekBar Choose Line Width. 9697 Bitmap,
, . 98
Canvas Bitmap. onProgressChanged (100116) ,
SeekBar. 105109 Paint . setStrokeCap Paint (108)
(Paint.Cap.ROUND). 112113 bitmap
Android android.R.color.transparent eraseColor
Bitmap. canvas . , 115 bitmap widthImageView,
setImageBitmap ImageView.
7.9. EraseImageDialogFragment
EraseImageDialogFragment (7.30) DialogFragment AlertDialog, . ColorDialogFragment LineWidthDialogFragment,
onCreateDialog ( 1641).
AlertDialog .
2735 Erase Image , 32 clear
DoodleView . 38 Cancel
,
. 40 AlertDialog.
7.30. EraseImageDialogFragment
1 // EraseImageDialogFragment.java
2 //
7.9. EraseImageDialogFragment303
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
package com.deitel.doodlz;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.os.Bundle;
//
public class EraseImageDialogFragment extends DialogFragment
{
// AlertDialog
@Override
public Dialog onCreateDialog(Bundle bundle)
{
AlertDialog.Builder builder =
new AlertDialog.Builder(getActivity());
// AlertDialog
builder.setMessage(R.string.message_erase);
builder.setCancelable(false);
//
builder.setPositiveButton(R.string.button_erase,
new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
getDoodleFragment().getDoodleView().clear(); //
}
}
); // setPositiveButton
//
builder.setNegativeButton(R.string.button_cancel, null);
return builder.create(); //
} // onCreateDialog
// DoodleFragment
private DoodleFragment getDoodleFragment()
{
return (DoodleFragment) getFragmentManager().findFragmentById(
R.id.doodleFragment);
}
// DoodleFragment,
@Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
DoodleFragment fragment = getDoodleFragment();
304 7 Doodlz
57
if (fragment != null)
58
fragment.setDialogOnScreen(true);
59
}
60
61
// DoodleFragment,
62
@Override
63
public void onDetach()
64
{
65
super.onDetach();
66
DoodleFragment fragment = getDoodleFragment();
67
68
if (fragment != null)
69
fragment.setDialogOnScreen(false);
70
}
71 } // EraseImageDialogFragment
7.10.
Doodlz,
. : Android
SensorManager SensorEventListener,
( , Android ).
DialogFragment, AlertDialog, onAttach onDetach
,
.
, Canvas Bitmap,
Canvas Bitmap.
, .
Path. onTouchEvent View,
MotionEvent ,
. ,
Path.
, Android 4.4, ,
.
, GestureDetector
.
ContentResolver MediaStore.Images.Media.insertImage . ,
Android 4.4
7.10. 305
Address Book
AsyncTask
GUI
GUI,
8.1. 307
8.1.
Address Book (. 8.1)
, SQLite . , .
, .
. 8.1. :
a ;
( ) ,
EditText (.8.2). ( )
(. 8.3).
( ), EditText
(.8.4). Save Contact . .8.5 .
.
. 8.2. : a
;
. 8.3. : a
;
. 8.4. :
a ;
, , . .
.
EditTexts, .
Save Contact
.
8.3. 311
. .
, ,
.
8.3.
, Address Book (
).
8.3.1.
FragmentTransaction
, ,
, DialogFragment,
show. ,
. , , ,
, ,
.
FragmentManager FragmentTransaction. ,
Android , LIFO
(Last-In-First-Out) Back
Android , ,
.
8.3.2.
( )
, .
, . ,
MainActivity ,
8.3.3. onSaveInstanceState
onSaveInstanceState
, .
,
onCreate . (,
, ,
), GUI ( ,
). onSaveInstanceState 8.35.
8.3.4.
GUI
GUI XML ( 8.4.4).
, ( 8.4.7),
style. , ,
GUI,
. TextView,
.
8.3.5. TextView
, TextView . ,
Drawable android:background TextView.
Drawable ,
Drawable, XML-
( 8.4.5). Drawable drawable
textview_border.xml drawable-mdpi.
8.3.6. ListFragment
, ListView
, ListFragment ( android.app, 8.6)
8.4. 313
, ListActivity, 4.
ListFragment ListView .
ArrayAdapter
ListView CursorAdapter ( android.widget).
8.3.7. SQLite
SQLite.
SQLite (www.sqlite.org)
. , , SQLite DatabaseConnector ( 8.9).
SQLiteOpenHelper
( android.database.sqlite), SQLiteDatabase ( android.database.sqlite)
.
SQL (Structured Query Language),
Cursor ( android.database).
8.3.8.
GUI AsyncTask
( ,
, ) GUI.
ANR (Activity Not
Responding).
GUI, AsyncTask ( android.os)
GUI.
AsyncTask
, AsyncTask GUI.
8.4.
Java,
GUI.
8.4.1.
Android. New Android Project
, Finish.
8.4.2.
.
MainActivity ( 8.5) -
SQLite.
MainActivity . , com.deitel.
addressbook src.
NewClass,
.
8.4. 315
8.4.3. strings.xml
.8.1
. strings.xml res/values,
.
8.1. , Address Book
no_contacts
No Contacts
menuitem_add
Add
menuitem_edit
Edit
menuitem_delete
Delete
button_save_contact
Save Contact
hint_name
Name (Required)
hint_email
hint_phone
Phone
hint_street
Street
hint_city
City
hint_state
State
hint_zip
Zip
label_name
Name:
label_email
E-Mail:
label_phone
Phone:
label_street
Street:
label_city
City:
label_state
State:
label_zip
Zip:
confirm_title
confirm_message
ok
OK
error_message
button_cancel
Cancel
button_delete
Delete
8.4.4. styles.xml
TextView DetailsFragment,
( 8.4.7). ,
, res/values.
styles.xml .
,
GUI, , . , .
1. styles.xml res/values. ,
Resources.
2. Add, Style/Theme OK,
.
3. Name ContactLabelTextView .
4. , ContactLabelTextView.
Add OK, .
Name Value .
.8.2.
8.2. ContactLabelTextView
Name
Value
android:layout_width
wrap_content
android:layout_height
wrap_content
android:layout_gravity
right|center_vertical
5. 2 3 ContactTextView
Add, Create a new element at
the top level in Resources. 4 .8.3.
, styles.xml.
8.3. ContactTextView
Name
Value
android:layout_width
wrap_content
android:layout_height
wrap_content
android:layout_gravity
fill_horizontal
android:textSize
16sp
android:background
@drawable/textview_border
8.4. 317
8.4.5. textview_border.xml
ContactTextView, ,
TextView,
. Drawable ( )
@drawable/textview_border android:background attribute
TextView. Drawable
res/drawable-mdpi . Drawable
drawable , Android
. Drawable, .
1. res/drawable-mdpi
NewAndroid XML File.
2. File textview_border.xml, shape Finish.
3.
Drawable, XML 8.1
.
8.1. XML- Drawable,
TextView
1 <?xml version="1.0" encoding="utf-8"?>
2 <shape xmlns:android="http://schemas.android.com/apk/res/android"
3
android:shape="rectangle" >
4
<corners android:radius="5dp"/>
5
<stroke android:width="1dp" android:color="#555"/>
6
<padding android:top="10dp" android:left="10dp" android:bottom="10dp"
7
android:right="10dp"/>
8 </shape>
ContactListFragment FrameLayout.
: Id @+id/contactListFragment,
FrameLayout: Id @+id/rightPaneContainer,
2.
8.4. 319
GridLayout
GridLayout Width match_parent,
Height wrap_content, Column Count 2 Use
Default Margins true. Height ScrollView GridLayout ,
.
TextView GridLayout, .8.6.
TextView
Id TextView
.8.6. , .
Row 0 6 ( ).
Column 0.
Text strings.xml.
Style ( View) @style/ContactLabelTextView ( -
@style/).
TextView
Id TextView
.8.6. , .
Row 0 6 ( ).
Column 1.
Style ( View) @style/ContactTextView.
8.4. 321
GridLayout
GridLayout Width match_parent,
Height wrap_content, Column Count 1 Use
Default Margins true. , .8.7.
EditText
EditText Id . 8.7,
.
Width match_parent.
Height wrap_content.
Hint strings.xml.
IME Options actionNext , zipEditText (
actionDone).
@style/).
phoneEditText: phone .
emailEditText: textEmailAddress .
streetEditText: textPostalAddress|textCapWords ,
cityEditText: textPostalAddress|textCapWords.
stateEditText: textPostalAddress|textCapCharacters ,
zipEditText: number .
8.4.9.
, 7.3.4,
res/menu:
fragment_contact_list_menu.xml .
fragment_details_menu.xml -
Value
Id
@id/action_add
Order in category
Title
@string/menuitem_add
Icon
@android:drawable/ic_menu_add
Show as action
ifRoom|withText
8.5. fragment_details_menu.xml
Name
Value
Edit
Id
@id/action_edit
Order in category
Title
@string/menuitem_edit
Icon
@android:drawable/ic_menu_edit
Show as action
ifRoom|withText
Delete
Id
@id/action_delete
Order in category
Title
@string/menuitem_delete
Icon
@android:drawable/ic_delete
Show as action
ifRoom|withText
8.5. MainActivity323
8.5. MainActivity
MainActivity ( 8.28.11)
. MainActivity
ContactListFragment.
MainActivity ContactListFragment DetailsFragment, AddEditFragment 2/3 .
package, import MainActivity
MainActivity ( 8.2) FragmentTransaction ( 6) . MainActivity
.
ContactListFragment.ContactListFragmentListener
, ContactListFragment MainActivity,
.
DetailsFragment.DetailsFragmentListener ,
DetailsFragment MainActivity,
.
AddEditFragment.AddEditFragmentListener ,
AddEditFragment MainActivity, .
ROW_ID (15) ,
MainActivity . contactListFragment ( 17) ContactListFragment
.
8.2. package, import MainActivity
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// MainActivity.java
// Address Book
package com.deitel.addressbook;
import android.app.Activity;
import android.app.FragmentTransaction;
import android.os.Bundle;
public class MainActivity extends Activity
implements ContactListFragment.ContactListFragmentListener,
DetailsFragment.DetailsFragmentListener,
AddEditFragment.AddEditFragmentListener
{
// Bundle,
public static final String ROW_ID = "row_id";
ContactListFragment contactListFragment; //
// ContactListFragment MainActivity
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// , ;
// GUI .
if (savedInstanceState != null)
return;
// , fragmentContainer ( );
// ContactListFragment .
if (findViewById(R.id.fragmentContainer) != null)
{
// ContactListFragment
contactListFragment = new ContactListFragment();
// FrameLayout
FragmentTransaction transaction =
getFragmentManager().beginTransaction();
transaction.add(R.id.fragmentContainer, contactListFragment);
transaction.commit(); // ContactListFragment
8.5. MainActivity325
FragmentTransaction
ContactListFragment.
onResume MainActivity
onResume ( 8.4) contactListFragment null
, , 5557 FragmentManager
ContactListFragment MainActivity.
8.4. onResume MainActivity
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// MainActivity
@Override
protected void onResume()
{
super.onResume();
// contactListFragment null, ,
// ; FragmentManager
if (contactListFragment == null)
{
contactListFragment =
(ContactListFragment) getFragmentManager().findFragmentById(
R.id.contactListFragment);
}
onContactSelected MainActivity
onContactSelected (8.5) ContactListFragment.Con
tactListFragmentListener ContactListFragment MainActivity , .
( 65), 66
displayContact (8.6), ContactListFragment
fragmentContainer (. 8.4.6) DetailsFragment,
. 69
popBackStack FragmentManager
, 70 displayContact, rightPaneContainer (. 8.4.6) DetailsFragment
.
8.5. onContactSelected MainActivity
61
62
63
64
65
66
// DetailsFragment
@Override
public void onContactSelected(long rowID)
{
if (findViewById(R.id.fragmentContainer) != null) //
displayContact(rowID, R.id.fragmentContainer);
else //
{
getFragmentManager().popBackStack(); //
displayContact(rowID, R.id.rightPaneContainer);
}
displayContact MainActivity
displayContact (8.6) DetailsFragment FragmentTransaction . ,
Bundle, , rowID ,
DetailsFragment , .
Bundle 80. 81 putLong
ROW_ID (String) rowID
(long). 82 Bundle setArguments
Bundle (. 8.8). 8586
FragmentTransaction, 87
replace FragmentTransaction; ,
FragmentTransaction DetailsFragment , . 88
addToBackStack FragmentTransaction DetailsFragment
. , Back
, MainActivity
.
8.6. displayContact MainActivity
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
//
private void displayContact(long rowID, int viewID)
{
DetailsFragment detailsFragment = new DetailsFragment();
// rowID DetailsFragment
Bundle arguments = new Bundle();
arguments.putLong(ROW_ID, rowID);
detailsFragment.setArguments(arguments);
// FragmentTransaction DetailsFragment
FragmentTransaction transaction =
getFragmentManager().beginTransaction();
transaction.replace(viewID, detailsFragment);
transaction.addToBackStack(null);
transaction.commit(); // DetailsFragment
8.5. MainActivity327
onAddContact MainActivity
onAddContact ( 8.7) ContactListFragment.Contact
ListFragmentListener ContactListFragment MainActivity ,
. fragmentContainer , 97
displayAddEditFragment (8.8), AddEditFragment frag
mentContainer. 99 displayAddEditFragment
rightPaneContainer.
Bundle. null , .
8.7. onAddContact MainActivity
92
93
94
95
96
97
98
99
100
101
// AddEditFragment
@Override
public void onAddContact()
{
if (findViewById(R.id.fragmentContainer) != null) //
displayAddEditFragment(R.id.fragmentContainer, null);
else //
displayAddEditFragment(R.id.rightPaneContainer, null);
}
displayAddEditFragment MainActivity
displayAddEditFragment ( 8.8) , , AddEditFragment,
Bundle . null, ; Bundle ,
AddEditFragment . 105
AddEditFragment. Bundle null,
108 Fragment. 111115 FragmentTransaction,
, ,
.
8.8. displayAddEditFragment MainActivity
102
103
104
105
106
107
108
109
110
111
112
113
//
private void displayAddEditFragment(int viewID, Bundle arguments)
{
AddEditFragment addEditFragment = new AddEditFragment();
if (arguments != null) //
addEditFragment.setArguments(arguments);
// FragmentTransaction AddEditFragment
FragmentTransaction transaction =
getFragmentManager().beginTransaction();
transaction.replace(viewID, addEditFragment);
transaction.addToBackStack(null);
transaction.commit(); // AddEditFragment
onContactDeleted MainActivity
onContactDeleted (8.9) DetailsFragment.Details
FragmentListener DetailsFragment MainActivity
. 122 DetailsFragment . ,
125 updateContactList contactListFragment
.
8.9. onContactDeleted MainActivity
118
119
120
121
122
123
124
125
126
127
//
@Override
public void onContactDeleted()
{
getFragmentManager().popBackStack(); //
//
if (findViewById(R.id.fragmentContainer) == null) //
contactListFragment.updateContactList();
}
onEditContact MainActivity
onEditContact (8.10) DetailsFragment.Details
FragmentListener DetailsFragment MainActivity
, .
DetailsFragment Bundle ,
AddEditFragment . fragmentContainer, 133 displayAddEditFragment,
AddEditFragment fragmentContainer. 135 displayAddEditFragment AddEditFragment
rightPaneContainer.
8.10. onEditContact MainActivity
128
129
130
131
132
133
134
135
136
137
// AddEditFragment
@Override
public void onEditContact(Bundle arguments)
{
if (findViewById(R.id.fragmentContainer) != null) //
displayAddEditFragment(R.id.fragmentContainer, arguments);
else //
displayAddEditFragment(R.id.rightPaneContainer, arguments);
}
8.6. ContactListFragment329
onAddEditCompleted MainActivity
onAddEditCompleted (8.11) AddEditFragment.AddEdit
FragmentListener AddEditFragment MainActivity
,
. 142 AddEditFragment .
(144), 146
DetailsFragment ( ). 147
ContactListFragment, 150
rightPaneContainer.
8.11. onAddEditCompleted MainActivity
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153 }
// GUI
@Override
public void onAddEditCompleted(long rowID)
{
getFragmentManager().popBackStack(); //
if (findViewById(R.id.fragmentContainer) == null) //
{
getFragmentManager().popBackStack(); //
contactListFragment.updateContactList(); //
//
displayContact(rowID, R.id.rightPaneContainer);
8.6. ContactListFragment
ContactListFragment (8.128.21) ListFragment
ListView,
.
package import ContactListFragment
8.12 p a c k a g e i m p o r t
ContactListFragment, .
8.12. package import ContactListFragment
1
2
3
4
5
6
7
8
// ContactListFragment.java
//
package com.deitel.addressbook;
import
import
import
import
android.app.Activity;
android.app.ListFragment;
android.database.Cursor;
android.os.AsyncTask;
import
import
import
import
import
import
import
import
import
import
android.os.Bundle;
android.view.Menu;
android.view.MenuInflater;
android.view.MenuItem;
android.view.View;
android.widget.AdapterView;
android.widget.AdapterView.OnItemClickListener;
android.widget.CursorAdapter;
android.widget.ListView;
android.widget.SimpleCursorAdapter;
ContactListFragmentListener
ContactListFragment
8.13 ContactListFragment. 2330
ContactListFragmentListener , MainActivity ( 26) , ,
(29). 32
listener, (MainActivity), . contactListView (34)
ContactListFragment, ListView;
. contactAdapter
CursorAdapter, ListView .
8.13. ContactListFragmentListener
ContactListFragment
20 public class ContactListFragment extends ListFragment
21 {
22
// , MainActivity
23
public interface ContactListFragmentListener
24
{
25
//
26
public void onContactSelected(long rowID);
27
28
//
29
public void onAddContact();
30
}
31
32
private ContactListFragmentListener listener;
33
34
private ListView contactListView; // ListView ListActivity
35
private CursorAdapter contactAdapter; // ListView
36
8.6. ContactListFragment331
// ContactListFragmentListener
@Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
listener = (ContactListFragmentListener) activity;
}
// ContactListFragmentListener
@Override
public void onDetach()
{
super.onDetach();
listener = null;
}
onViewCreated ContactListFragment
ListFragment ListView, , .
ContactListFragment , . ContactListFragment
onViewCreated (8.15),
onCreateView.
8.15. onViewCreated
ContactListFragment
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
//
@Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
setRetainInstance(true); //
setHasOptionsMenu(true); //
// ,
setEmptyText(getResources().getString(R.string.no_contacts));
// ListView ListView
contactListView = getListView();
contactListView.setOnItemClickListener(viewContactListener);
contactListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
// TextView ListView
String[] from = new String[] { name };
ListView.
Cursor, , -
null, Cursor .
8.6. ContactListFragment333
.
int GUI.
0.
74 ListActivity setListAdapter
ListView CursorAdapter, ListView .
viewContactListener ListView
viewContactListener (8.16) MainActivity ,
, . 84 id ( )
onContactSelected (8.5).
8.16. viewContactListener
ListView
77
78
79
80
81
82
83
84
85
86
87
// ListView
OnItemClickListener viewContactListener = new OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id)
{
listener.onContactSelected(id); //
// MainActivity
}
}; // viewContactListener
onResume ContactListFragment
onResume (8.17)
AsyncTask ( 93) GetContactsTask (8.18),
contactAdapter
ListView ContactListFragment. execute
AsyncTask .
execute , , ,
doInBackground .
93 GetContactsTask ,
AsyncTask .
8.17. onResume ContactListFragment
88
89
90
91
// GetContactsTask
@Override
public void onResume()
{
super.onResume();
new GetContactsTask().execute((Object[]) null);
GetContactsTask
GetContactsTask (8.18) AsyncTask.
DatabaseConnector (8.9)
GUI
ListView. AsyncTask -.
doInBackground
onProgressUpdate
AsyncTask GUI -
. , Object
-.
, onPostExecute AsyncTask
( 111116), GUI
ContactListFragment AsyncTask.
AsyncTask ,
, .
8.18. GetContactsTask AsyncTask
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// GUI
private class GetContactsTask extends AsyncTask<Object, Object, Cursor>
{
DatabaseConnector databaseConnector =
new DatabaseConnector(getActivity());
// (Cursor)
@Override
protected Cursor doInBackground(Object... params)
{
databaseConnector.open();
return databaseConnector.getAllContacts();
}
// , doInBackground
@Override
8.6. ContactListFragment335
112
113
114
115
116
117
118
99100 DatabaseConnector,
( ContactListFragment). doInBackground
databaseConnector
. Cursor, getAllContacts,
onPostExecute, Cursor
changeCursor contactAdapter. ListView
ContactListFragment .
onStop ContactListFragment
onStop (8.19)
onPause, .
Cursor, ListView, , 123
getCursor CursorAdapter contactAdapter. 124 changeCursor
CursorAdapter null Cursor CursorAdapter.
127 close Cursor ,
Cursor.
8.19. onStop ContactListFragment
119
120
121
122
123
124
125
126
127
128
129
130
131
// contactAdapter
@Override
public void onStop()
{
Cursor cursor = contactAdapter.getCursor(); //
//
contactAdapter.changeCursor(null); //
if (cursor != null)
cursor.close(); //
}
super.onStop();
onCreateOptionsMenu onOptionsItemSelected
ContactListFragment
onCreateOptionsMenu (8.20, 133138)
MenuInflater fragment_contact_list_menu.xml,
//
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
{
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.fragment_contact_list_menu, menu);
}
//
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.action_add:
listener.onAddContact();
return true;
}
}
return super.onOptionsItemSelected(item); //
updateContactList ContactListFragment
updateContactList (8.21) GetContactsTask
.
8.21. updateContactList ContactListFragment
154
//
155
public void updateContactList()
156
{
157
new GetContactsTask().execute((Object[]) null);
158
}
159 } // ContactListFragment
8.7. AddEditFragment
AddEditFragment (8.228.28) .
8.7. AddEditFragment337
// AddEditFragment.java
//
package com.deitel.addressbook;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
android.app.Activity;
android.app.AlertDialog;
android.app.Dialog;
android.app.DialogFragment;
android.app.Fragment;
android.content.Context;
android.os.AsyncTask;
android.os.Bundle;
android.view.LayoutInflater;
android.view.View;
android.view.View.OnClickListener;
android.view.ViewGroup;
android.view.inputmethod.InputMethodManager;
android.widget.Button;
android.widget.EditText;
AddEditFragmentListener
8.23 AddEditFragmentListener, onAddEditCompleted, MainActivity
.
8.23. AddEditFragmentListener
23
24
25
26
27
28
29
// , MainActivity
public interface AddEditFragmentListener
{
//
public void onAddEditCompleted(long rowID);
}
AddEditFragment
8.24 .
listener AddEditFragmentListener,
, Save Contact.
contactInfoBundle null
Bundle .
3642
EditText .
8.24. AddEditFragmentListener
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// AddEditFragmentListener
@Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
listener = (AddEditFragmentListener) activity;
}
// AddEditFragmentListener
@Override
public void onDetach()
{
super.onDetach();
listener = null;
}
8.7. AddEditFragment339
onCreateView AddEditFragment
7078 onCreateView ( 8.26) EditText . getArguments Bundle ( ).
AddEditFragment MainActivity Bundle ,
.
getArguments null. Bundle ( 82),
AddEditFragment DetailsFragment,
. 8491
Bundle getLong ( 84) getString, String
EditText . 9597 (8.27) Save Contact.
8.26. onCreateView AddEditFragment
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
//
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
super.onCreateView(inflater, container, savedInstanceState);
setRetainInstance(true); //
setHasOptionsMenu(true); //
// GUI EditText
View view =
inflater.inflate(R.layout.fragment_add_edit, container, false);
nameEditText = (EditText) view.findViewById(R.id.nameEditText);
phoneEditText = (EditText) view.findViewById(R.id.phoneEditText);
emailEditText = (EditText) view.findViewById(R.id.emailEditText);
streetEditText = (EditText) view.findViewById(R.id.streetEditText);
cityEditText = (EditText) view.findViewById(R.id.cityEditText);
stateEditText = (EditText) view.findViewById(R.id.stateEditText);
zipEditText = (EditText) view.findViewById(R.id.zipEditText);
contactInfoBundle = getArguments(); // null
if (contactInfoBundle != null)
{
rowID = contactInfoBundle.getLong(MainActivity.ROW_ID);
nameEditText.setText(contactInfoBundle.getString("name"));
phoneEditText.setText(contactInfoBundle.getString("phone"));
emailEditText.setText(contactInfoBundle.getString("email"));
streetEditText.setText(contactInfoBundle.getString("street"));
cityEditText.setText(contactInfoBundle.getString("city"));
stateEditText.setText(contactInfoBundle.getString("state"));
zipEditText.setText(contactInfoBundle.getString("zip"));
}
// Save Contact
Button saveContactButton =
(Button) view.findViewById(R.id.saveContactButton);
saveContactButton.setOnClickListener(saveContactButtonClicked);
return view;
// ,
OnClickListener saveContactButtonClicked = new OnClickListener()
{
@Override
public void onClick(View v)
{
if (nameEditText.getText().toString().trim().length() != 0)
{
// AsyncTask
AsyncTask<Object, Object, Object> saveContactTask =
new AsyncTask<Object, Object, Object>()
{
@Override
protected Object doInBackground(Object... params)
{
saveContact(); //
return null;
}
@Override
protected void onPostExecute(Object result)
{
//
InputMethodManager imm = (InputMethodManager)
getActivity().getSystemService(
Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(
getView().getWindowToken(), 0);
listener.onAddEditCompleted(rowID);
}
}; // AsyncTask
8.7. AddEditFragment341
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
//
saveContactTask.execute((Object[]) null);
}
else // ,
{
DialogFragment errorSaving =
new DialogFragment()
{
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
AlertDialog.Builder builder =
new AlertDialog.Builder(getActivity());
builder.setMessage(R.string.error_message);
builder.setPositiveButton(R.string.ok, null);
return builder.create();
}
};
errorSaving.show(getFragmentManager(), "error saving contact");
}
} // onClick
}; // OnClickListener
saveContact AddEditFragment
saveContact (8.28) , EditText . 162163
DatabaseConnector, , contactInfoBundle
null. , ; 168175 EditText, insertContact
DatabaseConnector . null Bundle, .
EditText updateContact DatabaseConnector,
rowID , .
insertContact updateContact DatabaseConnector
.
8.28. saveContact AddEditFragment
158
159
160
161
162
163
164
165
166
167
168
//
private void saveContact()
{
// DatabaseConnector SQLite
DatabaseConnector databaseConnector =
new DatabaseConnector(getActivity());
if (contactInfoBundle == null)
{
//
rowID = databaseConnector.insertContact(
8.8. DetailsFragment
DetailsFragment ( 8.298.38)
,
.
package import DetailsFragment
8.29 package, import
DetailsFragment. .
8.29. package import DetailsFragment
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// DetailsFragment.java
//
package com.deitel.addressbook;
import
import
import
import
import
import
import
import
import
import
import
import
import
android.app.Activity;
android.app.AlertDialog;
android.app.Dialog;
android.app.DialogFragment;
android.app.Fragment;
android.content.DialogInterface;
android.database.Cursor;
android.os.AsyncTask;
android.os.Bundle;
android.view.LayoutInflater;
android.view.Menu;
android.view.MenuInflater;
android.view.MenuItem;
8.8. DetailsFragment343
18
19
20
21
22
23
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class DetailsFragment extends Fragment
{
DetailsFragmentListener
8.30 DetailsFragmentListener, , MainActivity
( 28)
(31).
8.30. DetailsFragmentListener
24
25
26
27
28
29
30
31
32
33
// , MainActivity
public interface DetailsFragmentListener
{
//
public void onContactDeleted();
// Bundle
// c .
public void onEditContact(Bundle arguments);
}
DetailsFragment
8.31 . 34
listener, (MainActivity),
DetailsFragmentListener. rowID
. TextView
( 3743) .
8.31. DetailsFragment
34
35
36
37
38
39
40
41
42
43
44
//
//
//
//
//
//
//
//
rowID
// DetailsFragmentListener
@Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
listener = (DetailsFragmentListener) activity;
}
// DetailsFragmentListener
@Override
public void onDetach()
{
super.onDetach();
listener = null;
}
onCreateView DetailsFragment
onCreateView (8.33) rowID ( 7079). , rowID
savedInstanceState;
Bundle . 8293
TextView.
8.33. onCreateView DetailsFragment
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
//
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
super.onCreateView(inflater, container, savedInstanceState);
setRetainInstance(true); //
// , rowID
if (savedInstanceState != null)
rowID = savedInstanceState.getLong(MainActivity.ROW_ID);
else
{
// rowID
Bundle arguments = getArguments();
if (arguments != null)
rowID = arguments.getLong(MainActivity.ROW_ID);
// DetailsFragment
8.8. DetailsFragment345
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
View view =
inflater.inflate(R.layout.fragment_details, container, false);
setHasOptionsMenu(true); //
// EditText
nameTextView = (TextView) view.findViewById(R.id.nameTextView);
phoneTextView = (TextView) view.findViewById(R.id.phoneTextView);
emailTextView = (TextView) view.findViewById(R.id.emailTextView);
streetTextView = (TextView) view.findViewById(R.id.streetTextView);
cityTextView = (TextView) view.findViewById(R.id.cityTextView);
stateTextView = (TextView) view.findViewById(R.id.stateTextView);
zipTextView = (TextView) view.findViewById(R.id.zipTextView);
return view;
onResume DetailsFragment
onResume (8.34)
AsyncTask ( 102) LoadContactTask (8.37),
. execute
rowID .
102 LoadContactTask , ,
AsyncTask .
8.34. onResume DetailsFragment
97
98
99
100
101
102
103
104
// DetailsFragment
@Override
public void onResume()
{
super.onResume();
new LoadContactTask().execute(rowID); // rowID
}
onSaveInstanceState DetailsFragment
onSaveInstanceState ( 8.35) rowID
,
.
GUI , , , Bundle,
onSaveInstanceState.
8.35. onSaveInstanceState
DetailsFragment
105
106
107
// rowID
@Override
public void onSaveInstanceState(Bundle outState)
{
}
super.onSaveInstanceState(outState);
outState.putLong(MainActivity.ROW_ID, rowID);
onCreateOptionsMenu onOptionsItemSelected
DetailsFragment
DetailsFragment . onCreateOptionsMenu (8.36, 114119) fragment_details_menu.xml. onOptionsItemSelected
(122146) MenuItem
, .
R.id.action_edit, 129137 Bundle , 138 Bundle
DetailsFragmentListener AddEditFragment.
R.id.action_delete, 141 deleteContact (8.38).
8.36. onCreateOptionsMenu
onOptionsItemSelected DetailsFragment
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
//
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
{
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.fragment_details_menu, menu);
}
//
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.action_edit:
// Bundle
Bundle arguments = new Bundle();
arguments.putLong(MainActivity.ROW_ID, rowID);
arguments.putCharSequence("name", nameTextView.getText());
arguments.putCharSequence("phone", phoneTextView.getText());
arguments.putCharSequence("email", emailTextView.getText());
arguments.putCharSequence("street", streetTextView.getText());
arguments.putCharSequence("city", cityTextView.getText());
arguments.putCharSequence("state", stateTextView.getText());
arguments.putCharSequence("zip", zipTextView.getText());
listener.onEditContact(arguments); // Bundle
//
return true;
case R.id.action_delete:
8.8. DetailsFragment347
141
142
143
144
145
146
147
}
}
deleteContact();
return true;
return super.onOptionsItemSelected(item);
LoadContactTask
LoadContactTask ( 8.37) AsyncTask.
DatabaseConnector (8.9)
. -.
Long ,
Object ,
onProgressUpdate AsyncTask. .
Cursor , onPostExecute
AsyncTask.
8.37. LoadContactTask
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
// GUI
private class LoadContactTask extends AsyncTask<Long, Object, Cursor>
{
DatabaseConnector databaseConnector =
new DatabaseConnector(getActivity());
//
@Override
protected Cursor doInBackground(Long... params)
{
databaseConnector.open();
return databaseConnector.getOneContact(params[0]);
}
// , doInBackground
@Override
protected void onPostExecute(Cursor result)
{
super.onPostExecute(result);
result.moveToFirst(); //
//
int nameIndex = result.getColumnIndex(name);
int phoneIndex = result.getColumnIndex("phone");
int emailIndex = result.getColumnIndex("email");
int streetIndex = result.getColumnIndex("street");
int cityIndex = result.getColumnIndex("city");
8.8. DetailsFragment349
. , DialogFragment AsyncTask
. Delete,
222223 DatabaseConnector. 226241
AsyncTask, ( 244) Long,
, doInBackground,
. 232 deleteContact DatabaseConnector
. doInBackground , 239 onContactDeleted ,
MainActivity DetailsFragment .
8.38. deleteContact DialogFragment
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
//
private void deleteContact()
{
// FragmentManager confirmDelete
confirmDelete.show(getFragmentManager(), "confirm delete");
}
// DialogFragment
private DialogFragment confirmDelete =
new DialogFragment()
{
// AlertDialog
@Override
public Dialog onCreateDialog(Bundle bundle)
{
// Builder AlertDialog
AlertDialog.Builder builder =
new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.confirm_title);
builder.setMessage(R.string.confirm_message);
// OK
builder.setPositiveButton(R.string.button_delete,
new DialogInterface.OnClickListener()
{
@Override
public void onClick(
DialogInterface dialog, int button)
{
final DatabaseConnector databaseConnector =
new DatabaseConnector(getActivity());
// AsyncTask
AsyncTask<Long, Object, Object> deleteTask =
new AsyncTask<Long, Object, Object>()
{
@Override
protected Object doInBackground(Long... params)
{
databaseConnector.deleteContact(params[0]);
8.9. DatabaseConnector
DatabaseConnector (8.398.46) SQLite UserContacts,
contacts.
package, import
8.39 package , import
DatabaseConnector. import , 8.3. DATABASE_NAME
(16) .
, . SQLiteDatabase (18)
SQLite /. DatabaseOpenHelper
( 19) ,
SQLiteOpenHelper; ,
(, ).
SQLiteOpenHelper 8.46.
8.39. package, import
DatabaseConnector
1 // DatabaseConnector.java
2 //
// UserContacts.
3 package com.deitel.addressbook;
8.9. DatabaseConnector351
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import
import
import
import
import
import
import
android.content.ContentValues;
android.content.Context;
android.database.Cursor;
android.database.SQLException;
android.database.sqlite.SQLiteDatabase;
android.database.sqlite.SQLiteOpenHelper;
android.database.sqlite.SQLiteDatabase.CursorFactory;
// DatabaseConnector
public DatabaseConnector(Context context)
{
// DatabaseOpenHelper
databaseOpenHelper =
new DatabaseOpenHelper(context, DATABASE_NAME, null, 1);
}
//
public void open() throws SQLException
{
// /
database = databaseOpenHelper.getWritableDatabase();
}
//
public void close()
{
}
if (database != null)
database.close(); //
insertContact DatabaseConnector
insertContact ( 8.41)
.
ContentValues (4754),
.
5658 ,
. insert SQLiteDatabase (57) ContentValues , ,
"contacts" . ,
, nullColumnHack; ,
SQLite
insert ContentValues. ,
ContentValues,
nullColumnHack , NULL.
8.41. insertContact DatabaseConnector
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//
public long insertContact(String name, String phone, String email,
String street, String city, String state, String zip)
{
ContentValues newContact = new ContentValues();
newContact.put(name, name);
newContact.put("phone", phone);
newContact.put("email", email);
newContact.put("street", street);
newContact.put("city", city);
newContact.put("state", state);
newContact.put("zip", zip);
open(); //
long rowID = database.insert(contacts, null, newContact);
close(); //
return rowID;
} // insertContact
updateContact DatabaseConnector
updateContact (8.42) insertContact, , update SQLiteDatabase (76)
. update
SQL WHERE ( WHERE),
. .
8.9. DatabaseConnector353
//
public void updateContact(long id, String name, String phone,
String email, String street, String city, String state, String zip)
{
ContentValues editContact = new ContentValues();
editContact.put("name", name);
editContact.put("phone", phone);
editContact.put("email", email);
editContact.put("street", street);
editContact.put("city", city);
editContact.put("state", state);
editContact.put("zip", zip);
open(); //
database.update("contacts", editContact, "_id=" + id, null);
close(); //
getAllContacts
getAllContacts ( 8.43) query SqLiteDatabase
( 8384) , . :
, ;
String (_id name )
cnull ,
( , );
String , WHERE
?, null, WHERE ;
null, .
Cursor, query, , ( ).
//
public Cursor getAllContacts()
{
return database.query(contacts, new String[] {_id, name},
null, null, null, null, name);
}
getOneContact
getOneContact (8.44) query SqLite
Database . .
8.44. getOneContact DatabaseConnector
87
88
89
90
91
92
93
//
public Cursor getOneContact(long id)
{
return database.query(
contacts, null, _id= + id, null, null, null, null);
}
deleteContact
deleteContact (8.45) delete SqLiteDatabase
( 98) . .
, , WHERE (
WHERE) WHERE
, WHERE (null ).
8.45. deleteContact DatabaseConnector
94
95
96
97
98
99
100
101
// ,
public void deleteContact(long id)
{
open(); //
database.delete(contacts, _id= + id, null);
close(); //
}
DatabaseOpenHelper
DatabaseOpenHelper (8.46) SQLiteOpenHelper,
8.9. DatabaseConnector355
. (105109)
, .
, .
null
.
CursorFactory null ,
CursorFactory, SQLite (
).
( 1).
onCreate onUpgrade .
, onCreate DatabaseOpenHelper
. , ,
, onUpgrade DatabaseOpenHelper
(,
).
8.46. DatabaseOpenHelper
102
private class DatabaseOpenHelper extends SQLiteOpenHelper
103
{
104
//
105
public DatabaseOpenHelper(Context context, String name,
106
CursorFactory factory, int version)
107
{
108
super(context, name, factory, version);
109
}
110
111
// contacts
112
@Override
113
public void onCreate(SQLiteDatabase db)
114
{
115
// contacts
116
String createQuery = "CREATE TABLE contacts" +
117
"(_id integer primary key autoincrement," +
118
"name TEXT, phone TEXT, email TEXT, " +
119
"street TEXT, city TEXT, state TEXT, zip TEXT);";
120
121
db.execSQL(createQuery); //
122
}
123
124
@Override
125
public void onUpgrade(SQLiteDatabase db, int oldVersion,
126
int newVersion)
127
{
128
}
129
} // DatabaseOpenHelper
130 } // DatabaseConnector
8.10.
Address Book, , ,
, SQLite. GUI XML- style,
, , style. TextView,
Drawable android:background TextView, Drawable
XML- . Android
.
, , , ListFragment , ListView.
,
.
CursorAdapter, .
FragmentTransaction
GUI. Back,
,
.
8.10. 357
, ( ) , .
Bundle.
SQLiteOpenHelper
SQLiteDatabase,
. Cursor
. AsyncTask
GUI GUI,
Android
.
9 Android. , Google
Play, ;
Google Play.
, .
.
,
.
Google Play , .
Google Play
,
Google Play
Google Wallet
Google Play
Play Store
Android
,
9.2. 359
9.1.
28 Android.
( , Android),
Google Play(/ )
. ,
Google Play Google Wallet,
. ,
Google Play. Android , ,
.
, Android.
,
. ,
Android .
9.2.
Preparing for Release Dev Guide (http://developer.android.
com/tools/publishing/preparing.html) ,
Google Play. :
Android.
End User License Agreement
( ).
.
(, 1.0, 1.1, 2.0, 2.3, 3.0).
.
.
9.2.1.
Google Play,
. ,
Android .
Google Play Developer Console - - Google+.
https://play.google.com/apps/publish/
9.2.2.
EULA (End User License Agreement). , .
,
, , .. ,
EULA . EULA
http://www.rocketlawyer.com/document/end-user-license-agreement.rl
9.2.3.
(), Google Play .
, . Android Asset Studio
http://android-ui-utils.googlecode.com/hg/asset-studio/dist/index.html
:
xx-high (XXHDPI): 144144 ;
x-high (XHDPI): 9696 ;
high (HDPI): 7272 ;
medium (MDPI): 4848 .
,
Google Play. :
512512 ;
9.2. 361
32- PNG;
1 .
,
. , ,
. .9.1 ,
. ,
AndroidManifest.xml, android:icon android:label
application.
9.1. ,
URL-
glyphlab
http://www.glyphlab.com/icon_design/
Androidicons
http://www.androidicons.com
,
200
,
Iconiza
http://www.iconiza.com
Aha-Soft
http://www.aha-soft.com/icon-design.
htm
Rosetta
http://icondesign.rosetta.com/
Elance
http://www.elance.com
9.2.4.
( ) ( , Google Play)
. ,
1.0, 1.1 1.2,
2.0. ,
1 1 . Versioning Your Applications
http://developer.android.com/tools/publishing/versioning.html
9.2.5.
Google Play , . ,
,
.
http://developer.android.com/google/play/licensing/index.html
9.2.6.
, Google Play, ,
.
ProGuard ( )
.apk ( Android,
),
,
1. ProGuard
http://developer.android.com/tools/help/proguard.html
http://www.techrepublic.com/blog/app-builder/protect-your-android-apps-withobfuscation/1724
9.2.7.
, Google Play
, .apk , .
, ..
(, , );
( ). Eclipse
. Google
http://developer.android.com/tools/help/proguard.html#enabling
9.2. 363
Play, 365 .
Signing
Your Applications
http://developer.android.com/tools/publishing/app-signing.html
9.2.8.
, Google Play (. 9.2),
, 7- 10- .
,
(
15 ).
,
.
9.2.
320 ,
3840 ( )
24
PNG
JPEG
- ()
5. , , Save
.
6. ,
Refresh Device Screen
Capture window.
9.2.9.
Google Play ULR , YouTube. .9.3
. , . .
.9.4 ( , ).
, YouTube. Upload .
9.3. : ? 365
URL
Temple Run: Oz
http://www.youtube.com/watch?v=QM9sT1ydtj0
http://www.youtube.com/watch?v=2Z9OPICdgoA
http://www.youtube.com/watch?v=YqDczawTsYw
http://www.youtube.com/watch?v=rLn697AszGs
Zappos.com
http://www.youtube.com/watch?v=U-oNyK9kl_Q
Megopolis International
http://www.youtube.com/watch?v=JrqeEJ1xzCY
9.4.
URL
Animoto
http://animoto.com
Apptamin
http://www.apptamin.com
http://windows.microsoft.com/en-us/windows-live/
movie-maker
CamStudio
http://camstudio.org
Jing
http://www.techsmith.com/jing.html
Camtasia Studio
http://www.techsmith.com/camtasia.html
TurboDemo
http://www.turbodemo.com/eng/index.php
9.3. :
?
, Google
Play. ,
.
, ,
, . .9.5
.
Google Play
Android
(. 9.5)
, (. 9.4)
,
9.3.1.
. ,
AppBrain (http://www.appbrain.com), - $1,54, - $6.47.1
, ,
,
.
, .
?
? ?
, , ?
?
- ,
.
.
Google Play Google Wallet (http://google.com/wallet),
(AT&T, Sprint T-Mobile)
, . Google Wallet
.2
, Google Play.
http://www.appbrain.com/stats/android-market-app-categories
http://support.google.com/googleplay/android-developer/answer/137997?hl=en&ref_
topic=15867
9.3. : ? 367
9.3.2.
80% Android , .1
, , . , ,
.
,
Google Play .
(. 9.5). , AdMob,
.2
, (. 9.6).
9.6. , Android
Amazon Mobile
Amazon
Bank of America
Best Buy
Best Buy
CNN
Epicurious Recipe
,
Cond Nast, Gourmet
Bon Appetit
ESPN ScoreCenter
(
)
NFL Mobile
NFL, , NFL
http://www.gartner.com/newsroom/id/2592315
1
2
http://metrics.admob.com/wp-content/uploads/2009/08/AdMob-Mobile-Metrics-July-09.pdf
UPS Mobile
,
,
NYTimes
Pocket Agent
Progressive Insurance
, ,
USA Today
USA Today
, ,
9.4.
,
,
, -. , AdMob (http://www.admob.com/) Google AdSense for Mobile
(http://www.google.com/mobileads/publisher_home.html), ,
(. 9.13).
.
. ,
,
, , ,
.
9.5. 369
9.5.
,
http://developer.android.com/google/play/billing/billing_integrate.html
http://android-developers.blogspot.com/2012/05/in-app-subscriptions-in-google-play.html
http://www.businessinsider.com/its-morning-in-venture-capital-2012-5?utm_source=
readme&utm_medium=rightrail&utm_term=&utm_content=6&utm_campaign=recirc
http://developer.android.com/training/in-app-billing/index.html
,
(. 9.11),
. ,
API (. 9.8),
Google Play . (, ).
- , ,
, , .
.
25 45 % .
9.8. ,
URL
PayPal Mobile
Payments Library
http://developer.paypal.com/
webapps/developer/docs/
classic/mobile/gs_MPL/
Pay
with PayPal,
PayPal,
Pay
Amazon In-App
Purchasing
http://developer.amazon.com/
sdk/in-app-purchasing.html
,
Amazon App Store for Android
Zong
http://www.zong.com/android
Buy ,
.
Samsung In-App
Purchase
http://developer.samsung.com/ android/tools-sdks/In-App,
Purchase-Library
Samsung
Boku
http://www.boku.com
Pay by
Mobile, , ,
,
-
,
18
;
http://support.google.com/googleplay/android-developer/answer/150324?hl=en&ref_
topic=15867
;
, Google -
;
,
, , ,
.
9.10. , Google Wallet
Google Wallet
. Google Play .1 Google 70% .
Google Wallet ,
(, ,
).
.
http://checkout.google.com/termsOfService?type=SELLER
, -
Google Play.
Google Play,
Google, ( ).
180 120
, 24- PNG JPEG .
(
).
, Google Play ( ). -
URL- (,
YouTube c ).
:
1. . , . ,
(. 9.11).
2. , Google Play ( 30 ).
Android.
9.11. Google Play
()
()
()
(
)
()
()
()
()
()
9.11. Android375
.
Play Store.
Play Store. -,
Google Play , , . ,
, Google Play,
, .
, Play Store,
, .
-,
Play Store.
, Play Store ,
Linking Your Products
http://developer.android.com/distribute/googleplay/promote/linking.html
9.11. Android
Google Play, (. 9.12) -
, AndroidLicenser (http://www.androidlicenser.com).
http://developer.android.com/tools/publishing/publishing_overview.html
URL
Amazon Appstore
http://developer.amazon.com/welcome.html
http://apps.opera.com/en_us/index.php
Moborobo
http://www.moborobo.com
Appitalism
http://www.appitalism.com/index.html
Samsung Apps
http://apps.samsung.com/mars/main/getMain.as
GetJar
http://www.getjar.com
SlideMe
http://www.slideme.org
Handango
http://www.handango.com
Mplayit
http://www.mplayit.com
AndroidPit
http://www.androidpit.com
9.12.
URL
Android
http://developer.android.com
58%
17%
http://www.abiresearch.com/press/android-will-account-for-58-of-smartphone-app-down.
9.13. 377
URL
iOS (Apple)
http://developer.apple.com/ios
33%
75%
Windows Phone 8
http://developer.windowsphone.com
4%
2%
BlackBerry (RIM)
http://developer.blackberry.com
3%
Amazon Kindle
http://developer.amazon.com
4%
9.13.
.1
,
Facebook, Twitter YouTube. .
Pew Research Center, 72%
, 67% Facebook.2 . 9.14 .
.
9.14.
URL
http://www.facebook.com
http://www.twitter.com
Google+
http://plus.google.com
Groupon
http://www.groupon.com
Foursquare
http://www.foursquare.com
http://www.pinterest.com
YouTube
http://www.youtube.com
http://www.linkedin.com
Flickr
http://www.flickr.com
http://pewinternet.org/Commentary/2012/March/Pew-Internet-Social-Networking-full-detail.
aspx
http://expandedramblings.com/index.php/by-the-numbers-17-amazing-facebook-stats/
http://www.statisticbrain.com/twitter-statistics/
9.13. 379
,
.
. Google Play,
. ,
.
,
(. 9.15), .
(. 9.3). ,
,
.
YouTube (. 9.16).
9.15. , Android
URL
Android Tapp
http://www.androidtapp.com
Appolicious
http://www.androidapps.com
AppBrain
http://www.appbrain.com
AndroidZoom
http://www.androidzoom.com
Appstorm
http://android.appstorm.net
http://www.bestandroidappsreview.com
http://www.androidappreviewsource.com
Androinica
http://www.androinica.com
AndroidLib
http://www.androlib.com
Android and Me
http://www.androidandme.com
AndroidGuys
http://www.androidguys.com/category/reviews
Android Police
http://www.androidpolice.com
AndroidPIT
http://www.androidpit.com
Phandroid
http://www.phandroid.com
URL
http://dailyappshow.com
http://crazymikesapps.com
Appolicious
http://www.appvee.com/?device_filter=android
Life of Android
http://www.lifeofandroid.com/video/
http://www.androidvideoreview.net/
-
,
. ,
Web 2.0, , ,
RSS- PR-. . 9.17
-, , -,
- .
9.17. PR-
URL
PRWeb
http://www.prweb.com
- ( )
ClickPress
http://www.clickpress.com
( ). ClickPress,
.
ClickPress
-
PRLog
http://www.prlog.org/pub/
i-Newswire
http://www.i-newswire.com
openPR
http://www.openpr.com
http://www.prleap.com
PR Leap
9.13. 381
URL
Marketwire
http://www.marketwire.com
-,
: , . .
Mobility PR
http://www.mobilitypr.com
, ,
Press Release
Writing
http://www.press-releasewriting.com
-, : ,
- ..
-
(, , ,
) . (. 9.18)
, Android ( ). , , (, Android, iPhone,
BlackBerry ) . ,
, .
9.18.
URL
AdMob (Google)
http://www.admob.com/
Medialets
http://www.medialets.com
Tapjoy
http://www.tapjoy.com
Nexage
http://www.nexage.com
Jumptap
http://www.jumptap.com
Smaato
http://www.smaato.com
mMedia
http://mmedia.com
InMobi
http://www.inmobi.com
Flurry
http://www.flurry.com
(, ..).
9.14.
Google Play Google Wallet, . ,
Google Play,
Android, , AndroidManifest.xml. , Google
Play, ,
.
. ,
, Google Play.
http://www.insidemobileapps.com/2012/12/14/ios-leads-the-pack-in-ecpm-traffic-and-revenueon-operas-mobile-ad-platform-ipad-average-ecpm-of-4-42/
http://paidcontent.org/2012/01/05/419-jumptap-android-the-most-popular-but-ios-still-moreinteractive-for-ads/
. , . , .
Android
.
.
.
.
. , .
.
, 192102, -, . (. ), 3, , . 7.
034-2014, 58.11.12.000
, .
06.03.15. 70100/16. . . . 30,960. 1200. 0000.
142300, , . , . , 1.
: www.chpk.ru. E-mail: marketing@chpk.ru
: 8(496) 726-54-10, : (495) 988-63-87