MobAppDev (Fall 2013): UI Development; Loopers & Handlers
-
Upload
vladimir-kulyukin -
Category
Technology
-
view
555 -
download
0
description
Transcript of MobAppDev (Fall 2013): UI Development; Loopers & Handlers
Android MobAppDev
UI Development, Loopers & Handlers
Vladimir Kulyukin
Outline
● UI Development– Views & Containers– Common View Properties– Android UI Measurement Units– XML UI Design– International Date Display Application
● Loopers & Handlers: Updating GUIs on the Main Thread
International Date Display Application
Android 2.3.3 (Ginger Bread) source
Android 4.2 (Jelly Bean) source
XML-Based UI Design● The most important step to mastering XML-Based GUI design is to
relate visual GUIs with XML code that defines them
● XML specs are used to construct GUI objects they specify via XML inflation
● Why care about XML-Based GUI Design?
● It is not just for Android:
– Microsoft's Extensible Application Markup Language (XAML)
– Adobe's Flex
– Mozilla's XML User Interface Language (XUL)
XML Inflation
<Buttonandroid:id=”@+id/button_one”
style=”@style/my_button_style”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”@string/button_one_text”
/>
// XML inflation of the Button View defined above
protected Button mButtonOne = null;
mButtonOne = (Button) findViewById(R.id.button_one);
App Specs● Develop an application that consists of one activity that displays
three buttons: one for US locale, one for Italy locale, and one for France locale
● A click on a button displays in the screen the current date according to the rules of the specific locale
● The app should use a vertical LinearLayout to arrange its components
● Dates should be displayed in an EditText● Buttons should be arranged in a horizontal LinearLayout● EditText and LinearLayout with buttons should have image
backgrounds
Sample Screenshots
Front Screen US Click IT Click FR Click
Development Steps● UI XML Specification
– Vertical LinearLayout
– EditText
– Horizontal LinearLayout
– Buttons● UI Construction & Logic
– Date Formatting
– Button Click Consumption
UI XML Design
Activity UI Structure
UI: Vertical Linear Layout<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent”
android:orientation="vertical" >
<EditText> … </EditText>
<LinearLayout>
<Button> … </Button>
<Button> … </Button>
<Button> … </Button>
</lLinearLayout>
</LinearLayout>
UI: EditText<EditText
android:id="@+id/edTxtDate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/background_002"
android:ems="10"
android:inputType="none"
android:textSize="30sp" >
<requestFocus />
</EditText>
1) Create /res/drawable directory in your project
2) Place background_002.jpg in /res/drawable
3) Press F5 to refresh the project
UI: Horizontal LinearLayout<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:background="@drawable/background_001" >
<Button />
<Button />
<Button />
</LinearLayout>
1) Create /res/drawable directory in your project
2) Place background_001.jpg in /res/drawable
3) Press F5 to refresh the project
UI: Button Style in /res/values/styles.xml<resources
xmlns:android="http://schemas.android.com/apk/res/android">
<style name="AppTheme" parent="android:Theme.Light" />
<!-- This the added button style definition -->
<style name="my_button_style">
<item name="android:textSize">20sp</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
</style>
</resources>
UI: Button Texts in /res/values/strings.xml
<resources>
<string name="app_name">International Date Display</string>
<string name="hello_world">Hello world!</string>
<string name="menu_settings">Settings</string>
<string name="title_activity_inter_date_display">International Date Display Screen</string>
<string name="btnUSTxt">US</string>
<string name="btnITTxt">IT</string>
<string name="btnFRTxt">FR</string>
</resources>
Define string constants for button texts in /res/values/strings.xml
UI: Buttons<Button
android:id="@+id/btnUS"
style="@style/my_button_style"
android:layout_gravity="left|center_vertical"
android:layout_weight="1"
android:text="@string/btnUSTxt" />
<Button <!-- same properties as 1st button -->
android:text="@string/btnITTxt" />
<Button <!-- same properties as 1st button -->
android:text="@string/btnFRTxt" />
UI Construction & Logic
UI Construction// Member Declaration
protected Button mBtnUS = null;
protected Button mBtnIT = null;
protected Button mBtnFR = null;
protected EditText mEdTxtDateDisplay = null;
// Member Construction via XML Inflation
mEdTxtDateDisplay = (EditText) this.findViewById(R.id.edTxtDate);
mBtnUS = (Button) this.findViewById(R.id.btnUS);
mBtnIT = (Button) this.findViewById(R.id.btnIT);
mBtnFR = (Button) this.findViewById(R.id.btnFR);
Date Formatting: Java Imports● java.text.DateFormat
– Abstract class for date/time formatting subclasses● java.text.SimpleDateFormat
– Concrete class for formatting and parsing dates in locale-sensitive ways
● java.util.Date– specific instant in time, with millisecond precision
● java.util.Locale– Locale objects represent specific geographical, political,
or cultural regions
Date Formatting: UI Logic// Member Declaration
protected DateFormat mDateFormatUS = null;
protected DateFormat mDateFormatIT = null;
protected DateFormat mDateFormatFR = null;
// Member Construction
mDateFormatUS = SimpleDateFormat
.getDateInstance(SimpleDateFormat.LONG, Locale.US);
mDateFormatIT = SimpleDateFormat
.getDateInstance(SimpleDateFormat.LONG, Locale.ITALY);
mDateFormatFR = SimpleDateFormat
.getDateInstance(SimpleDateFormat.LONG, Locale.FRANCE);
// Run Time
String us_date = mDateFormatUS.format(new Date())
String it_date = mDateFormatIT.format(new Date())
String fr_date = mDateFormatFR.format(new Date())
Button Click Consumptionimport android.view.View.OnClickListener;
public class InterDateDisplayAct extends Activity implements OnClickListener {
public void onCreate(Bundle savedInstanceState) {
mBtnUS.setOnClickListener(this); // set this object to be OnClickListener
mBtnIT.setOnClickListener(this); // set this object to be OnClickListener
mBtnFR.setOnClickListener(this); // set this object to be OnClickListener
}
public void onClick(View v) { // implementing onClick() of OnClickListener interface
int ID = v.getId();
switch ( ID ) {
case R.id.btnUS:
mEdTxtDateDisplay.setText(this.mDateFormatUS.format(new Date())); break;
case R.id.btnIT:
mEdTxtDateDisplay.setText(this.mDateFormatIT.format(new Date())); break;
case R.id.btnFR:
mEdTxtDateDisplay.setText(this.mDateFormatFR.format(new Date()));; break;
}}}
Loopers & Handlers
Shared Agenda
● Sequential processing of messages and tasks is accomplished on Android via the Shared Agenda Thread pattern
● Agenda is an AI term frequently used in AI robotics
● Pipeline is an OS term commonly used in the concurrency literature
Shared Agenda
● Shared Agenda Thread pattern is used on many robotic platforms (ActivMedia robots is one example)
● Shared Agenda pattern or something very similar to it are used in many UI frameworks such as Swing or Adobe Flex
● The general idea is to use the Shared Agenda thread to push sequential tasks off the main UI thread
Shared Agenda
● Shared Agenda is a thread that holds a queue of messages and tasks
● A message (android.os.Message) is a data structure for someone else to process
● A task (java.lang.Runnable) is a unit of CPU work that can be executed
Shared Agenda
● When there are no tasks on the Shared Agenda, it blocks
● Other threads can push new messages onto the queue at any time
● When there are messages on the queue, the Shared Agenda processes them one after another
android.os.Looper and android.os.Handler
● Looper is a class that turns a thread into a shared agenda thread with a message queue
● Handler is a class that other threads can use to push messages to the shared agenda
● The term Looper emphasizes the fact that a Looper object loops over the message queue executing messages one after another
Threads and android.os.Handler
● Thread in Android has a MessageQueue● MessageQueue is a queue of Message objects● Handler is associated with a specific Thread and
its MessageQueue● Handler, once associated with a Thread, can
send Messages and Runnables to the Thread's MessageQueue and for the Looper to execute them as they come off the MessageQueue
android.os.Handler● Handlers are used to schedule Messages and Runnables● You can enqueue Runnables with
– post(Runnable)
– postAtTime(Runnable, long)
– postDelayed(Runnable, long)
● The enqueued Runnables are called as they are received● You can send messages with
– sendEmptyMessage(int)
– sendMessage(Message)
– sendMessageAtTime(Messasge, int)
– sendDelayedMessage(Message, long)
android.os.Looper
● Looper runs a message loop for a Thread● Handler is typically used in conjunction with
a Looper● Looper.prepare() creates a message queue● Looper.loop() processes messages as long
as the Thread runs
App Specs
● Develop an application that consists of one activity that displays one button
● A click on a button displays in a progress bar that works on the scale from 0 to 100
● The progress bar simulates a file download and posts update messages to the main thread via a Handler from a separate thread
UI Components
public class ProgressBarDemoActivity extends Activity implements OnClickListener {
Button mBtnStartProgress;
ProgressDialog mProgressBar;
private int mProgressBarStatus=0;
// Handler to post messages on the main thread from a non-main threads.
private Handler mProgressBarHandler=new Handler();
private long mFileSize=0;
static final String PROGRESS_MESSAGE="File Downloading . . .";
static final String COMPLETION_MESSAGE="Download complete.";
…
}
www.vkedco.blogspot.com
UI XML Inflation
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.progressbar_demo_layout);
mBtnStartProgress =(Button) findViewById(R.id.btnStartProgress);
mBtnStartProgress.setOnClickListener(this);
}
www.vkedco.blogspot.com
UI Logic mProgressBar=new ProgressDialog(v.getContext());
mProgressBar.setCancelable(true);
// Set the message of the Progress Dialog object to File Downloading...
mProgressBar.setMessage(PROGRESS_MESSAGE);
// This is a horizontal ProgressDialog
mProgressBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
// Set the progress to 0, because we have not downloaded anything.
mProgressBar.setProgress(0);
// The progress indicator will go from 0 and upto 99.
mProgressBar.setMax(100);
mProgressBar.show();
mProgressBarStatus=0;
mFileSize=0;
// Create a thread
Thread thread = new Thread(){ public void run(){ updateProgressBar(); }};
// Start the thread
thread.start();
www.vkedco.blogspot.com