Android Application Model I - Ohio State University

Transcription

Android Application Model ICSE 5236: Mobile Application DevelopmentInstructor: Adam C. Champion, Ph.D.Course Coordinator: Dr. Rajiv RamnathReading: Big Nerd Ranch Guide, Chapters 3, 5 (Activities);Chapter 13 (menus)1

AndroidFrameworkSupport2

Framework Capabilities and Add-Ons Built-In Services:– GUI– OS services (file I/O, threads, device management)– Graphics– Device access (GPS, camera, media players, sensors),– Networking– Standard language libraries Add-ons:– Google Play services (e.g. Google Maps, Games, etc.)– Database support (SQLite)– WebKit/Chromium3

Tooling SupportIDE: Android StudioTesting tools: JUnit, EspressoPerformance profilers: Android ProfilerSource code management: Git,Subversion, CVS, etc. Software emulators: Android emulator,Intel HAXM, Genymotion Sensor injection via emulator 4

Android Studio Project Components5

Types of Android Programs Applications– Home app, Home screen– Take over screen Services: Run in the background without UI App widgets and home screen widgets– View-only interface to a service– Home screen widget if on Home screen All apps have Activities: key parts of anyAndroid app6

Activities inTic-Tac-Toe7

Specifying Activities: AndroidManifest.xml activity android:name ".SplashScreen"android:label "@string/app name"android:screenOrientation "portrait" intent-filter action android:name "android.intent.action.MAIN"/ category android:name "android.intent.category.LAUNCHER”/ /intent-filter /activity activity android:name ".Login"android:label "@string/app name"android:launchMode "singleInstance"android:screenOrientation "portrait" intent-filter actionandroid:name "com.wiley.fordummies.androidsdk.Login"/ category android:name "android.intent.category.DEFAULT"/ /intent-filter /activity 8

Implementing ActivitiesJavaKotlinSingleFragmentActivity {class LoginActivity :SingleFragmentActivity()/* . */{public class LoginActivity extends/* . */}.public class GameSessionActivityextends SingleFragmentActivity {/*. */}.class GameSessionActivity :SingleFragmentActivity(){}/* . */}9Note: SingleFragmentActivity extends AppCompatActivity

Activity UI Widgets View and ViewGroup Package android.view Specified declaratively in layout files Later: always use Fragments (even forsimple Activities)10

Sample Layout: Login Activity ?xml version "1.0" encoding "utf-8"? ScrollView xmlns:android oid:background "@color/background"android:orientation "horizontal"android:layout width "fill parent"android:layout height "fill parent"android:padding "20dip" LinearLayout android:orientation "vertical. . . TextView android:text "@string/login title” / TextView . . . / EditText . . . / TextView . . . / EditText . . . / Button . . . / Button . . . / Button . . . / /LinearLayout /ScrollView 11 project /app/src/main/res/layout/fragment login.xml

Views, ViewGroups, Layouts, Widgets Many types of views, layouts and widgets:– ScrollView, HorizontalScrollView– LinearLayout, AbsoluteLayout, FrameLayout,RelativeLayout– TextView, EditText, Button, DatePicker, Spinner Nested nature of layout– ViewGroup base class for composite elements– View base class for terminal UI components Layout files “compiled” into resource R class inres subtree12

Implement UI Logic: Listener Objects: Javapublic class LoginActivity extends SingleFragmentActivity {// Create LoginFragment in onCreate() method. (See SingleFragmentActivity)}public class LoginFragment extends Fragment implements View.OnClickListener {private EditText mUsernameEditText;private EditText mPasswordEditText; /* . */@Overridepublic View onCreateView(. . .) {// The real code has null checks, screen rotation check (omitted for brevity)View v inflater.inflate(R.layout.fragment login, container, false);mUsernameEditText v.findViewById(R.id.username text);mPasswordEditText v.findViewById(R.id.password text);Button loginButton v.findViewById(R.id.login button); /* . */loginButton.setOnClickListener(this);Button cancelButton v.findViewById(R.id.cancel button); /* . */cancelButton.setOnClickListener(this);Button newUserButton v.findViewById(R.id.new user button); /* . */newUserButton.setOnClickListener(this);return v;}13

Impl. UI Logic: Listener Objects: Kotlinclass LoginActivity : SingleFragmentActivity() {// Create LoginFragment in onCreate() method. (See SingleFragmentActivity)}class LoginFragment : Fragment(), View.OnClickListener {private lateinit var mUsernameEditText: EditTextprivate lateinit var mPasswordEditText: EditText /* . . . */override fun onCreateView(. . . ): View? {// Similarly, real code has checks (omitted for brevity)val v inflater.inflate(R.layout.fragment login, container, false)mUsernameEditText v.findViewById(R.id.username text)mPasswordEditText v.findViewById (R.id.password text)val loginButton v.findViewById(R.id.login button)loginButton.setOnClickListener(this)val cancelButton v.findViewById(R.id.cancel button)cancelButton.setOnClickListener(this)val newUserButton v.findViewById(R.id.new user n v} // . . .14

The OnClick HandlerJavapublic void onClick(View v) {switch (v.getId()) {case R.id.login button:checkLogin();break;case R.id.cancel button:Kotlinoverride fun onClick(view: View) {when (view.id) {R.id.login button - checkLogin()R.id.cancel button - activity?.finish()R.id.new user button - val fm place(/* container */, fragment)?.addToBackStack(. . .)?.commit()break;case R.id.new user button:FragmentManager fm getFragmentManager();Fragment fragment new AccountFragment();fm.beginTransaction().replace(/* container */, fragment).addToBackStack("account fragment").commit();break;} // Null check code omitted}}}Kotlin’s operator ?. is short for:if (object ! null) {object.method()15}

Embedding View: GameSession Activity,Fragment: Javapublic class GameSessionActivity extends SingleFragmentActivity {. . .}public class GameSessionFragment extends Fragment {. . .} ?xml version "1.0" encoding "utf-8"? LinearLayout xmlns:android "http://schemas.android.com/apk/res/android” . . LinearLayout. com.wiley.fordummies.androidsdk.Boardandroid:id "@ id/board"android:layout width "fill parent"android:layout height "fill parent"/ /LinearLayout TextView . "/ TextView . "/ 16 /LinearLayout

Embedding a View: GameSessionActivity, Fragment: Kotlinclass GameSessionActivity : SingleFragmentActivity() {}class GameSessionFragment : Fragment() {} !-- Same XML as before -- 17

Embedding a View: Board ClassJava// Board.javapublic class Board extends View {. . .public boolean onTouchEvent(MotionEvent event) {. . .switch (action) {case MotionEvent.ACTION DOWN:/* . . . */break;}return super.onTouchEvent(event);}}Kotlin// Board.ktclass Board : View {. . .override fun onTouchEvent(event: MotionEvent): Boolean {. . .when (action) {MotionEvent.ACTION DOWN - { . . . }}return super.onTouchEvent(event)}}18

Handling UI in the Activity Activity also a View Can handle UI without any widgets.Why?– Handle non-widget-specific events (touch)– Handle user interaction outside theboundaries of any UI components– See onTouchEvent method inSplashScreenFragment class.19

Option Menus and Action Bars Declare the menu items Define onCreateOptionsMenu() and/oronCreateContextMenu() callback methods inActivity. Automatically called to create themenu (what if it doesn’t exist?). Implement onOptionsItemSelected()and/or onContextItemSelected() in activity.20

Menu Layout File ?xml version "1.0" encoding "utf-8"? menu xmlns:android "http://schemas.android.com/apk/res/android" item android:title "Settings"android:id "@ id/menu settings"android:icon "@android:drawable/ic menu preferences” / item android:title "Help"android:id "@ id/menu help"android:icon "@android:drawable/ic menu info details” / item android:title "Exit"android:id "@ id/menu exit"android:icon "@android:drawable/ic menu close clear cancel" / item android:title "Contacts"android:id "@ id/menu contacts"android:icon "@android:drawable/ic menu view" / /menu Action Bar: Declare menu item with additional attribute21android:showAsAction "ifRoom", "never", "withText", or "always".

Menu Creation: Javapublic class GameOptionsFragment {.public View onCreateView( ) { // . . .setHasOptionsMenu(true);}.public boolean onCreateOptionsMenu(Menu menu) {super.onCreateOptionsMenu(menu, inflater);inflater.inflate(R.menu.menu, menu);}.}22

Menu Creation: Kotlinclass GameOptionsFragment {. . .override fun onCreateView( ) { // . . .setHasOptionsMenu(true);}. . .override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {super.onCreateOptionsMenu(menu, inflater)inflater.inflate(R.menu.menu ingame, menu)}}23

Menu Handlers: Javapublic boolean onOptionsItemSelected(MenuItem item) {Activity activity getActivity();if (activity ! null) {switch (item.getItemId()) {case R.id.menu settings:startActivity(new Intent(activity, SettingsActivity.class));return true;case R.id.menu help:startActivity(new Intent(activity, HelpActivity.class));return true;case R.id.menu exit:showQuitAppDialog();return true;case R.id.menu contacts:startActivity(new Intent(activity, ContactsActivity.class));return true;}}return false;24}

Menu Handlers: Kotlinoverride fun onOptionsItemSelected(item: MenuItem?): Boolean {when (item!!.itemId) {R.id.menu settings - ,SettingsActivity::class.java))return true }R.id.menu help - ,HelpActivity::class.java))return true }R.id.menu exit - {showQuitAppDialog()return true }R.id.menu contacts - ,ContactsActivity::class.java))return true }}return false}Kotlin’s !! operator asserts that25calling object is not null

UI for Larger Screens - Fragments In Android 3.0 and up with compatibility library(ACL) for earlier versions Further decouples UI interactions from activitylifecycle– Standard concept in frameworks Allows reuse of UI components Specialized activity class – FragmentActivity We will cover it in a later class26

Special Types of Activities: Preferences: Javapublic class SettingsActivity extends AppCompatActivity { /* . */protected Fragment createFragment() { return new SettingsFragment(); }. . .@Overrideprotected void onCreate(Bundle savedInstanceState) {FragmentManager fm getSupportFragmentManager();Fragment fragment fm.findFragmentById(R.id.fragment container);Fragment preferenceFragment d.fragment container, DefaultValues(this, R.xml.settings, false); }}. . .public class SettingsFragment extends PreferenceFragmentCompat {@Overridepublic void onCreatePreferences(Bundle savedInstanceState, String rootKey) {// Load preferences from XML );}}27

Special Types of Activities: Preferences: Kotlinclass SettingsActivity : AppCompatActivity() { /* . */protected fun createFragment(): Fragment { return SettingsFragment() }. . .override fun onCreate(savedInstanceState: Bundle?) { /* . */val fm supportFragmentManagerval fragment fm.findFragmentById(R.id.fragment container)val preferenceFragment .fragment container, efaultValues(this, R.xml.settings, false)}}. . .class SettingsFragment : PreferenceFragmentCompat() {override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {// Load preferences from XML )}}28

Layout File for a Preferences Activity ?xml version "1.0" encoding "utf-8"? PreferenceScreenxmlns:android title "Settings"android:background "@color/background" EditTextPreference android:key "name"android:title "Player Info"android:summary "Select your name"android:defaultValue "Player 1"/ CheckBoxPreference android:key "human starts"android:title "Human Plays First"android:summary "Check box to play first"android:defaultValue "true" / /PreferenceScreen 29

SettingsJavaKotlin// Settings.java// Settings.ktpublic class Settings {. . .public static String getName(Context context) {return PreferenceManagerobject Settings {. . .fun getName(context: Context): String {return ext).getString(OPT NAME, OPT NAME g(OPT NAME, OPT NAME DEF);}}fun doesHumanPlayFirst(context: Context):Boolean {return PreferenceManagerpublic static boolean doesHumanPlayFirst(Context context) {return ext).getBoolean(OPT PLAY lean(OPT PLAY FIRST,OPT PLAY FIRST DEF)OPT PLAY FIRST DEF);}}}}30

Thank YouQuestions and comments?31

CSE 5236: Mobile Application Development Instructor: Adam C. Champion, Ph.D. Course Coordinator: Dr. Rajiv Ramnath Reading: Big Nerd Ranch Guide, Chapters 3, 5(Activities); Chapter 13 (menus) 1. Android Framework Support 2. Framework Capabilities and Add-Ons Built-In Services: –GUI –OS services (file I/O, threads, device management) –Graphics –Device access (GPS, camera,