AppCompatDelegate.java revision f5829201b976fc650789accc22f325a2541ed478
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 >= 23) { 93 return new AppCompatDelegateImplV23(context, window, callback); 94 } else if (sdk >= 14) { 95 return new AppCompatDelegateImplV14(context, window, callback); 96 } else if (sdk >= 11) { 97 return new AppCompatDelegateImplV11(context, window, callback); 98 } else { 99 return new AppCompatDelegateImplV7(context, window, callback); 100 } 101 } 102 103 /** 104 * Private constructor 105 */ 106 AppCompatDelegate() {} 107 108 /** 109 * Support library version of {@link Activity#getActionBar}. 110 * 111 * @return AppCompat's action bar, or null if it does not have one. 112 */ 113 public abstract ActionBar getSupportActionBar(); 114 115 /** 116 * Set a {@link Toolbar} to act as the {@link ActionBar} for this delegate. 117 * 118 * <p>When set to a non-null value the {@link #getSupportActionBar()} ()} method will return 119 * an {@link ActionBar} object that can be used to control the given toolbar as if it were 120 * a traditional window decor action bar. The toolbar's menu will be populated with the 121 * Activity's options menu and the navigation button will be wired through the standard 122 * {@link android.R.id#home home} menu select action.</p> 123 * 124 * <p>In order to use a Toolbar within the Activity's window content the application 125 * must not request the window feature 126 * {@link android.view.Window#FEATURE_ACTION_BAR FEATURE_ACTION_BAR}.</p> 127 * 128 * @param toolbar Toolbar to set as the Activity's action bar 129 */ 130 public abstract void setSupportActionBar(Toolbar toolbar); 131 132 /** 133 * Return the value of this call from your {@link Activity#getMenuInflater()} 134 */ 135 public abstract MenuInflater getMenuInflater(); 136 137 /** 138 * Should be called from {@link Activity#onCreate Activity.onCreate()} 139 */ 140 public abstract void onCreate(Bundle savedInstanceState); 141 142 /** 143 * Should be called from {@link Activity#onPostCreate(android.os.Bundle)} 144 */ 145 public abstract void onPostCreate(Bundle savedInstanceState); 146 147 /** 148 * Should be called from 149 * {@link Activity#onConfigurationChanged} 150 */ 151 public abstract void onConfigurationChanged(Configuration newConfig); 152 153 /** 154 * Should be called from {@link Activity#onStop Activity.onStop()} 155 */ 156 public abstract void onStop(); 157 158 /** 159 * Should be called from {@link Activity#onPostResume()} 160 */ 161 public abstract void onPostResume(); 162 163 /** 164 * Should be called instead of {@link Activity#setContentView(android.view.View)}} 165 */ 166 public abstract void setContentView(View v); 167 168 /** 169 * Should be called instead of {@link Activity#setContentView(int)}} 170 */ 171 public abstract void setContentView(int resId); 172 173 /** 174 * Should be called instead of 175 * {@link Activity#setContentView(android.view.View, android.view.ViewGroup.LayoutParams)}} 176 */ 177 public abstract void setContentView(View v, ViewGroup.LayoutParams lp); 178 179 /** 180 * Should be called instead of 181 * {@link Activity#addContentView(android.view.View, android.view.ViewGroup.LayoutParams)}} 182 */ 183 public abstract void addContentView(View v, ViewGroup.LayoutParams lp); 184 185 /** 186 * Should be called from {@link Activity#onTitleChanged(CharSequence, int)}} 187 */ 188 public abstract void setTitle(CharSequence title); 189 190 /** 191 * Should be called from {@link Activity#invalidateOptionsMenu()}} or 192 * {@link FragmentActivity#supportInvalidateOptionsMenu()}. 193 */ 194 public abstract void invalidateOptionsMenu(); 195 196 /** 197 * Should be called from {@link Activity#onDestroy()} 198 */ 199 public abstract void onDestroy(); 200 201 /** 202 * Returns an {@link ActionBarDrawerToggle.Delegate} which can be returned from your Activity 203 * if it implements {@link ActionBarDrawerToggle.DelegateProvider}. 204 */ 205 public abstract ActionBarDrawerToggle.Delegate getDrawerToggleDelegate(); 206 207 /** 208 * Enable extended window features. This should be called instead of 209 * {@link android.app.Activity#requestWindowFeature(int)} or 210 * {@link android.view.Window#requestFeature getWindow().requestFeature()}. 211 * 212 * @param featureId The desired feature as defined in {@link android.view.Window}. 213 * @return Returns true if the requested feature is supported and now 214 * enabled. 215 */ 216 public abstract boolean requestWindowFeature(int featureId); 217 218 /** 219 * Start an action mode. 220 * 221 * @param callback Callback that will manage lifecycle events for this context mode 222 * @return The ContextMode that was started, or null if it was canceled 223 */ 224 public abstract ActionMode startSupportActionMode(ActionMode.Callback callback); 225 226 /** 227 * Installs AppCompat's {@link android.view.LayoutInflater} Factory so that it can replace 228 * the framework widgets with compatible tinted versions. This should be called before 229 * {@code super.onCreate()} as so: 230 * <pre class="prettyprint"> 231 * protected void onCreate(Bundle savedInstanceState) { 232 * getDelegate().installViewFactory(); 233 * super.onCreate(savedInstanceState); 234 * getDelegate().onCreate(savedInstanceState); 235 * 236 * // ... 237 * } 238 * </pre> 239 * If you are using your own {@link android.view.LayoutInflater.Factory Factory} or 240 * {@link android.view.LayoutInflater.Factory2 Factory2} then you can omit this call, and instead call 241 * {@link #createView(android.view.View, String, android.content.Context, android.util.AttributeSet)} 242 * from your factory to return any compatible widgets. 243 */ 244 public abstract void installViewFactory(); 245 246 /** 247 * This should be called from a 248 * {@link android.support.v4.view.LayoutInflaterFactory LayoutInflaterFactory} in order 249 * to return tint-aware widgets. 250 * <p> 251 * This is only needed if you are using your own 252 * {@link android.view.LayoutInflater LayoutInflater} factory, and have therefore not 253 * installed the default factory via {@link #installViewFactory()}. 254 */ 255 public abstract View createView(View parent, String name, @NonNull Context context, 256 @NonNull AttributeSet attrs); 257 258 /** 259 * Whether AppCompat handles any native action modes itself. 260 * <p>This methods only takes effect on 261 * {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH} and above. 262 * 263 * @param enabled whether AppCompat should handle native action modes. 264 */ 265 public abstract void setHandleNativeActionModesEnabled(boolean enabled); 266 267 /** 268 * Returns whether AppCompat handles any native action modes itself. 269 * 270 * @return true if AppCompat should handle native action modes. 271 */ 272 public abstract boolean isHandleNativeActionModesEnabled(); 273 274} 275