User Interaction
MENU-GESTURE-NAVIGASI
Basic
Input Events
Basic Input Events
• Key events
• Track
• Touch events
• Other
Key Event Sources
Key Event Sources
Other event sources
• Touch events
• Trackball events
Other events
• Click
‣ Touch a clickable view
‣ Focus a view and press the action
button
‣ Call view.performClick()
• Long click
‣ Same as click. It’s just... longer
Other events
• Focus change
‣ Use DPad to select another view
‣ Call view.requestFocus()
• Create context menu
‣ Long click a view which is registered
for context menu
Handling events
• Register an event listener
OnEventListener listener = new OnEventListener() {
public void/boolean onEvent(...) {...}
};
view.setOnEventListener(listener);
Handling events
• Register an event listener
OnEventListener listener = new OnEventListener() {
public void/boolean onEvent(...) {...}
};
view.setOnEventListener(listener);
Key
Touch
FocusChange
CreateContextMenu
Click
LongClick
Handling events
• Register an event listener
OnClickListener listener = new OnClickListener() {
public void onClick(View view) {...}
};
view.setOnClickListener(listener);
Click listener example:
Handling events
• Extend View and override a method
‣ onKeyDown
‣ onKeyUp
‣ onTrackballEvent
‣ onTouchEvent
‣ onFocusChanged
‣ others...
The InputEvent
object
• Holds the event parameters
• Comes in two flavors - KeyEvent and
MotionEvent
• You receive it as an argument in your
callback
• Some methods worth mentioning:
‣ getAction()
‣ getKeyCode()
‣ getX(), getY()
Event propagation
Activity
dispatch***Event
Event propagation
Activity
dispatch***Event
Window
dispatch
DecorView
dispatch
Target View
dispatch
...
Event propagation
Activity
dispatch***Event
Window
dispatch
DecorView
dispatch
Target View
dispatch
...
bubble
...
bubble
bubble
Event propagation
Activity
dispatch***Event
Window
dispatch
DecorView
dispatch
Target View
dispatch
...
bubble
...
bubble
bubble
View target = ...;
if (target.dispatchTouchEvent(...)) {
return true;
}
return onTouchEvent(...);
Menu
ActionBar and Menus
• The default activity in Andriod Studio is an ActionBarActivity (via
the support.v7 library)
• This provides an ActionBar and menu in the same place back
to Android 2.3.3 (api 10)
• For the purpose of this lecture, that is what I’m going to use.
We have full support for fragments, ActionBar, and menus
• There is an older menu system from api 1, that still works,
but I’m not covering it.
• Note, there is a new ToolBar (via support.v7 library) that can
replaces the ActionBar and allows more support for lollipop
APIs, which we will see later.
• Also the toolbar can be moved around the screen and
support Material Design elements.
Menus
• Menus are created via an xml document
– First create a menu xml (normally in res/menu)
with menu as the type.
• You can add items (and sub menus). You can also group
the items as well.
Menu.xml example:
<group android:id="@+id/group1">
<item android:id="@+id/item1"
android:orderInCategory="5"
android:title="item1"/>
<item android:id="@+id/item2"
android:orderInCategory="10"
android:title="item2"/>
<item android:id="@+id/item3"
android:orderInCategory="1"
android:title="item3"/>
<item android:id="@+id/item4"
android:orderInCategory="3"
android:title="item4"/>
<item android:id="@+id/item5"
android:orderInCategory="2"
android:title="item5"/>
</group>
• Note the
orderInCategory
determines the order of
display, so this will
show:
Item3
Item5
Item3
Item1
item2
Sub menus in xml
• Create and item that
will be the submenu
heading
– Then create a menu
instead of the item tags.
<menu>
<item>
...
<menu>
...
</menu>
...
</item>
</menu>
Menu Java code
• Use onCreateOpensMenu and onOptionsItemSelected
• Which android studio creates for you by default
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here.
int id = item.getItemId();
if (id == R.id. item1) { //assuming previous xml document
return true; //do something here to handle the menu.
} … //handle the rest.
return super.onOptionsItemSelected(item);
}
Popup menus.
• Add a click listener (or longtouch, whatever) to
anything.
– We are using a TextView, so make sure it clickable
– It will then call our code, called
showPopupMenu(View v)
• Note this is not an override, just a method we are using
public void onClick(View v) {
showPopupMenu(v);
}
showPopupMenu
private void showPopupMenu(View v){
PopupMenu popupM = new PopupMenu(this, v);
popupM.inflate(R.menu.popup);
popupM.setOnMenuItemClickListener(new
PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
//do something
return true;
}
});
popupM.show();
}
Popup Menus Visual
Fragments and Menus
• Fragments can contribute to the menu as well
– Including if there is no menu.
– In the OnCreate() method of the fragment, you must
add
• setHasOptionsMenu(true);
– Otherwise the menu methods will not be called.
• A note, when the fragment is showing, the menu
will be there and when the fragment is
“removed”, then those menu items are removed
as well.
– Remember, fragments are nice, because of the
encapsulation.
Fragments and Menus (2)
• Override the following, note the onCreateOptionsMenu is a little different
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.frag2menu, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.frag2item:
//do something.
return true;
}
return super.onOptionsItemSelected(item);
}
Fragment Example
• The show Fragment X is menu from the activity.
Menu creation
• Menu items can be changed later by
– invalidateOptionsMenu();
– Which calls the onCreateOptionsMenu method
again.
– So if you need to change, enable/disable menu
items, you can pretty easily.
ACTIONBAR
Android
Action Bar
• The Action bar can provide a “Back” button to
the parent Activity.
• We can also add “buttons”, except they are
menu items, via the xml
– We can also add sub menu to the ActionBar that
drop down when clicked.
Xml code
• From Googles page: http://developer.android.com/guide/topics/resources/menu-
resource.html
– Using the xmlns:app="http://schemas.android.com/apk/res-auto"
• app:showAsAction=
– ifRoom
• Only place this item in the Action Bar if there is room for it.
– withText
• Also include the title text (defined by android:title) with the action item. You can include this value
along with one of the others as a flag set, by separating them with a pipe |.
– never
• Never place this item in the Action Bar.
– always
• Always place this item in the Action Bar. Avoid using this unless it's critical that the item always
appear in the action bar. Setting multiple items to always appear as action items can result in them
overlapping with other UI in the action bar.
– collapseActionView
• The action view associated with this action item (as declared by android:actionLayout or
android:actionViewClass) is collapsible.
– Introduced in API Level 14.
Xml code example
<menu … xmlns:app="http://schemas.android.com/apk/res-auto" >
<item android:id="@+id/actionmenu_settings"
app:showAsAction="ifRoom"
android:title="@string/action_settings"/>
<item android:id="@+id/submenu"
android:title="sub menu"
app:showAsAction="always" >
<menu>
<item android:id="@+id/asubitem1"
android:orderInCategory="1"
android:title="subitem1"/>
<item android:id="@+id/asubitem2"
android:orderInCategory="2"
android:title="subitem2"/>
</menu>
</item>
<item android:id="@+id/amenuitem1"
android:title="item1"/>
<item android:id="@+id/amenuitem2"
android:title="item2"/>
</menu>
Show if room, if not show in normal
menu
Always shows and creates a
Drop menu (separate from standard
Menu)
Normal menu items
End result
• This shows how it can look
– The sub menu item has been clicked to show the
sub menu.
Action Bar
• We can also have “buttons” as well and change them
as needed, programmatically.
• This example uses the ViewPager fragment example
and adds buttons for Previous and Next
– also finish, but that doesn’t do anything
• The buttons may show at the bottom of the screen if
there is not enough space on the actionbar.
Java code
• We need to use the invalidateOptionsMenu();
every time the page is changed, so
– Using the ViewPager.setOnPageChangeListener(…)
• Otherwise the main work is in the
onCreateOptionsMenu(Menu menu)
OnCreateOptionsMenu
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.activity_screen_slide, menu);
• Enable the previous menu item, if we are not on the first page (xml).
• menu.findItem(R.id.action_previous).setEnabled(viewPager.getCurrentItem() > 0);
• Add either a "next" or "finish" button to the action bar, depending on which page
is currently selected. Done programmatically.
MenuItem item = menu.add(Menu.NONE, R.id.action_next, Menu.NONE,
(viewPager.getCurrentItem() == mPagerAdapter.getCount() - 1)
? R.string.action_finish
: R.string.action_next);
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM |
MenuItem.SHOW_AS_ACTION_WITH_TEXT);
return true;
}
And the result looks like
• First page:
• Third page
• Last page
Other things xml .
• android:titleCondensed="string“
• android:icon="@[package:]drawable/drawable_resource_name“
• android:onClick="method name“
• android:actionLayout="@[package:]layout/layout_resource_name
"
• android:actionViewClass="class name"
• android:actionProviderClass="class name"
• android:alphabeticShortcut="string"
• android:numericShortcut="string"
• android:checkable=["true" | "false"]
• The layout allows you to add say a search bar to the top.
Gestures
What is a gesture?
• A series of touch events with pre-defined
behavior
• Common gestures:
Fling Long Press Pinch Scroll
Detecting Gestures
• The easy way:
1. Create a gesture listener - either
implement OnGestureListener or
extend SimpleOnGestureListener
2. Create a GestureDetector with your
gesture listener
3. Pass all touch events of your view to
the GestureDetector
Detecting Gestures
• The hard way:
1. Handle touch events for your view
2. Inspect the history of pointer
movement and detect patterns - too
messy for this lecture
3. Make sure no one steals your events -
even messier... Involves methods like
onInterceptTouchEvent and
requestDisallowInterceptTouchEvent
Drag & Drop
Drag & Drop
• Available since API level 11 (Android
3.0.x)
• Only works within a single application
• Allows users to move data (and other
stuff) within your Activity layout
Drag & Drop Workflow
• Register OnDragListeners for each
View you want to support drag & drop
• Call view.startDrag() whenever you
decide, e.g. when view is long pressed
• Respond to the incoming drag events
through your OnDragListeners
Drag & Drop Example
Drag & Drop Example
DRAG_STARTED DRAG_STARTED DRAG_STARTED
startDrag()
Drag & Drop Example
DRAG_STARTED DRAG_STARTED DRAG_STARTED
DRAG_ENTERED
startDrag()
Drag & Drop Example
DRAG_STARTED DRAG_STARTED DRAG_STARTED
DRAG_ENTERED
DRAG_LOCATION
DRAG_LOCATION
DRAG_LOCATION
DRAG_EXITED
startDrag()
Drag & Drop Example
DRAG_STARTED DRAG_STARTED DRAG_STARTED
DRAG_ENTERED
DRAG_LOCATION
DRAG_LOCATION
DRAG_LOCATION
DRAG_EXITED
DRAG_ENTERED
startDrag()
Drag & Drop Example
DRAG_STARTED DRAG_STARTED DRAG_STARTED
DRAG_ENTERED
DRAG_LOCATION
DRAG_LOCATION
DRAG_LOCATION
DRAG_EXITED
DRAG_ENTERED
DRAG_LOCATION
DRAG_LOCATION
startDrag()
Drag & Drop Example
DRAG_STARTED DRAG_STARTED DRAG_STARTED
DRAG_ENTERED
DRAG_LOCATION
DRAG_LOCATION
DRAG_LOCATION
DRAG_EXITED
DRAG_ENDED
DRAG_ENDED DRAG_ENTERED
DRAG_LOCATION
DRAG_LOCATION
DROP
DRAG_ENDED
startDrag()
Common Gestures
Handling Common Gestures
Create a GestureDetector.OnGestureListener (Several Gestures) or a
GestureDetector.SimpleOnGestureListener (More Gestures)
Use the GestureDetecture class
Add a GestureDetector object to the View
Override View.onTouchEvent method to pass MotionEvent on to the
GestureDetector.onTouchEvent method
Override the callback methods for onScroll, onLongPress, onFling,
onSingleTapConfirmed, etc.
Motion Event
Motion events describe movements in terms of an action code and a set of
axis values. The action code specifies the state change that occurred such as
a pointer going down or up. The axis values describe the position and other
movement properties.
For example, when the user first touches the screen, the system delivers a
touch event to the appropriate View with the action code ACTION_DOWN
and a set of axis values that include the X and Y coordinates of the touch
and information about the pressure, size and orientation of the contact
area.
Some devices can report multiple movement traces at the same time. Multi-
touch screens emit one movement trace for each finger. The individual
fingers or other objects that generate movement traces are referred to as
pointers. Motion events contain information about all of the pointers that
are currently active even if some of them have not moved since the last
event was delivered.
Simple Gesture Demo
App that listens for simple gestures
Updates lower TextView in call back methods
Gesture Demo
public class MainActivity extends AppCompatActivity implements
GestureDetector.OnGestureListener,
GestureDetector.OnDoubleTapListener {
GestureDetectorCompat gestureDetectorCompat;
TextView gesture;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gesture=findViewById(R.id.textView);
gestureDetectorCompat=new
GestureDetectorCompat(this,this);
gestureDetectorCompat.setIsLongpressEnabled(true);
}
Gesture Demo
Here, simply pass event on to the GestureDetectorCompat object.
◦ It will call back methods
@Override
public boolean onTouchEvent(MotionEvent event) {
gestureDetectorCompat.onTouchEvent(event);
return super.onTouchEvent(event);
}
Callback methods for
OnGestureLitener
@Override
public boolean onDown(MotionEvent e) {
gesture.setText("Down");
return true;
}
@Override
public void onShowPress(MotionEvent e) {
gesture.setText("Show Press");
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
gesture.setText("Single Tap Up");
return true;
}
Callback methods for
OnGestureLitener
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
gesture.setText("Scroll");
return true;
}
@Override
public void onLongPress(MotionEvent e) {
gesture.setText("Long Press");
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2,
float velocityX, float velocityY) {
gesture.setText("Fling");
return true;
}
Callback methods for
OnDoubleTapLitener
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
gesture.setText("Single Tap Confirmed");
return true;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
gesture.setText("Double Tap");
return true; }
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
gesture.setText("Double Tap Confirmed");
return true;
}
Multi-Touch
Gestures
Multi Touch Gestures
Multiple fingers (pointers) touch screen at the same time
Handled via MotionEvents
Each pointer has a MotionEvent
Track via index (an array of MotionEvents) or ID
MotionEvent object sent to onTouch contains number of “pointers”
involved
Displaying Multitouch data
Using methods of MotionEventCompat class
@Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getPointerCount() > 1){
gesture.setText("Multi TouchnEvent");
int action = event.getAction();
int index = event.getActionIndex();
gesture.append("n"+ actionToString(action)+"n Pointer Index: "+index);
}
gestureDetectorCompat.onTouchEvent(event);
return super.onTouchEvent(event);
}
Scale Gestures
Use ScaleGestureDetector Class
◦ Pinch to zoom in or out
◦ Out – Scale Up
◦ In – Scale Down
Scale Gestures
Create a class that implements
◦ ScaleGestureDetector.OnScaleGestureListener
OR a class that extends
◦ ScaleGestureDetector.SimpleOnScaleGestureListener
◦ Implement methods with dummy methods
◦ Override only the methods you care about
Create a ScaleGestureDetector with listener
Pass MotionEvents from onTouch
Scaling Example
public class MainActivity extends Activity implements ScaleGestureDetector.OnScaleGestureListener{
private TextView textView;
private float scale = 1f;
private float onScaleBegin = 0;
private float onScaleEnd = 0;
private ScaleGestureDetector detector;
String TAG = "DBG";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textView);
detector = new ScaleGestureDetector(this, this);
}
public boolean onTouchEvent(MotionEvent event) {
detector.onTouchEvent(event);
return super.onTouchEvent(event);
}
@Override
public boolean onScale(ScaleGestureDetector detector) {
scale *= detector.getScaleFactor();
// Don't let the object get too small or too large.
scale = Math.max(0.1f, Math.min(scale, 5.0f));
textView.setText(“Scale Factor:”+scale);
return true;
}
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
Log.d(TAG, "onScaleBegin");
onScaleBegin = scale;
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
Log.d(TAG, "onScaleEnd");
onScaleEnd = scale;
if (onScaleEnd > onScaleBegin) {
Toast.makeText(getApplicationContext(), "Scaled Up by a factor of " + String.valueOf(onScaleEnd /
onScaleBegin), Toast.LENGTH_SHORT).show();
}
if (onScaleEnd < onScaleBegin) {
Toast.makeText(getApplicationContext(), "Scaled Down by a factor of " + String.valueOf(onScaleBegin /
onScaleEnd), Toast.LENGTH_SHORT).show();
}
}
}
Complex
Gestures
Complex Gestures
Gesture Builder App on your device(Real
or Emulator)
◦ To define custom gestures you want your
app to recognize
Open the Gesture Builder App and
create your custom gestures as shown in
the gif image
◦ Each gesture is associated with a name
◦ Limited to single pointer
◦ Multiple gestures can have same name
◦ Variations on same gesture, better chance of
recognizing
Note: To see the image start slide show
Custom Gestures
After create above custom gestures, the app will create a file which
name is gesture.txt in the emulator to store the two gesture info. The
file is saved in
directory /storage/emulated/0/Android/data/pack.GestureApp.
Although it has a txt suffix, but the file is a binary file in fact.
To get above gesture.txt file, open Device File Explorer as shown below.
Contd.
Navigate to the directory
/storage/emulated/0/Android/data/pack.GestureApp, right click on
gesture.txt and save it as gesture.txt in the raw folder within your app’s
res folder.
Now you can use your defined custom gestures in your application
Recognize Custom Gesture In
Android Source Code
Recognize gestures via GestureOverlayView
◦ This widget is kind of a simple drawing board that shows and
captures user gestures.
When gesture is completed GestureLibrary is queried to see if
gesture is recognized
Predictions are made between entered gesture and those in
the library
Steps
Add a widget of GestureOverlayView class in layout xml file.
Create a class that implements
GestureOverlayView.OnGesturePerformedListener interface
◦ override it’s onGesturePerformed method
Create an instance of the class just created and
invoke GestureOverlayView‘s addOnGesturePerformedListener metho
d to set it.
Then when you start the app, gesture overlay view widget will capture
any gesture you performed and use the custom listener to response to
it.
Sample Code (Layout File)
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.gesture.GestureOverlayView
android:id="@+id/gesture_overlay_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gestureColor="@color/colorPrimary"
android:uncertainGestureColor="@color/colorPrimary"
android:gestureStrokeType="multiple"/>
</FrameLayout>
Sample Code
(MainActivity.java)
public class MainActivity extends AppCompatActivity {
private GestureOverlayView gestureOverlayView = null;
private GestureLibrary gestureLibrary = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gestureOverlayView = (GestureOverlayView)findViewById(R.id.gesture_overlay_view);
if(gestureLibrary == null)
{
// Load custom gestures from gesture.txt file.
gestureLibrary = GestureLibraries.fromRawResource(this, R.raw.gesture);
if(!gestureLibrary.load())
{
Toast.makeText(this, "Custom gesture file load failed.",Toast.LENGTH_LONG).show();
}
}
GesturePerformListener gesturePerformListener = new GesturePerformListener(this,gestureLibrary);
gestureOverlayView.addOnGesturePerformedListener(gesturePerformListener);
}
}
Sample Code (GesturePerformListener.java)
public class GesturePerformListener implements GestureOverlayView.OnGesturePerformedListener {
private GestureLibrary gestureLibrary = null;
private Context c;
public GesturePerformListener(Context c, GestureLibrary gestureLibrary) {
this.gestureLibrary = gestureLibrary;
this.c = c;
}
@Override
public void onGesturePerformed(GestureOverlayView gestureOverlayView, Gesture gesture) {
// Recognize the gesture and return prediction list.
ArrayList<Prediction> predictionList = gestureLibrary.recognize(gesture);
int size = predictionList.size();
if(size > 0)
{
// Get the first prediction.
Prediction firstPrediction = predictionList.get(0);
/* Higher score higher gesture match. */
if(firstPrediction.score > 5)
{
String action = firstPrediction.name;
Toast.makeText(c, "Your gesture match "+action, Toast.LENGTH_LONG).show();
}else
{
Toast.makeText(c, "Your gesture do not match any predefined gestures.", Toast.LENGTH_LONG).show();
}
}
}
}
NAVIGATION
Navigation visual
Back Button
ActionBar/
ToolBar
Menu
Note: If there is physical menu button, then the menu does not show on the screen
Navigation Drawer
Action Buttons
Navigation Drawer
• Provides a slider window that allows you have
navigation, like a listview, but not always on
screen.
Closed Opened
Navigation Drawer
• It uses a Drawer layout that takes two “views”
– Both views are likely layouts or fragments
– View/layout 1 is the main content.
– The one that shows when the drawer is closed.
– View/layout 2 is the drawer content.
– What shows when the drawer is open.
» Mostly like has a listview as well.
Navigation Drawer xml code
<android.support.v4.widget.DrawerLayout … android:id="@+id/drawer_layout"
android:layout_width="match_parent" android:layout_height="match_parent">
<!-- As the main content view -->
<…Layout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- whatever views/widgets needed -->
</…Layout>
<!– drawer content view -->
<ListView android:id="@+id/left_drawer"
android:layout_gravity="start" //default left to right and switch for right to left
languages.
android:choiceMode="singleChoice"/>
</android.support.v4.widget.DrawerLayout>
DrawerLayout Java
• The listview is setup like normal
– Except on a selection, we also close the drawer.
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
In the setOnItemClickListener use mDrawerLayout.closeDrawers();
• We need to tie the drawer to the actionbar, so
the icons show, uses the
ActionBarDrawerToggle.
DrawerLayout Java (2)
• enable ActionBar app icon to behave as action to toggle nav drawer
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
• ActionBarDrawerToggle ties together the proper interactions between the sliding drawer and the action
bar app icon
mDrawerToggle = new ActionBarDrawerToggle(this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.string.drawer_open, /* "open drawer" description for accessibility */
R.string.drawer_close /* "close drawer" description for accessibility */
) {
public void onDrawerClosed(View view) {
getSupportActionBar().setTitle(R.string.app_name); //change the title back , when closed.
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
public void onDrawerOpened(View drawerView) {
getSupportActionBar().setTitle("Categories"); //change the name, when opened.
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
} };
mDrawerLayout.setDrawerListener(mDrawerToggle);
DrawerLayout Java (3)
• Lastly, these two or it doesn’t drawer correctly in the actionbar.
/**
* When using the ActionBarDrawerToggle, you must call it during
* onPostCreate() and onConfigurationChanged()...
*/
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Pass any configuration change to the drawer toggls
mDrawerToggle.onConfigurationChanged(newConfig);
}
DrawerLayout Java (4)
• Lastly, a fix to the menu as well.
public boolean onOptionsItemSelected(MenuItem item) {
// The action bar home/up action should open or
close the drawer.
// ActionBarDrawerToggle will take care of this.
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
…
Demos
• The NavDrawerFragDemo
– Uses the Shakespeare fragments from listview demos
in the Drawerlayout
• Not the ListFragment, since you need to change the text
color correctly, for a dark background and light text color.
• Also changing the listview rowlayout.
• NavDrawer is google example, show a listview and
fragment.
– Some corrections for the newer version of the
drawerlayout.
ToolBar
• The ToolBar is a replacement for the ActionBar
– Basically everything works the same, but uses a
support.v7.widget.Toolbar.
– It’s better suited to cover with Lollipop and
Material Design lecture.

Chapt 04 user interaction

  • 1.
  • 2.
  • 3.
    Basic Input Events •Key events • Track • Touch events • Other
  • 4.
  • 5.
  • 6.
    Other event sources •Touch events • Trackball events
  • 7.
    Other events • Click ‣Touch a clickable view ‣ Focus a view and press the action button ‣ Call view.performClick() • Long click ‣ Same as click. It’s just... longer
  • 8.
    Other events • Focuschange ‣ Use DPad to select another view ‣ Call view.requestFocus() • Create context menu ‣ Long click a view which is registered for context menu
  • 9.
    Handling events • Registeran event listener OnEventListener listener = new OnEventListener() { public void/boolean onEvent(...) {...} }; view.setOnEventListener(listener);
  • 10.
    Handling events • Registeran event listener OnEventListener listener = new OnEventListener() { public void/boolean onEvent(...) {...} }; view.setOnEventListener(listener); Key Touch FocusChange CreateContextMenu Click LongClick
  • 11.
    Handling events • Registeran event listener OnClickListener listener = new OnClickListener() { public void onClick(View view) {...} }; view.setOnClickListener(listener); Click listener example:
  • 12.
    Handling events • ExtendView and override a method ‣ onKeyDown ‣ onKeyUp ‣ onTrackballEvent ‣ onTouchEvent ‣ onFocusChanged ‣ others...
  • 13.
    The InputEvent object • Holdsthe event parameters • Comes in two flavors - KeyEvent and MotionEvent • You receive it as an argument in your callback • Some methods worth mentioning: ‣ getAction() ‣ getKeyCode() ‣ getX(), getY()
  • 14.
  • 15.
  • 16.
  • 17.
    Event propagation Activity dispatch***Event Window dispatch DecorView dispatch Target View dispatch ... bubble ... bubble bubble Viewtarget = ...; if (target.dispatchTouchEvent(...)) { return true; } return onTouchEvent(...);
  • 18.
  • 19.
    ActionBar and Menus •The default activity in Andriod Studio is an ActionBarActivity (via the support.v7 library) • This provides an ActionBar and menu in the same place back to Android 2.3.3 (api 10) • For the purpose of this lecture, that is what I’m going to use. We have full support for fragments, ActionBar, and menus • There is an older menu system from api 1, that still works, but I’m not covering it. • Note, there is a new ToolBar (via support.v7 library) that can replaces the ActionBar and allows more support for lollipop APIs, which we will see later. • Also the toolbar can be moved around the screen and support Material Design elements.
  • 21.
    Menus • Menus arecreated via an xml document – First create a menu xml (normally in res/menu) with menu as the type. • You can add items (and sub menus). You can also group the items as well.
  • 22.
    Menu.xml example: <group android:id="@+id/group1"> <itemandroid:id="@+id/item1" android:orderInCategory="5" android:title="item1"/> <item android:id="@+id/item2" android:orderInCategory="10" android:title="item2"/> <item android:id="@+id/item3" android:orderInCategory="1" android:title="item3"/> <item android:id="@+id/item4" android:orderInCategory="3" android:title="item4"/> <item android:id="@+id/item5" android:orderInCategory="2" android:title="item5"/> </group> • Note the orderInCategory determines the order of display, so this will show: Item3 Item5 Item3 Item1 item2
  • 23.
    Sub menus inxml • Create and item that will be the submenu heading – Then create a menu instead of the item tags. <menu> <item> ... <menu> ... </menu> ... </item> </menu>
  • 24.
    Menu Java code •Use onCreateOpensMenu and onOptionsItemSelected • Which android studio creates for you by default @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. int id = item.getItemId(); if (id == R.id. item1) { //assuming previous xml document return true; //do something here to handle the menu. } … //handle the rest. return super.onOptionsItemSelected(item); }
  • 25.
    Popup menus. • Adda click listener (or longtouch, whatever) to anything. – We are using a TextView, so make sure it clickable – It will then call our code, called showPopupMenu(View v) • Note this is not an override, just a method we are using public void onClick(View v) { showPopupMenu(v); }
  • 26.
    showPopupMenu private void showPopupMenu(Viewv){ PopupMenu popupM = new PopupMenu(this, v); popupM.inflate(R.menu.popup); popupM.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { //do something return true; } }); popupM.show(); }
  • 27.
  • 28.
    Fragments and Menus •Fragments can contribute to the menu as well – Including if there is no menu. – In the OnCreate() method of the fragment, you must add • setHasOptionsMenu(true); – Otherwise the menu methods will not be called. • A note, when the fragment is showing, the menu will be there and when the fragment is “removed”, then those menu items are removed as well. – Remember, fragments are nice, because of the encapsulation.
  • 29.
    Fragments and Menus(2) • Override the following, note the onCreateOptionsMenu is a little different @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); inflater.inflate(R.menu.frag2menu, menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.frag2item: //do something. return true; } return super.onOptionsItemSelected(item); }
  • 30.
    Fragment Example • Theshow Fragment X is menu from the activity.
  • 31.
    Menu creation • Menuitems can be changed later by – invalidateOptionsMenu(); – Which calls the onCreateOptionsMenu method again. – So if you need to change, enable/disable menu items, you can pretty easily.
  • 32.
  • 33.
    Action Bar • TheAction bar can provide a “Back” button to the parent Activity. • We can also add “buttons”, except they are menu items, via the xml – We can also add sub menu to the ActionBar that drop down when clicked.
  • 34.
    Xml code • FromGoogles page: http://developer.android.com/guide/topics/resources/menu- resource.html – Using the xmlns:app="http://schemas.android.com/apk/res-auto" • app:showAsAction= – ifRoom • Only place this item in the Action Bar if there is room for it. – withText • Also include the title text (defined by android:title) with the action item. You can include this value along with one of the others as a flag set, by separating them with a pipe |. – never • Never place this item in the Action Bar. – always • Always place this item in the Action Bar. Avoid using this unless it's critical that the item always appear in the action bar. Setting multiple items to always appear as action items can result in them overlapping with other UI in the action bar. – collapseActionView • The action view associated with this action item (as declared by android:actionLayout or android:actionViewClass) is collapsible. – Introduced in API Level 14.
  • 35.
    Xml code example <menu… xmlns:app="http://schemas.android.com/apk/res-auto" > <item android:id="@+id/actionmenu_settings" app:showAsAction="ifRoom" android:title="@string/action_settings"/> <item android:id="@+id/submenu" android:title="sub menu" app:showAsAction="always" > <menu> <item android:id="@+id/asubitem1" android:orderInCategory="1" android:title="subitem1"/> <item android:id="@+id/asubitem2" android:orderInCategory="2" android:title="subitem2"/> </menu> </item> <item android:id="@+id/amenuitem1" android:title="item1"/> <item android:id="@+id/amenuitem2" android:title="item2"/> </menu> Show if room, if not show in normal menu Always shows and creates a Drop menu (separate from standard Menu) Normal menu items
  • 36.
    End result • Thisshows how it can look – The sub menu item has been clicked to show the sub menu.
  • 37.
    Action Bar • Wecan also have “buttons” as well and change them as needed, programmatically. • This example uses the ViewPager fragment example and adds buttons for Previous and Next – also finish, but that doesn’t do anything • The buttons may show at the bottom of the screen if there is not enough space on the actionbar.
  • 38.
    Java code • Weneed to use the invalidateOptionsMenu(); every time the page is changed, so – Using the ViewPager.setOnPageChangeListener(…) • Otherwise the main work is in the onCreateOptionsMenu(Menu menu)
  • 39.
    OnCreateOptionsMenu public boolean onCreateOptionsMenu(Menumenu) { super.onCreateOptionsMenu(menu); getMenuInflater().inflate(R.menu.activity_screen_slide, menu); • Enable the previous menu item, if we are not on the first page (xml). • menu.findItem(R.id.action_previous).setEnabled(viewPager.getCurrentItem() > 0); • Add either a "next" or "finish" button to the action bar, depending on which page is currently selected. Done programmatically. MenuItem item = menu.add(Menu.NONE, R.id.action_next, Menu.NONE, (viewPager.getCurrentItem() == mPagerAdapter.getCount() - 1) ? R.string.action_finish : R.string.action_next); item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); return true; }
  • 40.
    And the resultlooks like • First page: • Third page • Last page
  • 41.
    Other things xml. • android:titleCondensed="string“ • android:icon="@[package:]drawable/drawable_resource_name“ • android:onClick="method name“ • android:actionLayout="@[package:]layout/layout_resource_name " • android:actionViewClass="class name" • android:actionProviderClass="class name" • android:alphabeticShortcut="string" • android:numericShortcut="string" • android:checkable=["true" | "false"] • The layout allows you to add say a search bar to the top.
  • 42.
  • 43.
    What is agesture? • A series of touch events with pre-defined behavior • Common gestures: Fling Long Press Pinch Scroll
  • 44.
    Detecting Gestures • Theeasy way: 1. Create a gesture listener - either implement OnGestureListener or extend SimpleOnGestureListener 2. Create a GestureDetector with your gesture listener 3. Pass all touch events of your view to the GestureDetector
  • 45.
    Detecting Gestures • Thehard way: 1. Handle touch events for your view 2. Inspect the history of pointer movement and detect patterns - too messy for this lecture 3. Make sure no one steals your events - even messier... Involves methods like onInterceptTouchEvent and requestDisallowInterceptTouchEvent
  • 46.
  • 47.
    Drag & Drop •Available since API level 11 (Android 3.0.x) • Only works within a single application • Allows users to move data (and other stuff) within your Activity layout
  • 48.
    Drag & DropWorkflow • Register OnDragListeners for each View you want to support drag & drop • Call view.startDrag() whenever you decide, e.g. when view is long pressed • Respond to the incoming drag events through your OnDragListeners
  • 49.
    Drag & DropExample
  • 50.
    Drag & DropExample DRAG_STARTED DRAG_STARTED DRAG_STARTED startDrag()
  • 51.
    Drag & DropExample DRAG_STARTED DRAG_STARTED DRAG_STARTED DRAG_ENTERED startDrag()
  • 52.
    Drag & DropExample DRAG_STARTED DRAG_STARTED DRAG_STARTED DRAG_ENTERED DRAG_LOCATION DRAG_LOCATION DRAG_LOCATION DRAG_EXITED startDrag()
  • 53.
    Drag & DropExample DRAG_STARTED DRAG_STARTED DRAG_STARTED DRAG_ENTERED DRAG_LOCATION DRAG_LOCATION DRAG_LOCATION DRAG_EXITED DRAG_ENTERED startDrag()
  • 54.
    Drag & DropExample DRAG_STARTED DRAG_STARTED DRAG_STARTED DRAG_ENTERED DRAG_LOCATION DRAG_LOCATION DRAG_LOCATION DRAG_EXITED DRAG_ENTERED DRAG_LOCATION DRAG_LOCATION startDrag()
  • 55.
    Drag & DropExample DRAG_STARTED DRAG_STARTED DRAG_STARTED DRAG_ENTERED DRAG_LOCATION DRAG_LOCATION DRAG_LOCATION DRAG_EXITED DRAG_ENDED DRAG_ENDED DRAG_ENTERED DRAG_LOCATION DRAG_LOCATION DROP DRAG_ENDED startDrag()
  • 56.
  • 57.
    Handling Common Gestures Createa GestureDetector.OnGestureListener (Several Gestures) or a GestureDetector.SimpleOnGestureListener (More Gestures) Use the GestureDetecture class Add a GestureDetector object to the View Override View.onTouchEvent method to pass MotionEvent on to the GestureDetector.onTouchEvent method Override the callback methods for onScroll, onLongPress, onFling, onSingleTapConfirmed, etc.
  • 58.
    Motion Event Motion eventsdescribe movements in terms of an action code and a set of axis values. The action code specifies the state change that occurred such as a pointer going down or up. The axis values describe the position and other movement properties. For example, when the user first touches the screen, the system delivers a touch event to the appropriate View with the action code ACTION_DOWN and a set of axis values that include the X and Y coordinates of the touch and information about the pressure, size and orientation of the contact area. Some devices can report multiple movement traces at the same time. Multi- touch screens emit one movement trace for each finger. The individual fingers or other objects that generate movement traces are referred to as pointers. Motion events contain information about all of the pointers that are currently active even if some of them have not moved since the last event was delivered.
  • 59.
    Simple Gesture Demo Appthat listens for simple gestures Updates lower TextView in call back methods
  • 60.
    Gesture Demo public classMainActivity extends AppCompatActivity implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener { GestureDetectorCompat gestureDetectorCompat; TextView gesture; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); gesture=findViewById(R.id.textView); gestureDetectorCompat=new GestureDetectorCompat(this,this); gestureDetectorCompat.setIsLongpressEnabled(true); }
  • 61.
    Gesture Demo Here, simplypass event on to the GestureDetectorCompat object. ◦ It will call back methods @Override public boolean onTouchEvent(MotionEvent event) { gestureDetectorCompat.onTouchEvent(event); return super.onTouchEvent(event); }
  • 62.
    Callback methods for OnGestureLitener @Override publicboolean onDown(MotionEvent e) { gesture.setText("Down"); return true; } @Override public void onShowPress(MotionEvent e) { gesture.setText("Show Press"); } @Override public boolean onSingleTapUp(MotionEvent e) { gesture.setText("Single Tap Up"); return true; }
  • 63.
    Callback methods for OnGestureLitener @Override publicboolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { gesture.setText("Scroll"); return true; } @Override public void onLongPress(MotionEvent e) { gesture.setText("Long Press"); } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { gesture.setText("Fling"); return true; }
  • 64.
    Callback methods for OnDoubleTapLitener @Override publicboolean onSingleTapConfirmed(MotionEvent e) { gesture.setText("Single Tap Confirmed"); return true; } @Override public boolean onDoubleTap(MotionEvent e) { gesture.setText("Double Tap"); return true; } @Override public boolean onDoubleTapEvent(MotionEvent e) { gesture.setText("Double Tap Confirmed"); return true; }
  • 65.
  • 66.
    Multi Touch Gestures Multiplefingers (pointers) touch screen at the same time Handled via MotionEvents Each pointer has a MotionEvent Track via index (an array of MotionEvents) or ID MotionEvent object sent to onTouch contains number of “pointers” involved
  • 67.
    Displaying Multitouch data Usingmethods of MotionEventCompat class @Override public boolean onTouchEvent(MotionEvent event) { if(event.getPointerCount() > 1){ gesture.setText("Multi TouchnEvent"); int action = event.getAction(); int index = event.getActionIndex(); gesture.append("n"+ actionToString(action)+"n Pointer Index: "+index); } gestureDetectorCompat.onTouchEvent(event); return super.onTouchEvent(event); }
  • 68.
    Scale Gestures Use ScaleGestureDetectorClass ◦ Pinch to zoom in or out ◦ Out – Scale Up ◦ In – Scale Down
  • 69.
    Scale Gestures Create aclass that implements ◦ ScaleGestureDetector.OnScaleGestureListener OR a class that extends ◦ ScaleGestureDetector.SimpleOnScaleGestureListener ◦ Implement methods with dummy methods ◦ Override only the methods you care about Create a ScaleGestureDetector with listener Pass MotionEvents from onTouch
  • 70.
    Scaling Example public classMainActivity extends Activity implements ScaleGestureDetector.OnScaleGestureListener{ private TextView textView; private float scale = 1f; private float onScaleBegin = 0; private float onScaleEnd = 0; private ScaleGestureDetector detector; String TAG = "DBG"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = findViewById(R.id.textView); detector = new ScaleGestureDetector(this, this); } public boolean onTouchEvent(MotionEvent event) { detector.onTouchEvent(event); return super.onTouchEvent(event); } @Override public boolean onScale(ScaleGestureDetector detector) { scale *= detector.getScaleFactor(); // Don't let the object get too small or too large. scale = Math.max(0.1f, Math.min(scale, 5.0f)); textView.setText(“Scale Factor:”+scale); return true; } @Override public boolean onScaleBegin(ScaleGestureDetector detector) { Log.d(TAG, "onScaleBegin"); onScaleBegin = scale; return true; } @Override public void onScaleEnd(ScaleGestureDetector detector) { Log.d(TAG, "onScaleEnd"); onScaleEnd = scale; if (onScaleEnd > onScaleBegin) { Toast.makeText(getApplicationContext(), "Scaled Up by a factor of " + String.valueOf(onScaleEnd / onScaleBegin), Toast.LENGTH_SHORT).show(); } if (onScaleEnd < onScaleBegin) { Toast.makeText(getApplicationContext(), "Scaled Down by a factor of " + String.valueOf(onScaleBegin / onScaleEnd), Toast.LENGTH_SHORT).show(); } } }
  • 71.
  • 72.
    Complex Gestures Gesture BuilderApp on your device(Real or Emulator) ◦ To define custom gestures you want your app to recognize Open the Gesture Builder App and create your custom gestures as shown in the gif image ◦ Each gesture is associated with a name ◦ Limited to single pointer ◦ Multiple gestures can have same name ◦ Variations on same gesture, better chance of recognizing Note: To see the image start slide show
  • 73.
    Custom Gestures After createabove custom gestures, the app will create a file which name is gesture.txt in the emulator to store the two gesture info. The file is saved in directory /storage/emulated/0/Android/data/pack.GestureApp. Although it has a txt suffix, but the file is a binary file in fact. To get above gesture.txt file, open Device File Explorer as shown below.
  • 74.
    Contd. Navigate to thedirectory /storage/emulated/0/Android/data/pack.GestureApp, right click on gesture.txt and save it as gesture.txt in the raw folder within your app’s res folder. Now you can use your defined custom gestures in your application
  • 75.
    Recognize Custom GestureIn Android Source Code Recognize gestures via GestureOverlayView ◦ This widget is kind of a simple drawing board that shows and captures user gestures. When gesture is completed GestureLibrary is queried to see if gesture is recognized Predictions are made between entered gesture and those in the library
  • 76.
    Steps Add a widgetof GestureOverlayView class in layout xml file. Create a class that implements GestureOverlayView.OnGesturePerformedListener interface ◦ override it’s onGesturePerformed method Create an instance of the class just created and invoke GestureOverlayView‘s addOnGesturePerformedListener metho d to set it. Then when you start the app, gesture overlay view widget will capture any gesture you performed and use the custom listener to response to it.
  • 77.
    Sample Code (LayoutFile) <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <android.gesture.GestureOverlayView android:id="@+id/gesture_overlay_view" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:gestureColor="@color/colorPrimary" android:uncertainGestureColor="@color/colorPrimary" android:gestureStrokeType="multiple"/> </FrameLayout>
  • 78.
    Sample Code (MainActivity.java) public classMainActivity extends AppCompatActivity { private GestureOverlayView gestureOverlayView = null; private GestureLibrary gestureLibrary = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); gestureOverlayView = (GestureOverlayView)findViewById(R.id.gesture_overlay_view); if(gestureLibrary == null) { // Load custom gestures from gesture.txt file. gestureLibrary = GestureLibraries.fromRawResource(this, R.raw.gesture); if(!gestureLibrary.load()) { Toast.makeText(this, "Custom gesture file load failed.",Toast.LENGTH_LONG).show(); } } GesturePerformListener gesturePerformListener = new GesturePerformListener(this,gestureLibrary); gestureOverlayView.addOnGesturePerformedListener(gesturePerformListener); } }
  • 79.
    Sample Code (GesturePerformListener.java) publicclass GesturePerformListener implements GestureOverlayView.OnGesturePerformedListener { private GestureLibrary gestureLibrary = null; private Context c; public GesturePerformListener(Context c, GestureLibrary gestureLibrary) { this.gestureLibrary = gestureLibrary; this.c = c; } @Override public void onGesturePerformed(GestureOverlayView gestureOverlayView, Gesture gesture) { // Recognize the gesture and return prediction list. ArrayList<Prediction> predictionList = gestureLibrary.recognize(gesture); int size = predictionList.size(); if(size > 0) { // Get the first prediction. Prediction firstPrediction = predictionList.get(0); /* Higher score higher gesture match. */ if(firstPrediction.score > 5) { String action = firstPrediction.name; Toast.makeText(c, "Your gesture match "+action, Toast.LENGTH_LONG).show(); }else { Toast.makeText(c, "Your gesture do not match any predefined gestures.", Toast.LENGTH_LONG).show(); } } } }
  • 80.
  • 81.
    Navigation visual Back Button ActionBar/ ToolBar Menu Note:If there is physical menu button, then the menu does not show on the screen Navigation Drawer Action Buttons
  • 82.
    Navigation Drawer • Providesa slider window that allows you have navigation, like a listview, but not always on screen. Closed Opened
  • 83.
    Navigation Drawer • Ituses a Drawer layout that takes two “views” – Both views are likely layouts or fragments – View/layout 1 is the main content. – The one that shows when the drawer is closed. – View/layout 2 is the drawer content. – What shows when the drawer is open. » Mostly like has a listview as well.
  • 84.
    Navigation Drawer xmlcode <android.support.v4.widget.DrawerLayout … android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- As the main content view --> <…Layout android:layout_width="match_parent" android:layout_height="match_parent"> <!-- whatever views/widgets needed --> </…Layout> <!– drawer content view --> <ListView android:id="@+id/left_drawer" android:layout_gravity="start" //default left to right and switch for right to left languages. android:choiceMode="singleChoice"/> </android.support.v4.widget.DrawerLayout>
  • 85.
    DrawerLayout Java • Thelistview is setup like normal – Except on a selection, we also close the drawer. mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); In the setOnItemClickListener use mDrawerLayout.closeDrawers(); • We need to tie the drawer to the actionbar, so the icons show, uses the ActionBarDrawerToggle.
  • 86.
    DrawerLayout Java (2) •enable ActionBar app icon to behave as action to toggle nav drawer getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setHomeButtonEnabled(true); • ActionBarDrawerToggle ties together the proper interactions between the sliding drawer and the action bar app icon mDrawerToggle = new ActionBarDrawerToggle(this, /* host Activity */ mDrawerLayout, /* DrawerLayout object */ R.string.drawer_open, /* "open drawer" description for accessibility */ R.string.drawer_close /* "close drawer" description for accessibility */ ) { public void onDrawerClosed(View view) { getSupportActionBar().setTitle(R.string.app_name); //change the title back , when closed. invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu() } public void onDrawerOpened(View drawerView) { getSupportActionBar().setTitle("Categories"); //change the name, when opened. invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu() } }; mDrawerLayout.setDrawerListener(mDrawerToggle);
  • 87.
    DrawerLayout Java (3) •Lastly, these two or it doesn’t drawer correctly in the actionbar. /** * When using the ActionBarDrawerToggle, you must call it during * onPostCreate() and onConfigurationChanged()... */ @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); // Sync the toggle state after onRestoreInstanceState has occurred. mDrawerToggle.syncState(); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); // Pass any configuration change to the drawer toggls mDrawerToggle.onConfigurationChanged(newConfig); }
  • 88.
    DrawerLayout Java (4) •Lastly, a fix to the menu as well. public boolean onOptionsItemSelected(MenuItem item) { // The action bar home/up action should open or close the drawer. // ActionBarDrawerToggle will take care of this. if (mDrawerToggle.onOptionsItemSelected(item)) { return true; } …
  • 89.
    Demos • The NavDrawerFragDemo –Uses the Shakespeare fragments from listview demos in the Drawerlayout • Not the ListFragment, since you need to change the text color correctly, for a dark background and light text color. • Also changing the listview rowlayout. • NavDrawer is google example, show a listview and fragment. – Some corrections for the newer version of the drawerlayout.
  • 90.
    ToolBar • The ToolBaris a replacement for the ActionBar – Basically everything works the same, but uses a support.v7.widget.Toolbar. – It’s better suited to cover with Lollipop and Material Design lecture.