Lauren Bricker
CSE 340 Spring 2022
Administrivia
Callbacks handle application response to events
Example: MotionEvent which inherits from InputEvent abstract class.
Android events registered with the system
Application Program:
Application Program:
onCreate
@Overrideprotected void onCreate(Bundle savedInstanceState) { // We want to do any view initialization work here super.onCreate(savedInstanceState); // Load the XML representation of our layout into the view setContentView(R.layout.activity_main); // Any other work we need to do like adding views or // registering click listeners!}
onStart
onCreate
or onRestart
onStart
onCreate
or onRestart
onResume
onStart
Implementation strategy
Basic goal: notify something of a change
At the time Android was created the toolkit developers have no idea how every app may want to respond to events
Listeners are an interface that acts as a callback method
At the time Android was created the toolkit developers have no idea how every app may want to respond to events
Listeners are an interface that acts as a callback method
At the time Android was created the toolkit developers have no idea how every app may want to respond to events
Listeners are an interface that acts as a callback method
View
View
) then delivers events that arrive at that View to those listenersView
is interacted with by the userAt the time Android was created the toolkit developers have no idea how every app may want to respond to events
Listeners are an interface that acts as a callback method
View
View
) then delivers events that arrive at that View to those listenersView
is interacted with by the userView
can have listen for different types of interactionsWhat is an interface?
The toolkit has pre-defined interfaces so apps or components can respond to events such as clicks or touches.
View
as inner classes // User tapped a view public static interface View.OnClickListener { ... } // User long pressed on a View public static interface View.OnLongClickListener { ... } // State of view has changed // (e.g. user clicked outside a EditText input box) public static interface View.OnFocusChangeListener { ... } // user typed something public static interface View.OnKeyListener { ... }
Create your button
Register an event listener with the button
In general to respond to a click/press/touch
Examples here
onClick
eventsCounter
Interactor (we created) that responds to onTouch
eventsThree five ways to register an event listener:
Examples of all of these in the Counter exercise
Code for the Counter exercise uses a helper function
/** Method to increment the count field */private void incrementCount(View v) { TextView counter = findViewById(R.id.count); String textCount = counter.getText().toString(); int count = Integer.parseInt(textCount); counter.setText("" + ++count); ((TextView)findViewById(R.id.whichButton)).setText(((Button)v).getText());}
// Approach 3 implementation: implement the listener in// *this* class @Override public void onClick(View v) { incrementCount(v); }
Registration typically done in onCreate()
// Approach 3 implementation: implement the listener in //*this* class @Override public void onClick(View v) { incrementCount(v); } // in onCreate... // Registering the listener in Approach 3 (using // this class) Button b3 = findViewById(R.id.button_three); if (b3 != null) { // Should always check for null b3.setOnClickListener(this); }
public class EventExampleActivity extends AppCompatActivity { // An anonymous inner class as a member variable in an Activity View.OnClickListener mButtonClickListener = new View.OnClickListener() { @Override public void onClick(View v) { // call the private method in EventExampleActivity incrementCount(v); } }; protected void onCreate(Bundle savedState) { Button b1 = findViewById(R.id.button_one); if (b1 != null) { b1.setOnClickListener(mButtonClickListener); } }}
incrementCount is a private method Mention that mXxxx variables are private fields and this is a quick way to find all private fields when searching variables in code
Let's take some time to parse this...
View.OnClickListener mButtonClickListener = new View.OnClickListener() {
View.OnClickListener
is the variable type (Documentation) - a nested class in View
new View.OnClickListener()
is the the anonymous objectOnClick
which overrides the abstract method public void OnClick(View v) { /* stuff in here does the work when a click is received! */ }
Create the and register the listener all at once with lamba syntax
Button b5 = findViewById(R.id.button_five); if (b5 != null) { // Should always check for null b5.setOnClickListener((View v) -> incrementCount(v)); }
To use Lambdas you have to upgrade to Java 8. See these instructions to do this.
// User tapped a view public static interface View.OnClickListener { ... } // User long pressed on a View public static interface View.OnLongClickListener { ... } // State of view has changed // (e.g. user clicked outside a EditText input box) public static interface View.OnFocusChangeListener { ... } // user typed something public static interface View.OnKeyListener { ... }
Can register more than one listener
For example:
View v = new View(); v.setOnClickListener(...); v.setOnLongClickListener(...);
Event callbacks are passed the View
as a parameter
Event callbacks are passed the View
as a parameter
We can reuse a listener for views that handle the same action (e.g. all 5 buttons could use the same class/method for the action)
And we can handle different actions by checking the View
or its id
:
protected void onCreate(Bundle savedState) { Button b1 = (Button) findViewById(R.id.button_one); if (b1 != null) { b1.setOnClickListener(mButtonClickListener); } Button b2 = (Button) findViewById(R.id.button_two); if (b2 != null) { b2.setOnClickListener(mButtonClickListener); } }
You can use the ID of the view to determine where the event originated from
View.OnClickListener mButtonClickListener = new View.OnClickListener({ public void onClick(View v) { if (v == null) { return; } int viewId = v.getId(); switch (viewId) { case R.id.button_one: // First Button Log.d("Button Press", "First Button"); break; case R.id.button_two: // Second Button Log.d("Button Press", "Second Button"); break; default: // Someone else is using the listener! Log.d("Button Press", "Invalid Button!"); } }});
This ensures only one view gets it (we talk about the algorithm behind this later)
Return boolean
value that indicate the event has been handled (true
)
/** * onLongClick - triggered when a view is long clicked * @param v - the view long pressed * @return - true if the callback consumed the long click, false otherwise. **/ boolean onLongClick (View v) { ... };
What other types of interactors have you used in a Graphical User Interface (GUI)?
What other types of interactors have you used in a Graphical User Interface (GUI)?
Create the menu resource
Example: Counter
Handle the callback (from the system) with an onCreateOptionsMenu(Menu menu)
listener
@Overridepublic boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu_main, menu); return true;}
But we still need to handle the events generated from the user
public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id != R.id.dropdown_menu) { // if not the parent hamburger menu if (id == R.id.reset_button_count) { ... } else if (id == R.id.reset_click_count) { ... } else { ... } return true; // return true if we handled the event! } // Otherwise pass it off to the parent class for handling return super.onOptionsItemSelected(item);}
Hardware level: electronics to sense circuits closing or movement
OS: "Interrupts" that tell the Window system something happened
Windows system: Tells which window received the input
Toolkit Architecture:
Views
should get themApplication Program:
Thing to think about...
How would you handle input in a circular component?
Administrivia
Keyboard shortcuts
↑, ←, Pg Up, k | Go to previous slide |
↓, →, Pg Dn, Space, j | Go to next slide |
Home | Go to first slide |
End | Go to last slide |
Number + Return | Go to specific slide |
b / m / f | Toggle blackout / mirrored / fullscreen mode |
c | Clone slideshow |
p | Toggle presenter mode |
s | Start & Stop the presentation timer |
t | Reset the presentation timer |
?, h | Toggle this help |
Esc | Back to slideshow |