Lecture Presentation

Lecture Presentation

Goals

  • Understand how events can be handled in your application
  • Respond to View and Activity events
  • Create and respond to Menu options
  • Start your own Activity and get a response back

Examples of some object types and the events they may fire

  • Activity
    • Created, paused, resumed, stopped, destroyed
    • Back button pressed
    • Menu item chosen by user
    • Started sub-activity has returned with a result
  • View and derived views
    • Content/selection of view has changed
    • User has touched somewhere in the view
  • System
    • Incoming call
    • Received sms message
    • Battery level low

Ways to handle an event in Java

  • By extending a base class (deriving)
    • Extend your own class from a base class with overridable methods
    • Override the base class method with your own
    • One class can only be derived from one single base class
  • By implementing interface
    • Declare that your class implements the interface
    • Define the implementation of all methods in the interface
    • Specify your object to a method on the firing object
    • One class can implement any number of interfaces, but only have one implementation for a particular interface

Example of event handler as overridden method

  • onBackPressed is fired when back button is pressed on device
    public class MyActivity extends Activity {
      @Override
      public void onBackPressed() {
      }
    }
    
  • Method name, return type and argument types must be exactly right
  • Attribute @Override is optional
    • Recommended to use since it will tell you if the method does not exist in the base class (if you've spelled it wrong)

Example of event handler by implementing interface

  • No @Override attribute - not applicable
  • Declare that Activity implements interface
    public class MyActivity extends Activity implements OnClickListener {
    
  • Define the method
    public void onClick(View view) {
    }
    
  • Method name, return type and argument types must be exactly right
  • Bind the event handler (our object that implements the interface) to an event
    Button btn = (Button)findViewById(R.id.save);
    btn.setOnClickListener(this);
    

Example of event handler in anonymous class

  • When implementing an interface, you can also create a new anonymous class which primary/only purpose is to respond to events. Only one statement necessary.
  • Create an anonymous object and bind it to the event source
    btn.setOnClickListener(new OnClickListener() {
      public void onClick(View view) {
      }
    });
    
  • Inside onClick, "this" is the anonymous object
    • If you need the outer this (usually the Activity) reference it with class.this, like "Activity.this".

Single event handler for multiple source views

  • Sometimes desirable to have a single event handler in your code for more than one view that fires the same type of event
  • Source view is almost always specified as an argument to the event handler
  • Identify a particular source view
    • Use the id of the view
    • Use the fact that all views can have extra data associated with it
  • Associate extra data with a view in xml
    <TextView android:id="@+id/thousand" android:tag="1000"
    
  • Check the extra data in Java
    public void onTouch(View src, MotionEvent event) {
      int value = Integer.parseInt((String)src.getTag());
      if (src.getId()==R.id.thousand) {
      }
    }
    

Activity lifetime events

  • Events fired by the Activity and handled by overriding methods in your own Activity class
  • onCreate
    • Already used. Fired once when the Activity is first created.
  • onStart
    • Fired when the user navigates back to the Activity after running some other Activity
  • onResume
    • Fired when the Activity receives focus again after losing it to something like a Dialog and also as a follow up to onStart
  • onPause
    • Fired when the Activity loses focus, either because of something like a Dialog or because of the user navigating to another Activity
  • onStop
    • Fired when the user navigates to another Activity
  • onDestroy
    • Fired when the Activity is about to be destroyed (exiting/haven't been used in a while)

Other Activity events

  • onBackPressed
    • Fired when the physical back button of the device is pressed. (No event exists for the physical home button.)

General View event interfaces

  • OnClickListener
    • This event is fired when the user has touched and released a finger on the view
    • void onClick(View src)
  • OnTouchListener
    • This event is fired when the user touches, moves and releases any amount of fingers on the view
    • boolean onTouch(View src, MotionEvent event)
  • OnLongClickListener
    • This event is fired when the user touches and holds an amount of time on the view
    • boolean onLongClick(View src)

Spinner event

  • OnItemSelectedListener
    • This event is fired when the user has chosen an option from the drop down list
  • Two methods in interface
    • void onItemSelected(AdapterView<?> src, View selectedView, int selectedPosition, long selectedId)
      • Depending on how the entries of the Spinner was specified, there might not be any selectedId that is valid. Best to use the selectedPosition if the order of options is well known.
    • void onNothingSelected(AdapterView<?> src)
      • Not applicable to a Spinner. The event interface is shared with other visual elements where such an event is valid.

SeekBar

  • Visual element with a knob that you move between endpoints to set a value
    • Actually extended from the base Progress element that has no interaction and only shows some sort of visual progress bar while waiting for an operation to complete
  • Attributes
    • android:max
      • The maximum value that corresponds to moving the knob to the right-most position
    • android:progress
      • The default value to start at (zero is always the value when the knob is in the left-most position)

SeekBar event interfaces

  • OnSeekBarChangeListener
    • void onStartTrackingTouch(SeekBar source)
      • Called when the user first touches the knob, before moving it
    • void onProgressChanged(SeekBar source, int pos, boolean byUser)
      • Called on every movement of the knob
    • void onStopTrackingTouch(SeekBar source)
      • Called when the user has released the knob and the operation is finished
  • Even if you only need to catch onProgressChanged, all methods must be defined (but can be empty)

Menus on Android

  • Most (all older) Android devices have a physical menu button
    • Requirement was removed when tablets and Android 3.0 appeared, where the menu button can appear as a virtual button on the screen instead.
  • Therefore, two versions depending on Android version
    • Menu pops up from the bottom of screen (older version, before 3.0)
    • Menu pops down from the so called ActionBar at the top of screen (from 3.0)
  • You can write the same code and the platform will display using the version at hand
    • All methods and callbacks (event handlers) are the same for the two versions

Menu handling

  • Event sent to Activity to create options in the menu
    • So can't be set statically at any point. I guess because menu options are more often than not dependent on the current context, selected item etc.
  • Example
    @Override
    boolean onCreateOptionsMenu(Menu menu) {
      menu.add(NONE, 123, 1, "Do something");
      return true;
    }
    
  • Event sent to Activity when user has chosen an option
    @Override
    boolean onOptionsItemSelected(MenuItem item) {
      if (item.getItemId()==123) {
        doSomething();
        return true;
      }
      return false;
    }
    

Add more activities to your app

  • Good for separating different user interfaces, forms, displays etc
  • Built-in back button handling will automatically destroy and switch back to previous activity
  • Choose "File, New, Android, Android Activity" in Eclipse
    • Is probably not a "Launcher Activity", meaning it will not get its own icon in the main launcher app
  • Things added
    • A new Java class to handle the activity (onCreate etc)
    • A new layout xml resource file for defining the user interface
    • A short description/reference of the activity in the AndroidManifest.xml file

Starting another Activity

  • When returning from another Activity, onResume is always fired
    • But this event is also fired in a lot of other situations (when coming back from a call/other app etc)
  • Start another Activity
    Intent other = new Intent(this, OtherActivity.class);
    startActivity(other);
    
  • Start another Activity and prepare to get a result back
    Intent other = new Intent(this, OtherActivity.class);
    startActivityForResult(other, 123);
    

Results from Activity

  • Other activity will
    • Set optional extra values to send back to calling activity
    • Set a resulting identifier usually to identify "Success", "Cancel" or similar
    • End itself by calling finish
  • When other activity wants to go back
    Intent resultData = new Intent();
    resultData.putExtra("name", "Adam");
    setResult(1000, resultData);
    finish();
    
  • Result is sent to event handler onActivityResult in the calling activity
    void onActivityResult(int requestId, int resultId, Intent result) {
      if (requestId==123 && resultId==1000) {
        String name = result.getStringExtra("name");
      }
    }
    

More information

  • Book references
    • Android Programming Unleashed, Chapter 2 Basic Widgets, Event Handling
    • Android Programming Unleashed, Chapter 5 Using Selection Widgets and Debugging, Using the Spinner Control
    • Android Programming Unleashed, Chapter 7 Creating Interactive Menus and ActionBars, Creating Menus Through Coding
    • Android Cookbook, Chapter 4.6 Retrieving Data from a Subactivity Back to Your Main Activity