AppCompatDelegate.java revision 547a80d347e0dc9751bbe3cf91f947477145bdba
1/* 2 * Copyright (C) 2014 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 17package android.support.v7.app; 18 19import android.app.Activity; 20import android.app.Dialog; 21import android.content.Context; 22import android.content.res.Configuration; 23import android.os.Build; 24import android.os.Bundle; 25import android.support.annotation.NonNull; 26import android.support.v4.app.FragmentActivity; 27import android.support.v7.view.ActionMode; 28import android.support.v7.widget.Toolbar; 29import android.util.AttributeSet; 30import android.view.MenuInflater; 31import android.view.View; 32import android.view.ViewGroup; 33import android.view.Window; 34 35/** 36 * This class represents a delegate which you can use to extend AppCompat's support to any 37 * {@link android.app.Activity}. 38 * <p> 39 * When using an {@link AppCompatDelegate}, you should any methods exposed in it rather than the 40 * {@link android.app.Activity} method of the same name. This applies to: 41 * <ul> 42 * <li>{@link #addContentView(android.view.View, android.view.ViewGroup.LayoutParams)}</li> 43 * <li>{@link #setContentView(int)}</li> 44 * <li>{@link #setContentView(android.view.View)}</li> 45 * <li>{@link #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)}</li> 46 * <li>{@link #requestWindowFeature(int)}</li> 47 * <li>{@link #invalidateOptionsMenu()}</li> 48 * <li>{@link #startSupportActionMode(android.support.v7.view.ActionMode.Callback)}</li> 49 * <li>{@link #setSupportActionBar(android.support.v7.widget.Toolbar)}</li> 50 * <li>{@link #getSupportActionBar()}</li> 51 * <li>{@link #getMenuInflater()}</li> 52 * </ul> 53 * There also some Activity lifecycle methods which should be proxied to the delegate: 54 * <ul> 55 * <li>{@link #onCreate(android.os.Bundle)}</li> 56 * <li>{@link #onPostCreate(android.os.Bundle)}</li> 57 * <li>{@link #onConfigurationChanged(android.content.res.Configuration)}</li> 58 * <li>{@link #setTitle(CharSequence)}</li> 59 * <li>{@link #onStop()}</li> 60 * <li>{@link #onDestroy()}</li> 61 * </ul> 62 * <p> 63 * An {@link Activity} can only be linked with one {@link AppCompatDelegate} instance, 64 * so the instance returned from {@link #create(Activity, AppCompatCallback)} should be kept 65 * until the Activity is destroyed. 66 */ 67public abstract class AppCompatDelegate { 68 69 static final String TAG = "AppCompatDelegate"; 70 71 /** 72 * Create a {@link android.support.v7.app.AppCompatDelegate} to use with {@code activity}. 73 * 74 * @param callback An optional callback for AppCompat specific events 75 */ 76 public static AppCompatDelegate create(Activity activity, AppCompatCallback callback) { 77 return create(activity, activity.getWindow(), callback); 78 } 79 80 /** 81 * Create a {@link android.support.v7.app.AppCompatDelegate} to use with {@code dialog}. 82 * 83 * @param callback An optional callback for AppCompat specific events 84 */ 85 public static AppCompatDelegate create(Dialog dialog, AppCompatCallback callback) { 86 return create(dialog.getContext(), dialog.getWindow(), callback); 87 } 88 89 private static AppCompatDelegate create(Context context, Window window, 90 AppCompatCallback callback) { 91 final int sdk = Build.VERSION.SDK_INT; 92 if (sdk >= 14) { 93 return new AppCompatDelegateImplV14(context, window, callback); 94 } else if (sdk >= 11) { 95 return new AppCompatDelegateImplV11(context, window, callback); 96 } else { 97 return new AppCompatDelegateImplV7(context, window, callback); 98 } 99 } 100 101 /** 102 * Private constructor 103 */ 104 AppCompatDelegate() {} 105 106 /** 107 * Support library version of {@link Activity#getActionBar}. 108 * 109 * @return AppCompat's action bar, or null if it does not have one. 110 */ 111 public abstract ActionBar getSupportActionBar(); 112 113 /** 114 * Set a {@link Toolbar} to act as the {@link ActionBar} for this delegate. 115 * 116 * <p>When set to a non-null value the {@link #getSupportActionBar()} ()} method will return 117 * an {@link ActionBar} object that can be used to control the given toolbar as if it were 118 * a traditional window decor action bar. The toolbar's menu will be populated with the 119 * Activity's options menu and the navigation button will be wired through the standard 120 * {@link android.R.id#home home} menu select action.</p> 121 * 122 * <p>In order to use a Toolbar within the Activity's window content the application 123 * must not request the window feature 124 * {@link android.view.Window#FEATURE_ACTION_BAR FEATURE_ACTION_BAR}.</p> 125 * 126 * @param toolbar Toolbar to set as the Activity's action bar 127 */ 128 public abstract void setSupportActionBar(Toolbar toolbar); 129 130 /** 131 * Return the value of this call from your {@link Activity#getMenuInflater()} 132 */ 133 public abstract MenuInflater getMenuInflater(); 134 135 /** 136 * Should be called from {@link Activity#onCreate Activity.onCreate()} 137 */ 138 public abstract void onCreate(Bundle savedInstanceState); 139 140 /** 141 * Should be called from {@link Activity#onPostCreate(android.os.Bundle)} 142 */ 143 public abstract void onPostCreate(Bundle savedInstanceState); 144 145 /** 146 * Should be called from 147 * {@link Activity#onConfigurationChanged} 148 */ 149 public abstract void onConfigurationChanged(Configuration newConfig); 150 151 /** 152 * Should be called from {@link Activity#onStop Activity.onStop()} 153 */ 154 public abstract void onStop(); 155 156 /** 157 * Should be called from {@link Activity#onPostResume()} 158 */ 159 public abstract void onPostResume(); 160 161 /** 162 * Should be called instead of {@link Activity#setContentView(android.view.View)}} 163 */ 164 public abstract void setContentView(View v); 165 166 /** 167 * Should be called instead of {@link Activity#setContentView(int)}} 168 */ 169 public abstract void setContentView(int resId); 170 171 /** 172 * Should be called instead of 173 * {@link Activity#setContentView(android.view.View, android.view.ViewGroup.LayoutParams)}} 174 */ 175 public abstract void setContentView(View v, ViewGroup.LayoutParams lp); 176 177 /** 178 * Should be called instead of 179 * {@link Activity#addContentView(android.view.View, android.view.ViewGroup.LayoutParams)}} 180 */ 181 public abstract void addContentView(View v, ViewGroup.LayoutParams lp); 182 183 /** 184 * Should be called from {@link Activity#onTitleChanged(CharSequence, int)}} 185 */ 186 public abstract void setTitle(CharSequence title); 187 188 /** 189 * Should be called from {@link Activity#invalidateOptionsMenu()}} or 190 * {@link FragmentActivity#supportInvalidateOptionsMenu()}. 191 */ 192 public abstract void invalidateOptionsMenu(); 193 194 /** 195 * Should be called from {@link Activity#onDestroy()} 196 */ 197 public abstract void onDestroy(); 198 199 /** 200 * Returns an {@link ActionBarDrawerToggle.Delegate} which can be returned from your Activity 201 * if it implements {@link ActionBarDrawerToggle.DelegateProvider}. 202 */ 203 public abstract ActionBarDrawerToggle.Delegate getDrawerToggleDelegate(); 204 205 /** 206 * Enable extended window features. This should be called instead of 207 * {@link android.app.Activity#requestWindowFeature(int)} or 208 * {@link android.view.Window#requestFeature getWindow().requestFeature()}. 209 * 210 * @param featureId The desired feature as defined in {@link android.view.Window}. 211 * @return Returns true if the requested feature is supported and now 212 * enabled. 213 */ 214 public abstract boolean requestWindowFeature(int featureId); 215 216 /** 217 * Start an action mode. 218 * 219 * @param callback Callback that will manage lifecycle events for this context mode 220 * @return The ContextMode that was started, or null if it was canceled 221 */ 222 public abstract ActionMode startSupportActionMode(ActionMode.Callback callback); 223 224 /** 225 * Installs AppCompat's {@link android.view.LayoutInflater} Factory so that it can replace 226 * the framework widgets with compatible tinted versions. This should be called before 227 * {@code super.onCreate()} as so: 228 * <pre class="prettyprint"> 229 * protected void onCreate(Bundle savedInstanceState) { 230 * getDelegate().installViewFactory(); 231 * super.onCreate(savedInstanceState); 232 * getDelegate().onCreate(savedInstanceState); 233 * 234 * // ... 235 * } 236 * </pre> 237 * If you are using your own {@link android.view.LayoutInflater.Factory Factory} or 238 * {@link android.view.LayoutInflater.Factory2 Factory2} then you can omit this call, and instead call 239 * {@link #createView(android.view.View, String, android.content.Context, android.util.AttributeSet)} 240 * from your factory to return any compatible widgets. 241 */ 242 public abstract void installViewFactory(); 243 244 /** 245 * This should be called from a 246 * {@link android.support.v4.view.LayoutInflaterFactory LayoutInflaterFactory} in order 247 * to return tint-aware widgets. 248 * <p> 249 * This is only needed if you are using your own 250 * {@link android.view.LayoutInflater LayoutInflater} factory, and have therefore not 251 * installed the default factory via {@link #installViewFactory()}. 252 */ 253 public abstract View createView(View parent, String name, @NonNull Context context, 254 @NonNull AttributeSet attrs); 255 256 /** 257 * Whether AppCompat handles any native action modes itself. 258 * <p>This methods only takes effect on 259 * {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH} and above. 260 * 261 * @param enabled whether AppCompat should handle native action modes. 262 */ 263 public abstract void setHandleNativeActionModesEnabled(boolean enabled); 264 265 /** 266 * Returns whether AppCompat handles any native action modes itself. 267 * 268 * @return true if AppCompat should handle native action modes. 269 */ 270 public abstract boolean isHandleNativeActionModesEnabled(); 271 272} 273