Home | History | Annotate | Download | only in widget
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 
     18 package com.example.android.supportv4.widget;
     19 
     20 import android.app.ActionBar;
     21 import android.app.Activity;
     22 import android.content.res.Configuration;
     23 import android.os.Build;
     24 import android.os.Bundle;
     25 import android.support.v4.app.ActionBarDrawerToggle;
     26 import android.support.v4.view.GravityCompat;
     27 import android.support.v4.widget.DrawerLayout;
     28 import android.view.Gravity;
     29 import android.view.MenuItem;
     30 import android.view.View;
     31 import android.widget.AdapterView;
     32 import android.widget.ArrayAdapter;
     33 import android.widget.ListView;
     34 import android.widget.TextView;
     35 import com.example.android.supportv4.R;
     36 import com.example.android.supportv4.Shakespeare;
     37 
     38 /**
     39  * This example illustrates a common usage of the DrawerLayout widget
     40  * in the Android support library.
     41  *
     42  * <p>A DrawerLayout should be positioned at the top of your view hierarchy, placing it
     43  * below the action bar but above your content views. The primary content should match_parent
     44  * in both dimensions. Each drawer should define a reasonable width and match_parent for height.
     45  * Drawer views should be positioned after the content view in your layout to preserve proper
     46  * ordering.</p>
     47  *
     48  * <p>When a navigation (left) drawer is present, the host activity should detect presses of
     49  * the action bar's Up affordance as a signal to open and close the navigation drawer.
     50  * Items within the drawer should fall into one of two categories.</p>
     51  *
     52  * <ul>
     53  *     <li><strong>View switches</strong>. A view switch follows the same basic policies as
     54  *     list or tab navigation in that a view switch does not create navigation history.
     55  *     This pattern should only be used at the root activity of a task, leaving some form
     56  *     of Up navigation active for activities further down the navigation hierarchy.</li>
     57  *     <li><strong>Selective Up</strong>. The drawer allows the user to choose an alternate
     58  *     parent for Up navigation. This allows a user to jump across an app's navigation
     59  *     hierarchy at will. The application should treat this as it treats Up navigation from
     60  *     a different task, replacing the current task stack using TaskStackBuilder or similar.
     61  *     This is the only form of navigation drawer that should be used outside of the root
     62  *     activity of a task.</li>
     63  * </ul>
     64  *
     65  * <p>Right side drawers should be used for actions, not navigation. This follows the pattern
     66  * established by the Action Bar that navigation should be to the left and actions to the right.
     67  * An action should be an operation performed on the current contents of the window,
     68  * for example enabling or disabling a data overlay on top of the current content.</p>
     69  */
     70 public class DrawerLayoutActivity extends Activity {
     71     private DrawerLayout mDrawerLayout;
     72     private ListView mDrawer;
     73     private TextView mContent;
     74 
     75     private ActionBarHelper mActionBar;
     76 
     77     private ActionBarDrawerToggle mDrawerToggle;
     78 
     79     @Override
     80     protected void onCreate(Bundle savedInstanceState) {
     81         super.onCreate(savedInstanceState);
     82 
     83         setContentView(R.layout.drawer_layout);
     84 
     85         mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
     86         mDrawer = (ListView) findViewById(R.id.start_drawer);
     87         mContent = (TextView) findViewById(R.id.content_text);
     88 
     89         mDrawerLayout.setDrawerListener(new DemoDrawerListener());
     90         mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
     91 
     92         // The drawer title must be set in order to announce state changes when
     93         // accessibility is turned on. This is typically a simple description,
     94         // e.g. "Navigation".
     95         mDrawerLayout.setDrawerTitle(GravityCompat.START, getString(R.string.drawer_title));
     96 
     97         mDrawer.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
     98                 Shakespeare.TITLES));
     99         mDrawer.setOnItemClickListener(new DrawerItemClickListener());
    100 
    101         mActionBar = createActionBarHelper();
    102         mActionBar.init();
    103 
    104         // ActionBarDrawerToggle provides convenient helpers for tying together the
    105         // prescribed interactions between a top-level sliding drawer and the action bar.
    106         mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
    107                 R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close);
    108     }
    109 
    110     @Override
    111     protected void onPostCreate(Bundle savedInstanceState) {
    112         super.onPostCreate(savedInstanceState);
    113 
    114         // Sync the toggle state after onRestoreInstanceState has occurred.
    115         mDrawerToggle.syncState();
    116     }
    117 
    118     @Override
    119     public boolean onOptionsItemSelected(MenuItem item) {
    120         /*
    121          * The action bar home/up action should open or close the drawer.
    122          * mDrawerToggle will take care of this.
    123          */
    124         if (mDrawerToggle.onOptionsItemSelected(item)) {
    125             return true;
    126         }
    127         return super.onOptionsItemSelected(item);
    128     }
    129 
    130     @Override
    131     public void onConfigurationChanged(Configuration newConfig) {
    132         super.onConfigurationChanged(newConfig);
    133         mDrawerToggle.onConfigurationChanged(newConfig);
    134     }
    135 
    136     /**
    137      * This list item click listener implements very simple view switching by changing
    138      * the primary content text. The drawer is closed when a selection is made.
    139      */
    140     private class DrawerItemClickListener implements ListView.OnItemClickListener {
    141         @Override
    142         public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    143             mContent.setText(Shakespeare.DIALOGUE[position]);
    144             mActionBar.setTitle(Shakespeare.TITLES[position]);
    145             mDrawerLayout.closeDrawer(mDrawer);
    146         }
    147     }
    148 
    149     /**
    150      * A drawer listener can be used to respond to drawer events such as becoming
    151      * fully opened or closed. You should always prefer to perform expensive operations
    152      * such as drastic relayout when no animation is currently in progress, either before
    153      * or after the drawer animates.
    154      *
    155      * When using ActionBarDrawerToggle, all DrawerLayout listener methods should be forwarded
    156      * if the ActionBarDrawerToggle is not used as the DrawerLayout listener directly.
    157      */
    158     private class DemoDrawerListener implements DrawerLayout.DrawerListener {
    159         @Override
    160         public void onDrawerOpened(View drawerView) {
    161             mDrawerToggle.onDrawerOpened(drawerView);
    162             mActionBar.onDrawerOpened();
    163         }
    164 
    165         @Override
    166         public void onDrawerClosed(View drawerView) {
    167             mDrawerToggle.onDrawerClosed(drawerView);
    168             mActionBar.onDrawerClosed();
    169         }
    170 
    171         @Override
    172         public void onDrawerSlide(View drawerView, float slideOffset) {
    173             mDrawerToggle.onDrawerSlide(drawerView, slideOffset);
    174         }
    175 
    176         @Override
    177         public void onDrawerStateChanged(int newState) {
    178             mDrawerToggle.onDrawerStateChanged(newState);
    179         }
    180     }
    181 
    182     /**
    183      * Create a compatible helper that will manipulate the action bar if available.
    184      */
    185     private ActionBarHelper createActionBarHelper() {
    186         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
    187             return new ActionBarHelperICS();
    188         } else {
    189             return new ActionBarHelper();
    190         }
    191     }
    192 
    193     /**
    194      * Stub action bar helper; this does nothing.
    195      */
    196     private class ActionBarHelper {
    197         public void init() {}
    198         public void onDrawerClosed() {}
    199         public void onDrawerOpened() {}
    200         public void setTitle(CharSequence title) {}
    201     }
    202 
    203     /**
    204      * Action bar helper for use on ICS and newer devices.
    205      */
    206     private class ActionBarHelperICS extends ActionBarHelper {
    207         private final ActionBar mActionBar;
    208         private CharSequence mDrawerTitle;
    209         private CharSequence mTitle;
    210 
    211         ActionBarHelperICS() {
    212             mActionBar = getActionBar();
    213         }
    214 
    215         @Override
    216         public void init() {
    217             mActionBar.setDisplayHomeAsUpEnabled(true);
    218             mActionBar.setHomeButtonEnabled(true);
    219             mTitle = mDrawerTitle = getTitle();
    220         }
    221 
    222         /**
    223          * When the drawer is closed we restore the action bar state reflecting
    224          * the specific contents in view.
    225          */
    226         @Override
    227         public void onDrawerClosed() {
    228             super.onDrawerClosed();
    229             mActionBar.setTitle(mTitle);
    230         }
    231 
    232         /**
    233          * When the drawer is open we set the action bar to a generic title.
    234          * The action bar should only contain data relevant at the top level of
    235          * the nav hierarchy represented by the drawer, as the rest of your content
    236          * will be dimmed down and non-interactive.
    237          */
    238         @Override
    239         public void onDrawerOpened() {
    240             super.onDrawerOpened();
    241             mActionBar.setTitle(mDrawerTitle);
    242         }
    243 
    244         @Override
    245         public void setTitle(CharSequence title) {
    246             mTitle = title;
    247         }
    248     }
    249 }
    250