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