57
Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Embed Size (px)

Citation preview

Page 1: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Understanding Android UI and Intents by Implementing Sudoku

Uichin LeeKAIST KSE

March 14, 2013

Hello, Android Chapter 3

Page 2: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Objective:

• Review Android Sudoku Example to understand Android User Interfaces and Intents

Filling a 9×9 grid with digits so that each column, each row, and each of the nine 3×3 sub-grids that compose the grid contains all of the digits from 1 to 9

Page 3: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Getting Started

• UI Design methods:– Procedural design: written in Java code (like Swing, e.g.,

JButton, JFrame)– Declarative design: XML description of UI objects

• Preferred method

• Creating the Opening ScreenProject name: SudokuBuild target: Android 2.2Application name: SudokuPackage name: org.example.sudokuCreate Activity: SudokuMin SDK Version: 8

Page 4: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Android – User InterfacesUsing XML Layouts

Victor MatosCleveland State University

Notes are based on: The Busy Coder's Guide to Android Developmentby Mark L. MurphyCopyright © 2008-2009 CommonsWare, LLC.ISBN: 978-0-9816780-0-9&Android Developers http://developer.android.com/index.html

Part 4

Page 5: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

5

4. Android – UI - User Interfaces

The View Class

5

• The View class represents the basic building block for user interface components.

• A View occupies a rectangular area on the screen and is responsible for drawing and event-handling.

• View is the base class for widgets that are used to create interactive UI components (buttons, text fields, etc.).

• The ViewGroup subclass (of View) is the base class for layouts, which are invisible containers that can hold other Views (or other ViewGroups) and define their layout properties.

Page 6: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

6

4. Android – UI - User Interfaces

Using Views

6

All of the views in a window are arranged in a single tree. You can add views either from code or by specifying a tree of views in one or more XML layout files.

Once you have created a tree of views, there are typically a few types of common operations you may wish to perform:

1. Set properties: for example setting the text of a TextView. Properties that are known at build time can be set in the XML layout files.

2. Set focus: The framework will handled moving focus in response to user input. To force focus to a specific view, call requestFocus().

3. Set up listeners: Views allow clients to set listeners that will be notified when something interesting happens to the view. For example, a Button exposes a listener to notify clients when the button is clicked.

4. Set visibility: You can hide or show views using setVisibility(int).

Page 7: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

7

4. Android – UI - User Interfaces

A brief sample of UI components

7

Linear LayoutA LinearLayout is a GroupView that will lay child View elements vertically or horizontally.

Relative LayoutA RelativeLayout is a ViewGroup that allows you to layout child elements in positions relative to the parent or siblings elements.

Table Layout A TableLayout is a ViewGroup that will lay child View elements into rows and columns.

Layouts

Page 8: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

8

4. Android – UI - User Interfaces

A brief sample of UI components

8

DatePickerA DatePicker is a widget that allows the user to select a month, day and year.

Form ControlsIncludes a variety of typical form widgets, like: image buttons, text fields, checkboxes and radio buttons.

GalleryView

TabWidget

Spinner

Widgets

Page 9: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

9

4. Android – UI - User Interfaces

A brief sample of UI components

9

AutoCompleteTextViewIt is a version of the EditText widget that will provide auto-complete suggestions as the user types. The suggestions are extracted from a collection of strings.

ListViewA ListView is a View that shows items in a vertically scrolling list. The items are acquired from a ListAdapter.

WebView

MapView

Page 10: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

10

4. Android – UI - User Interfaces

What is an XML Layout?

An XML-based layout is a specification of the various UI components and the relationships to each other – and to their containers – all written in XML format.

10

Android considers XML-based layouts to be resources, and as such layout files are stored in the res/layout directory inside your Android project.

Page 11: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

11

4. Android – UI - User Interfaces

What is an XML Layout?

Each XML file contains a tree of elements specifying a layout of widgets and containers that make up one View (shown later).

The attributes of the XML elements are properties, describing how a widget should look or how a container should behave.

Example: If a Button element has an attribute value of

android:textStyle = "bold" that means that the text appearing on the face of the button should be rendered in a boldface font style.

11

Page 12: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

12

4. Android – UI - User Interfaces

An example

12

The application places a button to occupy the screen. When clicked the button’s text shows current time.import java.util.Date;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;

public class AndDemo extends Activity {Button btn;

@Overridepublic void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.main); btn = (Button) findViewById(R.id.myButton); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { updateTime(); } }); }// onCreate//private void updateTime() { btn.setText(new Date().toString());}

}

Page 13: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

13

4. Android – UI - User Interfaces

An example

13

This is the XML-Layout definition

<?xml version="1.0" encoding="utf-8"?><Button xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/myButton" android:text="" android:layout_width="fill_parent" android:layout_height="fill_parent"/>

The root element needs to declare the Android XML namespace:xmlns:android="http://schemas.android.com/apk/res/android"

All other elements will be children of the root and will inherit that namespace declaration.

Because we want to reference this button from our Java code, we need to giveit an identifier via the android:id attribute.

Page 14: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

14

4. Android – UI - User Interfaces

An example cont.

14

<?xml version="1.0" encoding="utf-8"?><Button xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/myButton" android:text="" android:layout_width="fill_parent" android:layout_height="fill_parent"/>

The remaining attributes are properties of this Button instance:

• android:text indicates the initial text to be displayed on the button face (in this case, an empty string)

• android:layout_width and android:layout_height tell Android to have the button's width and height fill the "parent“ container, in this case the entire screen.

Page 15: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

15

4. Android – UI - User Interfaces

UI Hierarchy

15

The utility HierarchyViewer displays the UI structure of the current screen shown on the emulator or device (eclipse: Windows > Open Perspectives)

(Execute app on emulator, execute HierarchyViewer, click on Emulator > Refresh Screenshot )

UI Tree

Page 16: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

4. Android – UI - User Interfaces

UI HierarchyExample: Display UI Hierarchy

UI Tree

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" ><TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /></LinearLayout>

Page 17: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

17

4. Android – UI - User Interfaces

Attaching Layouts to Java Code

17

PLUMBING. You must ‘connect’ the XML elements with equivalent objects in your Java activity. This allows you to manipulate the UI with code.

XLM Layout<xml….. . . . . .</xml>

JAVA codepublic class ….{. . . . . .}

Page 18: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

18

4. Android – UI - User Interfaces

Attaching Layouts to Java Code

18

Assume the UI in res/layout/main.xml has been created. This layout could be called by an application using the statement

setContentView(R.layout.main);

Individual widgets, such as myButton could be accessed by the application using the statement findViewByID(...) as in

Button btn = (Button) findViewById(R.id.myButton);

Where R is a class automatically generated to keep track of resources available to the application. In particular R.id... is the collection of widgets defined in the XML layout.

Page 19: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

19

4. Android – UI - User Interfaces

Attaching Layouts to Java Code

19

Where R is a class automatically generated to keep track of resources available to the application. In particular R.id... is the collection of widgets defined in the XML layout.

/* AUTO-GENERATED FILE. DO NOT MODIFY. * * This class was automatically generated by the * aapt tool from the resource data it found. It * should not be modified by hand. */

package uichin.kaist;

public final class R { public static final class attr { } public static final class drawable { public static final int icon=0x7f020000; } public static final class layout { public static final int main=0x7f030000; } public static final class string { public static final int app_name=0x7f040001; public static final int hello=0x7f040000; }}

Page 20: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

20

4. Android – UI - User Interfaces

Attaching Layouts to Java Code

20

Attaching Listeners to the Widgets

The button of our example could now be used, for instance a listener for the click event could be written as:

btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { updateTime(); }});

private void updateTime() { btn.setText(new Date().toString());}

Page 21: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Sudoku Overview

(1) Main Layout XML

Sudoku.java(2) About

About.java(5) Draw Game

Game.javaPuzzleView.java

(3) Menu KeySudoku.java

(6) Key Pad

Keypad.java

Touch

Preference: Menu

Pref.java

(4) New Game

Page 22: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Step 1: Main Layout<?xml version="1.0" encoding="utf-8"?><LinearLayout

xmlns:android="http://schemas.../android"android:background="@color/background"android:layout_height="fill_parent"android:layout_width="fill_parent"android:padding="30dip"android:orientation="horizontal" ><LinearLayoutandroid:orientation="vertical"android:layout_height="wrap_content"android:layout_width="fill_parent"android:layout_gravity="center" ><TextView

android:text="@string/main_title"android:layout_height="wrap_content"android:layout_width="wrap_content"android:layout_gravity="center"android:layout_marginBottom="25dip"android:textSize="24.5sp" />

<Buttonandroid:id="@+id/continue_button"android:layout_width="fill_parent"android:layout_height="wrap_content"android:text="@string/continue_label" />

<Buttonandroid:id="@+id/exit_button"android:layout_width="fill_parent"android:layout_height="wrap_content"android:text="@string/exit_label" />

...more buttons..’</LinearLayout>

</LinearLayout>

<resources> <string name="app_name">Sudoku</string> <string name="main_title">Android Sudoku</string> <string name="continue_label">Continue</string> <string name="new_game_label">New Game</string> <string name="about_label">About</string> <string name="exit_label">Exit</string>

Page 23: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Step 1: Main Layout

Use “GraphicalLayout”

Page 24: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Step 1: Main Layout

• Emulator: Ctrl + F11 (rotate screen)• Add a new layout for the landscape mode (use “-land” suffix)

– Select res, Ctrl+N, select Android/Android XML Layout File/

Page 25: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Step 1: Main Layout• Set up click listeners for all the buttons

import android.app.Activity;import android.os.Bundle;import android.content.Intent;import android.view.View;import android.view.View.OnClickListener;

public class Soduku extends Activity implements OnClickListener {@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);setContentView(R.layout.about);

// Set up click listeners for all the buttonsView continueButton = findViewById(R.id.continue_button);continueButton.setOnClickListener(this);View newButton = findViewById(R.id.new_button);newButton.setOnClickListener(this);View aboutButton = findViewById(R.id.about_button);aboutButton.setOnClickListener(this);View exitButton = findViewById(R.id.exit_button);exitButton.setOnClickListener(this);

}}

Page 26: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Step 1: Main Layout• onClick handler

public void onClick(View v) { switch (v.getId()) { case R.id.continue_button:

Intent intent = new Intent(Sudoku.this, Game.class); intent.putExtra(Game.KEY_DIFFICULTY, Game.DIFFICULTY_CONTINUE); startActivity(intent);

break;

case R.id.about_button: Intent i = new Intent(this, About.class); startActivity(i); break;

// More buttons go here (if any) ... case R.id.new_button: openNewGameDialog(); break;

case R.id.exit_button: finish(); break; } }

(4) New Game(2) About

Continue

Shut down activity and return control

Page 27: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Android Intents

Part 2Inter-Process Communication Using Bundles

Victor MatosCleveland State University

Notes are based on: Android Developers http://developer.android.com/index.html

12-2

Page 28: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

28

12. Android – Intents – Part 2

Intents

28

Android IntentsAn activity usually presents a single visual user interface from which a number of actions could be performed.

Moving from one activity to another is accomplished by having the current activity start the next one through so called intents.

Intent {action + data}

requestCoderequestResult[ optional data ]

Activity-1

startActivityForResult…

onActivityResult()…

Activity-2

onResult()……

Page 29: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

29

12. Android – Intents – Part 2

Intents

29

Android Bundles

Most programming languages support the notion of IPC (Inter-Process Communication) method-calling with arguments flowing birectionally from the caller to the invoked method.

In android the calling activity issues an invocation to another activity using an Intent object.

Notably in Android, the caller does not wait for the called activity to return results. Instead a listening-method [onActivityResult(...) ] should be used.

IPC Inter-Process Communication

Page 30: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

30

12. Android – Intents – Part 2

Intents

30

Android Bundles

Normally the IPC expressions actual parameter list, and formal parameter list are used to designate the signature of particpating arguments, and the currently supplied data.

Instead of using the traditional formal/actual parameter lists, Android relies on the concept of Intents to establish Inter-process-communication.

Intents optionally carry a named actual list or bundle for data exchange.

Page 31: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

31

12. Android – Intents – Part 2

Intents

31

Android Bundles

The Android Bundle container is a simple mechanism used to pass data between activities.

A Bundle is a type-safe collection of <name, value> pairs.

There is a set of putXXX and getXXX methods to store and retrieve (single and array) values of primitive data types from/to the bundles. For example

Bundle myBundle = new Bundle();myBundle.putDouble (“var1”, 3.1415);

...Double v1 = myBundle.getDouble(“var1”);

Page 32: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

32

Intent myIntentA1A2 = new Intent (Activity1.this, Activity2.class);

Bundle myBundle1 = new Bundle();myBundle1.putInt (“val1”, 123);

myIntentA1A2.putExtras(myBundle1);

startActivityForResult(myIntentA1A2, 1122);

12. Android – Intents – Part 2

Intents

32

Android Intents & Bundles

Activity1: Sender Activity2: Receiver

INTENT

requestCode (1122)

resultCode

Extras: { val1 = 123 }

Sender class / Receiver class

Bundles

Page 33: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

33

12. Android – Intents – Part 2

Intents

33

Android Intents & Bundles

Activity1: Sender Activity2: Receiver

INTENT

requestCode (1122)

resultCode

Extras: { val1 = 123 }

Sender class / Receiver class

Intent myLocalIntent2 = getIntent();

Bundle myBundle = myLocalIntent.getExtras();

int val1 = myBundle.getInt(“val1");

Page 34: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

34

12. Android – Intents – Part 2

Intents

34

Android Intents & Bundles

Activity1: Sender Activity2: Receiver

INTENT

requestCode (1122)

resultCode (OK)

Extras: { val1 = 456 }

Sender class / Receiver class

myBundle.putString("val1", 456 );

myLocalIntent.putExtras(myBundle);

setResult(Activity.RESULT_OK, myLocalIntent);

Page 35: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Sudoku

Touch(1) Main Layout XML

(2) About

Preference: Menu

(3) Menu Key

(4) New Game

(5) Draw Game

(6) Key Pad

Sudoku.java

About.javaGame.java

PuzzleView.java

Keypad.java

Sudoku.java

Pref.java

Page 36: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Step 2: About Window• Draw a window with some info about Sudoku

– Define a new Activity, and start it– Use the AlertDialog class, and show it– Subclass Android’s Dialog class, and show that

• How to add a new Activity class in Eclipse?1. (create a new class) File > New > Class:

• Superclass: android.app.Activity

2. (activity registration) AndroidManitest.xml > Application > Application Nodes• Or manually type in <activity…> </activity> in the XML file

3. Auto-filling Override functions: Right click “About.java” > Source > Override/Implement methods > Select “onCreate”

Register a new activity here

<activity android:name=".About“></activity>

Page 37: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Step 2: About Window

• Adding a new layout? (about.xml)– New > Other > Android > Android XML Layout File

• This will automatically add R.layout.about (in R.java)

ScrollView

about.xml

“Layout”

<?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="10dip"> <TextView android:id="@+id/about_content" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/about_text" /></ScrollView>

Page 38: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Step 2: About Window

package org.example.sudoku;

import android.app.Activity;import android.os.Bundle;

public class About extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Set “about.xml” layout as a default view setContentView(R.layout.about); }}

Page 39: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Step 2: About Window

• Applying a theme– Very similar to Cascading Style Sheets (CSS) used for

web pages– Default styles, and user-defined styles

• Using a default theme: AndroidMenifest.xml

– “@android:” prefix means that it’s a reference to a resource defined by Android

<activity android:name=".About“android:label="@string/about_title“android:theme="@android:style/Theme.Dialog">

</activity>

Page 40: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Sudoku

Touch(1) Main Layout XML

(2) About

Preference: Menu

(3) Menu Key

(4) New Game

(5) Draw Game

(6) Key Pad

Sudoku.java

About.javaGame.java

PuzzleView.java

Keypad.java

Sudoku.java

Pref.java

Page 41: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Step 3: Adding a Menu/Setting

• Menus in Android:– When you press the physical Menu button

• Recent Androids (API 11 and higher) has a soft menu button instead (called an overflow menu button)

– Context menu popping up when you press and hold your finger on the screen

• Implementing “physical (or soft) menu”1. Define string labels that will be used in menu

(res/values/strings.xml)2. Define a menu using XML (res/menu/menu.xml) • New > Other > Android > Android XML File (select “menu”)

Page 42: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Step 3: Adding a Menu/Setting

• Bring up a menu: Sudoku.javaimport android.view.Menu;import android.view.MenuInflater;import android.view.MenuItem;

@Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu, menu); return true; }

@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.settings: startActivity(new Intent(this, Prefs.class)); return true; // More items go here (if any) ... } return false; }

Read menu definition from

xml file

Called when a user selects any

menu item

Page 43: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Step 3: Adding a Menu/Setting

• Bring up a setting: Pref.java1. Create a new layout (choose “Preference”): stored in

“res/xml” by default2. Create a class “Pref.java” (extends “PreferenceActivity”)• Register Activity in the AndroidMenifest.xml

<PreferenceScreenxmlns:android="http://schemas.android.com/apk/res/android"> <CheckBoxPreference android:key="music" android:title="@string/music_title" android:summary="@string/music_summary" android:defaultValue="true" /> <CheckBoxPreference android:key="hints" android:title="@string/hints_title" android:summary="@string/hints_summary" android:defaultValue="true" /></PreferenceScreen>

import android.content.Context;import android.os.Bundle;import android.preference.PreferenceActivity;import android.preference.PreferenceManager;

public class Prefs extends PreferenceActivity {@Overrideprotected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.settings);}}

setting.xml (layout)Pref.java

Page 44: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Sudoku

Touch(1) Main Layout XML

(2) About

Preference: Menu

(3) Menu Key

(4) New Game

(5) Draw Game

(6) Key Pad

Sudoku.java

About.javaGame.java

PuzzleView.java

Keypad.java

Sudoku.java

Pref.java

Page 45: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Step 4: New Game Menu• Pop up a dialog box, asking users to select among three difficulty

levels (AlertDialog)import android.app.AlertDialog;import android.content.DialogInterface;import android.util.Log;

public class Sudoku extends Activity implements OnClickListener { private void openNewGameDialog() { new AlertDialog.Builder(this) .setTitle(R.string.new_game_title) .setItems(R.array.difficulty, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialoginterface, int i) { startGame(i); } }) .show(); }private void startGame(int i) { Log.d(TAG, "clicked on " + i); Intent intent = new Intent(Sudoku.this, Game.class); intent.putExtra(Game.KEY_DIFFICULTY, i); startActivity(intent); }}

<resources> <array name="difficulty"> <item>@string/easy_label</item> <item>@string/medium_label</item> <item>@string/hard_label</item> </array></resources>

Sudoku.java

Page 46: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Debugging• Debugging with Log Messages

– Log class provides several static methods to print messages of various levels• Log.e(): errors• Log.w(): warnings• Log.i(): information• Log.d(): debugging• Log.v(): verbose• Log.wtf(): what a terrible failure

– Eclipse: Window > Show View > Other > Android > LogCat • Debugging with Eclipse debugger

– Must enable debugging: AndroidManifest.xml<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.example.sudoku" android:versionCode="1" android:versionName="1.0">

<application android:icon="@drawable/icon" android:label="@string/app_name“

android:debuggable=“true”>

Page 47: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Sudoku

Touch(1) Main Layout XML

(2) About

Preference: Menu

(3) Menu Key

(4) New Game

(5) Draw Game

(6) Key Pad

Sudoku.java

About.javaGame.java

PuzzleView.java

Keypad.java

Sudoku.java

Pref.java

Page 48: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Activity-2 (Game)

Step 5: Starting a Game

• Procedure:1. Start a new activity (Game)

• Game.java

2. Game initializes its view using PuzzleView• PuzzleView.java

Intent {action + data}

Activity-1(Sudoku)

startActivity()

Intent intent = new Intent(Sudoku.this, Game.class);intent.putExtra(Game.KEY_DIFFICULTY, i);startActivity(intent);

protected void onCreate(savedInstanceState) {int diff = getIntent().getIntExtra(KEY_DIFFICULTY, DIFFICULTY_EASY);puzzleView = new PuzzleView(this);setContentView(puzzleView);

PuzzleView

Page 49: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Step 5: Starting a Game – PuzzleView

• Android 2D graphic package:– Color

• E.g., color = Color.argb(127, 255, 0, 255) or color = getResources().getColor(R.color.mycolor)

– Paint• Style, color, and other info needed to draw any graphics such as

bitmaps, text, and geometric shapes

– Canvas: a surface on which you draw! • Display is taken up by an Activity, which hosts a View, which in turn

hosts Canvas• Drawing on the canvas by overriding the View.onDraw() method

– Path– Drawable: bitmap, Shape, etc.

Page 50: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Step 5: Starting a Game – PuzzleViewimport android.content.Context;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Rect;import android.graphics.Paint.FontMetrics;import android.graphics.Paint.Style;

import android.os.Bundle;import android.os.Parcelable;

import android.util.Log;import android.view.KeyEvent;import android.view.MotionEvent;import android.view.View;import android.view.animation.AnimationUtils;

public class PuzzleView extends View { private final Game game; public PuzzleView(Context context) {

super(context); this.game = (Game) context;

setFocusable(true); setFocusableInTouchMode(true);

}

private float width; // width of one tileprivate float height; // height of one tileprivate static final String SELX = "selX"; private static final String SELY = "selY";private final Rect selRect = new Rect();

@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) { width = w / 9f; height = h / 9f; getRect(selX, selY, selRect); super.onSizeChanged(w, h, oldw, oldh); }

private void getRect(int x, int y, Rect rect) { rect.set((int) (x * width), (int) (y * height), (int) (x * width + width), (int) (y * height + height));}

onSizeChanged() is called after the view is created

Page 51: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Step 5: Starting a Game - PuzzleView

• Drawing the board– onDraw() method is called anytime the view needs to be

updated

@Override protected void onDraw(Canvas canvas) {

// Draw the background... Paint background = new Paint();

background.setColor(getResources().getColor( R.color.puzzle_background));

canvas.drawRect(0, 0, getWidth(), getHeight(), background);

Page 52: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Step 5: Starting a Game - PuzzleView• Drawing the grid lines for the board // Define colors for the grid lines Paint dark = new Paint(); dark.setColor(getResources().getColor(R.color.puzzle_dark)); Paint hilite = new Paint(); hilite.setColor(getResources().getColor(R.color.puzzle_hilite)); Paint light = new Paint(); light.setColor(getResources().getColor(R.color.puzzle_light));

// Draw the minor grid lines for (int i = 0; i < 9; i++) { canvas.drawLine(0, i * height, getWidth(), i * height, light); canvas.drawLine(0, i * height + 1, getWidth(), i * height + 1, hilite); canvas.drawLine(i * width, 0, i * width, getHeight(), light); canvas.drawLine(i * width + 1, 0, i * width + 1, getHeight(), hilite); }

// Draw the major grid lines for (int i = 0; i < 9; i++) { if (i % 3 != 0) continue; canvas.drawLine(0, i * height, getWidth(), i * height, dark); canvas.drawLine(0, i * height + 1, getWidth(), i * height + 1, hilite); canvas.drawLine(i * width, 0, i * width, getHeight(), dark); canvas.drawLine(i * width + 1, 0, i * width + 1, getHeight(), hilite); }

Page 53: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Step 5: Starting a Game - PuzzleView• Drawing the numbers

// Define color and style for numbers Paint foreground = new Paint(Paint.ANTI_ALIAS_FLAG); foreground.setColor(getResources().getColor(R.color.puzzle_foreground)); foreground.setStyle(Style.FILL); foreground.setTextSize(height * 0.75f); foreground.setTextScaleX(width / height); foreground.setTextAlign(Paint.Align.CENTER);

// Draw the number in the center of the tile FontMetrics fm = foreground.getFontMetrics();

// Centering in X: use alignment (and X at midpoint) float x = width / 2;

// Centering in Y: measure ascent/descent first float y = height / 2 - (fm.ascent + fm.descent) / 2; for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { canvas.drawText(this.game.getTileString(i, j), i * width + x, j * height + y, foreground); } }

Page 54: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Sudoku

Touch(1) Main Layout XML

(2) About

Preference: Menu

(3) Menu Key

(4) New Game

(5) Draw Game

(6) Key Pad

Sudoku.java

About.javaGame.java

PuzzleView.java

Keypad.java

Sudoku.java

Pref.java

Page 55: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Step 6: Handling Input• Procedure

1. Create a new layout for keypad (buttons!)2. Create a new class, Keypad that extends Dialog

public class Keypad extends Dialog {

private final View keys[] = new View[9];private View keypad;

private final int useds[];private final PuzzleView puzzleView;

public Keypad(Context context, int useds[], PuzzleView puzzleView) { super(context); this.useds = useds; this.puzzleView = puzzleView; }

@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setTitle(R.string.keypad_title); setContentView(R.layout.keypad);

findViews(); // keys, keypad Views

for (int element : useds) { if (element != 0) keys[element-1].setVisibility(View.INVISIBLE); }

// for each key, keypad view, // set up OnClickListener() setListeners(); }

Cf. As of J2SE 5.0, Java allows you to iterate through a collection (array): http://www.java-tips.org/java-se-tips/java.lang/the-enhanced-for-loop.html

Page 56: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Step 6: Handling Input• PuzzleView:

– Keyboard: if a key is down, onKeyDown()is invoked– Touch: if a user touches the screen, onTouchEvent()is invoked– Then, display keypad: game.showKeypadOrError(selX, selY)

@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {switch (keyCode) { case KeyEvent.KEYCODE_DPAD_LEFT: select(selX - 1, selY); break; case KeyEvent.KEYCODE_DPAD_RIGHT: select(selX + 1, selY); break; case KeyEvent.KEYCODE_0: case KeyEvent.KEYCODE_SPACE: setSelectedTile(0); break; case KeyEvent.KEYCODE_1: setSelectedTile(1); break; case KeyEvent.KEYCODE_ENTER: case KeyEvent.KEYCODE_DPAD_CENTER: game.showKeypadOrError(selX, selY); break; default: return super.onKeyDown(keyCode, event); } return true;}

@Overridepublic boolean onTouchEvent(MotionEvent event) { if (event.getAction() != MotionEvent.ACTION_DOWN) return super.onTouchEvent(event);

select((int) (event.getX() / width), (int) (event.getY() / height));

game.showKeypadOrError(selX, selY); return true; }

Page 57: Understanding Android UI and Intents by Implementing Sudoku Uichin Lee KAIST KSE March 14, 2013 Hello, Android Chapter 3

Step 6: Handling Input• Showing keypad and returning the result

/** Open the keypad if there are any valid moves */ protected void showKeypadOrError(int x, int y) { int tiles[] = getUsedTiles(x, y); if (tiles.length == 9) { Toast toast = Toast.makeText(this, R.string.no_moves_label, Toast.LENGTH_SHORT); toast.setGravity(Gravity.CENTER, 0, 0); toast.show(); } else { Log.d(TAG, "showKeypad: used=" + toPuzzleString(tiles)); Dialog v = new Keypad(this, tiles, puzzleView); v.show(); } }

Game.java

private void returnResult(int tile) { puzzleView.setSelectedTile(tile); dismiss(); // dismissing a dialog from screen } Keypad.java

<string name="no_moves_label">

No moves</string>

strings.xml