• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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 package android.support.v7.app;
18 
19 import android.content.res.Configuration;
20 import android.content.res.Resources;
21 import android.content.res.TypedArray;
22 import android.os.Bundle;
23 import android.support.v4.view.GravityCompat;
24 import android.support.v4.widget.DrawerLayout;
25 import android.support.v7.appcompat.test.R;
26 import android.support.v7.testutils.BaseTestActivity;
27 import android.support.v7.testutils.Shakespeare;
28 import android.support.v7.widget.Toolbar;
29 import android.view.MenuItem;
30 import android.view.View;
31 import android.view.ViewTreeObserver;
32 import android.widget.AdapterView;
33 import android.widget.ArrayAdapter;
34 import android.widget.ListView;
35 import android.widget.TextView;
36 
37 /**
38  * Test activity for testing various APIs and interactions for DrawerLayout. It follows
39  * a common usage of the DrawerLayout widget combined with Toolbar in the Android support library
40  * that respect the
41  * <a href="https://www.google.com/design/spec/patterns/navigation-drawer.html">Material design
42  * guidelines</a> for the drawer component.
43  */
44 public class DrawerLayoutActivity extends BaseTestActivity {
45     private DrawerLayout mDrawerLayout;
46     private ListView mDrawer;
47     private TextView mContent;
48 
49     private ActionBarDrawerToggle mDrawerToggle;
50     private Toolbar mToolbar;
51 
52     @Override
getContentViewLayoutResId()53     protected int getContentViewLayoutResId() {
54         return R.layout.drawer_layout;
55     }
56 
57     @Override
onContentViewSet()58     protected void onContentViewSet() {
59         super.onContentViewSet();
60 
61         mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
62         mDrawer = (ListView) findViewById(R.id.start_drawer);
63         mContent = (TextView) findViewById(R.id.content_text);
64 
65         mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
66 
67         // The drawer title must be set in order to announce state changes when
68         // accessibility is turned on. This is typically a simple description,
69         // e.g. "Navigation".
70         mDrawerLayout.setDrawerTitle(GravityCompat.START, getString(R.string.drawer_title));
71 
72         mDrawer.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
73                 Shakespeare.TITLES));
74         mDrawer.setOnItemClickListener(new DrawerItemClickListener());
75 
76         // Find the toolbar in our layout and set it as the support action bar on the activity.
77         // This is required to have the drawer slide "over" the toolbar.
78         mToolbar = (Toolbar) findViewById(R.id.toolbar);
79         mToolbar.setTitle(R.string.drawer_title);
80         setSupportActionBar(mToolbar);
81 
82         getSupportActionBar().setDisplayHomeAsUpEnabled(true);
83         getSupportActionBar().setDisplayShowHomeEnabled(false);
84 
85         // ActionBarDrawerToggle provides convenient helpers for tying together the
86         // prescribed interactions between a top-level sliding drawer and the action bar.
87         // Note that, as the Javadocs of ActionBarDrawerToggle constructors say, we are
88         // *not* using a constructor that gets a Toolbar since we're setting our toolbar
89         // dynamically at runtime. Furthermore, as the drawer is sliding over the toolbar,
90         // we are suppressing the morphing animation from hamburger to back arrow by
91         // calling super.onDrawerSlide with slideOffset=0.0f. In case your app only has
92         // top-level pages and doesn't need back arrow visuals at all, you can set up
93         // your activity theme to have attribute named "drawerArrowStyle" that points
94         // to an extension of Widget.AppCompat.DrawerArrowToggle that has its "spinBars"
95         // attribute set to false.
96         mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
97                 R.string.drawer_open, R.string.drawer_close) {
98             @Override
99             public void onDrawerOpened(View drawerView) {
100                 super.onDrawerOpened(drawerView);
101                 super.onDrawerSlide(drawerView, 0.0f);
102             }
103 
104             @Override
105             public void onDrawerSlide(View drawerView, float slideOffset) {
106                 super.onDrawerSlide(drawerView, 0.0f);
107             }
108         };
109 
110         mDrawerLayout.addDrawerListener(mDrawerToggle);
111 
112         // Configure the background color fill of the system status bar (on supported platform
113         // versions) and the toolbar itself. We're using the same color, and android:statusBar
114         // from the theme makes the status bar slightly darker.
115         final int metalBlueColor = getResources().getColor(R.color.drawer_sample_metal_blue);
116         mDrawerLayout.setStatusBarBackgroundColor(metalBlueColor);
117         mToolbar.setBackgroundColor(metalBlueColor);
118 
119         // Register a pre-draw listener to get the initial width of the DrawerLayout so
120         // that we can determine the width of the drawer based on the Material spec at
121         // https://www.google.com/design/spec/patterns/navigation-drawer.html#navigation-drawer-specs
122         mDrawerLayout.getViewTreeObserver().addOnPreDrawListener(
123                 new ViewTreeObserver.OnPreDrawListener() {
124                     @Override
125                     public boolean onPreDraw() {
126                         // What is the width of the entire DrawerLayout?
127                         final int drawerLayoutWidth = mDrawerLayout.getWidth();
128 
129                         // What is the action bar size?
130                         final Resources.Theme theme = mDrawerLayout.getContext().getTheme();
131                         final TypedArray a = theme.obtainStyledAttributes(
132                                 new int[] { android.support.v7.appcompat.R.attr.actionBarSize });
133                         final int actionBarSize = a.getDimensionPixelSize(0, 0);
134                         if (a != null) {
135                             a.recycle();
136                         }
137 
138                         // Compute the width of the drawer and set it on the layout params.
139                         final int idealDrawerWidth = 5 * actionBarSize;
140                         final int maxDrawerWidth = Math.max(0, drawerLayoutWidth - actionBarSize);
141                         final int drawerWidth = Math.min(idealDrawerWidth, maxDrawerWidth);
142 
143                         final DrawerLayout.LayoutParams drawerLp =
144                                 (DrawerLayout.LayoutParams) mDrawer.getLayoutParams();
145                         drawerLp.width = drawerWidth;
146                         mDrawer.setLayoutParams(drawerLp);
147 
148                         // Remove ourselves as the pre-draw listener since this is a one-time
149                         // configuration.
150                         mDrawerLayout.getViewTreeObserver().removeOnPreDrawListener(this);
151                         return true;
152                     }
153                 });
154     }
155 
156     @Override
onPostCreate(Bundle savedInstanceState)157     protected void onPostCreate(Bundle savedInstanceState) {
158         super.onPostCreate(savedInstanceState);
159 
160         // Sync the toggle state after onRestoreInstanceState has occurred.
161         mDrawerToggle.syncState();
162     }
163 
164     @Override
onOptionsItemSelected(MenuItem item)165     public boolean onOptionsItemSelected(MenuItem item) {
166         /*
167          * The action bar home/up action should open or close the drawer.
168          * The drawer toggle will take care of this.
169          */
170         if (mDrawerToggle.onOptionsItemSelected(item)) {
171             return true;
172         }
173         return super.onOptionsItemSelected(item);
174     }
175 
176     @Override
onBackPressed()177     public void onBackPressed() {
178         // Is the drawer open?
179         if (mDrawerLayout.isDrawerOpen(mDrawer)) {
180             // Close the drawer and return.
181             mDrawerLayout.closeDrawer(mDrawer);
182             return;
183         }
184 
185         super.onBackPressed();
186     }
187 
188     @Override
onConfigurationChanged(Configuration newConfig)189     public void onConfigurationChanged(Configuration newConfig) {
190         super.onConfigurationChanged(newConfig);
191         mDrawerToggle.onConfigurationChanged(newConfig);
192     }
193 
194     /**
195      * This list item click listener implements very simple view switching by changing
196      * the primary content text. The drawer is closed when a selection is made.
197      */
198     private class DrawerItemClickListener implements ListView.OnItemClickListener {
199         @Override
onItemClick(AdapterView<?> parent, View view, int position, long id)200         public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
201             mContent.setText(Shakespeare.DIALOGUE[position]);
202             mToolbar.setTitle(Shakespeare.TITLES[position]);
203             mDrawerLayout.closeDrawer(mDrawer);
204         }
205     }
206 }
207