SlidingPaneLayoutActivity.java revision 63a2530d57dfe7a90de8b3ef70088e23773428fb
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 18package com.example.android.supportv4.widget; 19 20import android.app.ActionBar; 21import android.app.Activity; 22import android.os.Build; 23import android.os.Bundle; 24import android.support.v4.widget.SlidingPaneLayout; 25import android.view.MenuItem; 26import android.view.View; 27import android.view.ViewTreeObserver; 28import android.widget.AdapterView; 29import android.widget.ArrayAdapter; 30import android.widget.ListView; 31import android.widget.TextView; 32 33import com.example.android.supportv4.R; 34import com.example.android.supportv4.Shakespeare; 35 36/** 37 * This example illustrates a common usage of SlidingPaneLayout in the Android support library. 38 * 39 * <p>A SlidingPaneLayout should be positioned at the top of your view hierarchy, placing it 40 * below the action bar but above your content views. It is ideal as a two-pane layout 41 * for larger screens, used in place of a horizontal LinearLayout.</p> 42 * 43 * <p>What separates SlidingPaneLayout from LinearLayout in this usage is that SlidingPaneLayout 44 * allows these wide, two-pane layouts to overlap when horizontal space is at a premium. The user 45 * can then access both panes by physically sliding the content pane into view or out of the way 46 * or implicitly by moving focus between the two panes. This can greatly simplify development 47 * of Android apps that support multiple form factors and screen sizes.</p> 48 * 49 * <p>When it comes to your navigation hierarchy, the left pane of a SlidingPaneLayout is always 50 * considered to be one level up from the right content pane. As such, your Action Bar's 51 * Up navigation should be enabled if the right pane is obscuring the left pane, and invoking it 52 * should open the panes, revealing the left pane for normal interaction. From this open state 53 * where the left pane is in primary focus, the Action Bar's Up affordance should act as if 54 * both panes were fully visible in the activity window and navigate to the activity one level up 55 * in the app's logical hierarchy. If the activity is the root of the application's task, the up 56 * affordance should be disabled when the sliding pane is open and showing the left pane. 57 * This code example illustrates this root activity case.</p> 58 * 59 * <p>Note that SlidingPaneLayout differs in usage from DrawerLayout. While DrawerLayout offers 60 * sliding utility drawers for extended navigation options and actions, the panes of a 61 * SlidingPaneLayout are firmly part of the content itself. If it would not make sense for 62 * both panes to be visible all the time on a sufficiently wide screen, DrawerLayout and its 63 * associated patterns are likely to be a better choice for your usage.</p> 64 */ 65public class SlidingPaneLayoutActivity extends Activity { 66 private SlidingPaneLayout mSlidingLayout; 67 private ListView mList; 68 private TextView mContent; 69 70 private ActionBarHelper mActionBar; 71 72 @Override 73 protected void onCreate(Bundle savedInstanceState) { 74 super.onCreate(savedInstanceState); 75 76 setContentView(R.layout.sliding_pane_layout); 77 78 mSlidingLayout = (SlidingPaneLayout) findViewById(R.id.sliding_pane_layout); 79 mList = (ListView) findViewById(R.id.left_pane); 80 mContent = (TextView) findViewById(R.id.content_text); 81 82 mSlidingLayout.setPanelSlideListener(new SliderListener()); 83 mSlidingLayout.openPane(); 84 85 mList.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, 86 Shakespeare.TITLES)); 87 mList.setOnItemClickListener(new ListItemClickListener()); 88 89 mActionBar = createActionBarHelper(); 90 mActionBar.init(); 91 92 mSlidingLayout.getViewTreeObserver().addOnGlobalLayoutListener(new FirstLayoutListener()); 93 } 94 95 @Override 96 public boolean onOptionsItemSelected(MenuItem item) { 97 /* 98 * The action bar up action should open the slider if it is currently closed, 99 * as the left pane contains content one level up in the navigation hierarchy. 100 */ 101 if (item.getItemId() == android.R.id.home && !mSlidingLayout.isOpen()) { 102 mSlidingLayout.openPane(); 103 return true; 104 } 105 return super.onOptionsItemSelected(item); 106 } 107 108 /** 109 * This list item click listener implements very simple view switching by changing 110 * the primary content text. The slider is closed when a selection is made to fully 111 * reveal the content. 112 */ 113 private class ListItemClickListener implements ListView.OnItemClickListener { 114 @Override 115 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 116 mContent.setText(Shakespeare.DIALOGUE[position]); 117 mActionBar.setTitle(Shakespeare.TITLES[position]); 118 mSlidingLayout.closePane(); 119 } 120 } 121 122 /** 123 * This panel slide listener updates the action bar accordingly for each panel state. 124 */ 125 private class SliderListener extends SlidingPaneLayout.SimplePanelSlideListener { 126 @Override 127 public void onPanelOpened(View panel) { 128 mActionBar.onPanelOpened(); 129 } 130 131 @Override 132 public void onPanelClosed(View panel) { 133 mActionBar.onPanelClosed(); 134 } 135 } 136 137 /** 138 * This global layout listener is used to fire an event after first layout occurs 139 * and then it is removed. This gives us a chance to configure parts of the UI 140 * that adapt based on available space after they have had the opportunity to measure 141 * and layout. 142 */ 143 private class FirstLayoutListener implements ViewTreeObserver.OnGlobalLayoutListener { 144 @Override 145 public void onGlobalLayout() { 146 mActionBar.onFirstLayout(); 147 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { 148 mSlidingLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this); 149 } else { 150 //noinspection deprecation 151 mSlidingLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this); 152 } 153 } 154 } 155 156 /** 157 * Create a compatible helper that will manipulate the action bar if available. 158 */ 159 private ActionBarHelper createActionBarHelper() { 160 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 161 return new ActionBarHelperICS(); 162 } else { 163 return new ActionBarHelper(); 164 } 165 } 166 167 /** 168 * Stub action bar helper; this does nothing. 169 */ 170 private class ActionBarHelper { 171 public void init() {} 172 public void onPanelClosed() {} 173 public void onPanelOpened() {} 174 public void onFirstLayout() {} 175 public void setTitle(CharSequence title) {} 176 } 177 178 /** 179 * Action bar helper for use on ICS and newer devices. 180 */ 181 private class ActionBarHelperICS extends ActionBarHelper { 182 private final ActionBar mActionBar; 183 private CharSequence mDrawerTitle; 184 private CharSequence mTitle; 185 186 ActionBarHelperICS() { 187 mActionBar = getActionBar(); 188 } 189 190 @Override 191 public void init() { 192 mActionBar.setDisplayHomeAsUpEnabled(true); 193 mActionBar.setHomeButtonEnabled(true); 194 mTitle = mDrawerTitle = getTitle(); 195 } 196 197 @Override 198 public void onPanelClosed() { 199 super.onPanelClosed(); 200 mActionBar.setDisplayHomeAsUpEnabled(true); 201 mActionBar.setHomeButtonEnabled(true); 202 mActionBar.setTitle(mTitle); 203 } 204 205 @Override 206 public void onPanelOpened() { 207 super.onPanelOpened(); 208 mActionBar.setHomeButtonEnabled(false); 209 mActionBar.setDisplayHomeAsUpEnabled(false); 210 mActionBar.setTitle(mDrawerTitle); 211 } 212 213 @Override 214 public void onFirstLayout() { 215 if (mSlidingLayout.isSlideable() && !mSlidingLayout.isOpen()) { 216 onPanelClosed(); 217 } else { 218 onPanelOpened(); 219 } 220 } 221 222 @Override 223 public void setTitle(CharSequence title) { 224 mTitle = title; 225 } 226 } 227 228} 229