Download presentation
Presentation is loading. Please wait.
1
Android Application Model I
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)
2
Android Framework Support
Walk through components Explain drivers – these connect the hardware components to the OS Could we have used libc and c interface to drivers to get access to everything in OS using Java? Why write libraries in C? Performance? Have you heard of Java JNI? Build Java layer on top of C.
3
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/Chromium Framework tailored to mobile apps? How? Built in services that could be used by any kind of app. Add ons Maps. DB support, Webkit Why separated?
4
Tooling Support IDE: Android Studio Testing tools: JUnit, Espresso
Performance profiling tools: Android Profiler Source code management: Git, Subversion, CVS, etc. Software emulators: Android emulator, Intel HAXM, Genymotion Sensor injection via emulator
5
Android Studio Project Components
Go over the following directories: Src = source Gen = generated code (R.java) Android SDK version assets = application specific types of resources (i.e. non-standard resources) res = resources go over drawable, layout, menu, raw and values AndroidManifest.xml file Activities, intents project.properties file – project settings
6
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 – a key part of any Android app
7
Activities in Tic-Tac-Toe
Refer to layout files for each one
8
Specifying Activities – AndroidManifest.xml
<activity android:name=".SplashScreen" 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:launchMode="singleInstance" <action android:name="com.wiley.fordummies.androidsdk.Login"/> <category android:name="android.intent.category.DEFAULT"/> App name Orientation Intent filter – invocation messages the activity will respond to. Services Launch mode (talk about tasks) Discussion: Why have concept of activities? Ans: High-grain element of reuse
9
Implementing Activities
Java Kotlin public class LoginActivity extends SingleFragmentActivity { ... } public class GameSessionActivity extends SingleFragmentActivity { class LoginActivity : SingleFragmentActivity() { ... } class GameSessionActivity : SingleFragmentActivity() { Difference between Login and GameSession. Login implements its own UI. GameSession delegates its UI to another class (subclass of View). Only has passive UI elements Walk through these two activities SingleFragmentActivity is an interface with one method, createFragment(), for creating activities with just one fragment Note: SingleFragmentActivity extends FragmentActivity
10
Specified declaratively in layout files Always use Fragments…
Activity UI Widgets View and ViewGroup Package android.view Specified declaratively in layout files Always use Fragments…
11
Sample Layout: Login Activity
<?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android=" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="20dip"> <LinearLayout android:orientation="vertical . . . <TextView /> <TextView /> <EditText /> <Button /> </LinearLayout> </ScrollView> <project>/app/src/main/res/layout/fragment_login.xml
12
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 in res subtree A ViewGroup is a special view that can contain other views (called children.) Superclass of Layout and specific collection views: Datepicker, Calendarview
13
Implement UI Logic: Listener Objects: Java
public 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; . . public View onCreateView(. . .) { // The real code has many null checks and 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; } Ask students to view Login class How layout is inflated How to access a button How to attach listeners
14
Implement UI Logic: Listener Objects: Kotlin
class LoginActivity : SingleFragmentActivity() { // Create LoginFragment in onCreate() method. (See SingleFragmentActivity) } class LoginFragment : Fragment(), View.OnClickListener { private lateinit var mUsernameEditText: EditText private lateinit var mPasswordEditText: EditText override fun onCreateView(. . . ): View? { // Similarly, real code has screen rotation check (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_button) newUserButton.setOnClickListener(this) return v } // . . .
15
The OnClick Handler Java Kotlin Kotlin’s ?. operator is short for:
public void onClick(View v) { switch (v.getId()) { case R.id.login_button: checkLogin(); break; case R.id.cancel_button: finish(); case R.id.new_user_button: FragmentManager fm = getFragmentManager(); Fragment fragment = new AccountFragment(); fm.beginTransaction() .replace(/* container */, fragment) .addToBackStack("account_fragment") .commit(); } // Null check code omitted } override 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 = fragmentManager fm?.beginTransaction() ?.replace(/* container */, fragment) ?.addToBackStack(. . .) ?.commit() } } Why one callback for all buttons? Why not separate onclick call backs? Like, say, iOS Ans: Could do that. Convention. Kotlin’s ?. operator is short for: if (object != null) { object.callMethod() }
16
Embedding a View: GameSession Activity, Fragment: Java
public class GameSessionActivity extends SingleFragmentActivity { . . . } public class GameSessionFragment extends Fragment { <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" . . > <LinearLayout ... <com.wiley.fordummies.androidsdk.Board android:layout_width="fill_parent" android:layout_height="fill_parent"/> </LinearLayout> <TextView ... "/> Board is a custom view. Ask students to view in Eclipse
17
Embedding a View: GameSession Activity, Fragment: Kotlin
class GameSessionActivity : SingleFragmentActivity() { } class GameSessionFragment : Fragment() { <!-- Same XML as before -->
18
Embedding a View: Board Class
Java Kotlin // Board.java public class Board extends View { ... public boolean onTouchEvent( MotionEvent event) { switch (action) { case MotionEvent.ACTION_DOWN: break; } return super.onTouchEvent(event); } } // Board.kt class Board : View { override fun onTouchEvent( event: MotionEvent): Boolean { when (action) { MotionEvent.ACTION_DOWN -> { } } return super.onTouchEvent(event) } } Ask students to view Board implements onTouchEvent callback
19
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 the boundaries of any UI components See onTouchEvent method in SplashScreenFragment class.
20
Menus (Option menus) and Action Bars
Declare the menu items Define onCreateOptionsMenu() and/or the onCreateContextMenu() callback methods in Activity. Automatically called to create the menu (what if it doesn’t exist?). Implement onOptionsItemSelected() and/or onContextItemSelected() in activity. Why menus? Talk about action bar. Briefly mention context menus (pop-up menus)
21
Menu Layout File <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android=" <item android:title="Settings" /> <item android:title="Help" <item android:title="Exit" <item android:title="Contacts" </menu> Ask students to view menu.xml Ask students to view menu_ingame.xml It should be obvious that this layout file defines four items, named Settings, Help, Exit, and Contacts, respectively. The identifiers for these items are menu_settings, menu_help, menu_exit, and menu_contacts respectively. Icons for @android:drawable/ic_menu_close_clear_cancel and are standard icons in the Android SDK. This layout file is compiled into resources specified in the R class in the gen subtree of the Android project. Action Bar: Declare menu item with additional attribute android:showAsAction ="ifRoom","never","withText" or "always".
22
Menu Creation: Java public class GameOptionsFragment { ... public View onCreateView(…) { // setHasOptionsMenu(true); } public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu, inflater); inflater.inflate(R.menu.menu, menu); Ask students to view GameOptions onCreateOptionsMenu method where menu is inflated. Ask students to view GameSession onCreateOptionsMenu
23
Menu Creation: Kotlin class GameOptionsFragment { override fun onCreateView(…) { // setHasOptionsMenu(true); } override fun onCreateOptionsMenu( menu: Menu, inflater: MenuInflater) { super.onCreateOptionsMenu(menu, inflater) inflater.inflate(R.menu.menu_ingame, menu) }
24
Menu Handlers: Java public 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; }
25
Menu Handlers: Kotlin Kotlin’s !! operator asserts that
override fun onOptionsItemSelected(item: MenuItem?): Boolean { when (item!!.itemId) { R.id.menu_settings -> { startActivity(Intent(activity?.applicationContext, SettingsActivity::class.java)) return true } R.id.menu_help -> { startActivity(Intent(activity?.applicationContext, HelpActivity::class.java)) return true } R.id.menu_exit -> { showQuitAppDialog() return true } R.id.menu_contacts -> { startActivity(Intent(activity?.applicationContext, ContactsActivity::class.java)) return true } } return false } Kotlin’s !! operator asserts that calling object is not null
26
UI for Larger Screens - Fragments
In Android 3.0 and up with compatibility library (ACL) for earlier versions Further decouples UI interactions from activity lifecycle Standard concept in frameworks Allows reuse of UI components Specialized activity class – FragmentActivity We will cover it in a later class
27
Special Types of Activities: Preferences: Java
public class SettingsActivity extends AppCompatActivity { protected Fragment createFragment() { return new SettingsFragment(); } . . protected void onCreate(Bundle savedInstanceState) { FragmentManager fm = getSupportFragmentManager(); Fragment fragment = fm.findFragmentById(R.id.fragment_container); Fragment preferenceFragment = createFragment(); fm.beginTransaction().replace(R.id.fragment_container, preferenceFragment) .commit(); PreferenceManager.setDefaultValues(this, R.xml.settings, false); } } public class SettingsFragment extends PreferenceFragmentCompat { . . public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { // Load preferences from XML resource. addPreferencesFromResource(R.xml.settings); } } Ask students to view Settings class Ask students to view settings.xml in layouts Ask students to see onCreate method And see: private final static String OPT_NAME = "name"; private final static String OPT_NAME_DEF = "Player"; private final static String OPT_PLAY_FIRST = "human_starts"; private final static boolean OPT_PLAY_FIRST_DEF = true;
28
Special Types of Activities: Preferences: Kotlin
class SettingsActivity : AppCompatActivity() { protected fun createFragment(): Fragment { return SettingsFragment() } override fun onCreate(savedInstanceState: Bundle?) { val fm = supportFragmentManager val fragment = fm.findFragmentById(R.id.fragment_container) val preferenceFragment = createFragment() fm.beginTransaction().replace(R.id.fragment_container, preferenceFragment) .commit() } PreferenceManager.setDefaultValues(this, R.xml.settings, false) } } class SettingsFragment : PreferenceFragmentCompat() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { // Load preferences from XML resource. addPreferencesFromResource(R.xml.settings) } }
29
Layout File for a Preferences Activity
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android= android:title="Settings" <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>
30
Settings Java Kotlin // Settings.java public class Settings { public static String getName( Context context) { return PreferenceManager .getDefaultSharedPreferences(context) .getString(OPT_NAME, OPT_NAME_DEF); } public static boolean doesHumanPlayFirst( Context context) { return PreferenceManager .getDefaultSharedPreferences(context) .getBoolean(OPT_PLAY_FIRST, OPT_PLAY_FIRST_DEF); } } // Settings.kt object Settings { fun getName(context: Context): String { return PreferenceManager .getDefaultSharedPreferences(context) .getString(OPT_NAME, OPT_NAME_DEF) } fun doesHumanPlayFirst(context: Context): Boolean { return PreferenceManager .getDefaultSharedPreferences(context) .getBoolean(OPT_PLAY_FIRST, OPT_PLAY_FIRST_DEF) } }
31
Questions and comments?
Thank You Questions and comments?
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.