116e8d4dd91083260223c007c797e46bc8f631055Chris Banes/* 216e8d4dd91083260223c007c797e46bc8f631055Chris Banes * Copyright (C) 2015 The Android Open Source Project 316e8d4dd91083260223c007c797e46bc8f631055Chris Banes * 416e8d4dd91083260223c007c797e46bc8f631055Chris Banes * Licensed under the Apache License, Version 2.0 (the "License"); 516e8d4dd91083260223c007c797e46bc8f631055Chris Banes * you may not use this file except in compliance with the License. 616e8d4dd91083260223c007c797e46bc8f631055Chris Banes * You may obtain a copy of the License at 716e8d4dd91083260223c007c797e46bc8f631055Chris Banes * 816e8d4dd91083260223c007c797e46bc8f631055Chris Banes * http://www.apache.org/licenses/LICENSE-2.0 916e8d4dd91083260223c007c797e46bc8f631055Chris Banes * 1016e8d4dd91083260223c007c797e46bc8f631055Chris Banes * Unless required by applicable law or agreed to in writing, software 1116e8d4dd91083260223c007c797e46bc8f631055Chris Banes * distributed under the License is distributed on an "AS IS" BASIS, 1216e8d4dd91083260223c007c797e46bc8f631055Chris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1316e8d4dd91083260223c007c797e46bc8f631055Chris Banes * See the License for the specific language governing permissions and 1416e8d4dd91083260223c007c797e46bc8f631055Chris Banes * limitations under the License. 1516e8d4dd91083260223c007c797e46bc8f631055Chris Banes */ 1616e8d4dd91083260223c007c797e46bc8f631055Chris Banes 1716e8d4dd91083260223c007c797e46bc8f631055Chris Banespackage android.support.v7.app; 1816e8d4dd91083260223c007c797e46bc8f631055Chris Banes 1916e8d4dd91083260223c007c797e46bc8f631055Chris Banesimport android.app.Dialog; 2016e8d4dd91083260223c007c797e46bc8f631055Chris Banesimport android.content.Context; 2116e8d4dd91083260223c007c797e46bc8f631055Chris Banesimport android.os.Bundle; 2216e8d4dd91083260223c007c797e46bc8f631055Chris Banesimport android.support.annotation.LayoutRes; 23547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banesimport android.support.annotation.Nullable; 2416e8d4dd91083260223c007c797e46bc8f631055Chris Banesimport android.support.v7.appcompat.R; 2516e8d4dd91083260223c007c797e46bc8f631055Chris Banesimport android.support.v7.view.ActionMode; 2616e8d4dd91083260223c007c797e46bc8f631055Chris Banesimport android.util.TypedValue; 2716e8d4dd91083260223c007c797e46bc8f631055Chris Banesimport android.view.View; 2816e8d4dd91083260223c007c797e46bc8f631055Chris Banesimport android.view.ViewGroup; 2916e8d4dd91083260223c007c797e46bc8f631055Chris Banes 3016e8d4dd91083260223c007c797e46bc8f631055Chris Banes/** 3116e8d4dd91083260223c007c797e46bc8f631055Chris Banes * Base class for AppCompat themed {@link android.app.Dialog}s. 3216e8d4dd91083260223c007c797e46bc8f631055Chris Banes */ 3316e8d4dd91083260223c007c797e46bc8f631055Chris Banespublic class AppCompatDialog extends Dialog implements AppCompatCallback { 3416e8d4dd91083260223c007c797e46bc8f631055Chris Banes 3516e8d4dd91083260223c007c797e46bc8f631055Chris Banes private AppCompatDelegate mDelegate; 3616e8d4dd91083260223c007c797e46bc8f631055Chris Banes 3716e8d4dd91083260223c007c797e46bc8f631055Chris Banes public AppCompatDialog(Context context) { 3816e8d4dd91083260223c007c797e46bc8f631055Chris Banes this(context, 0); 3916e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 4016e8d4dd91083260223c007c797e46bc8f631055Chris Banes 4116e8d4dd91083260223c007c797e46bc8f631055Chris Banes public AppCompatDialog(Context context, int theme) { 4216e8d4dd91083260223c007c797e46bc8f631055Chris Banes super(context, getThemeResId(context, theme)); 4316e8d4dd91083260223c007c797e46bc8f631055Chris Banes 4416e8d4dd91083260223c007c797e46bc8f631055Chris Banes // This is a bit weird, but Dialog's are typically created and setup before being shown, 4516e8d4dd91083260223c007c797e46bc8f631055Chris Banes // which means that we can't rely on onCreate() being called before a content view is set. 4616e8d4dd91083260223c007c797e46bc8f631055Chris Banes // To workaround this, we call onCreate(null) in the ctor, and then again as usual in 4716e8d4dd91083260223c007c797e46bc8f631055Chris Banes // onCreate(). 4816e8d4dd91083260223c007c797e46bc8f631055Chris Banes getDelegate().onCreate(null); 4916e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 5016e8d4dd91083260223c007c797e46bc8f631055Chris Banes 5116e8d4dd91083260223c007c797e46bc8f631055Chris Banes protected AppCompatDialog(Context context, boolean cancelable, 5216e8d4dd91083260223c007c797e46bc8f631055Chris Banes OnCancelListener cancelListener) { 5316e8d4dd91083260223c007c797e46bc8f631055Chris Banes super(context, cancelable, cancelListener); 5416e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 5516e8d4dd91083260223c007c797e46bc8f631055Chris Banes 5616e8d4dd91083260223c007c797e46bc8f631055Chris Banes @Override 5716e8d4dd91083260223c007c797e46bc8f631055Chris Banes protected void onCreate(Bundle savedInstanceState) { 5816e8d4dd91083260223c007c797e46bc8f631055Chris Banes getDelegate().installViewFactory(); 5916e8d4dd91083260223c007c797e46bc8f631055Chris Banes super.onCreate(savedInstanceState); 6016e8d4dd91083260223c007c797e46bc8f631055Chris Banes getDelegate().onCreate(savedInstanceState); 6116e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 6216e8d4dd91083260223c007c797e46bc8f631055Chris Banes 6316e8d4dd91083260223c007c797e46bc8f631055Chris Banes /** 6416e8d4dd91083260223c007c797e46bc8f631055Chris Banes * Support library version of {@link android.app.Dialog#getActionBar}. 6516e8d4dd91083260223c007c797e46bc8f631055Chris Banes * 6616e8d4dd91083260223c007c797e46bc8f631055Chris Banes * <p>Retrieve a reference to this dialog's ActionBar. 6716e8d4dd91083260223c007c797e46bc8f631055Chris Banes * 6816e8d4dd91083260223c007c797e46bc8f631055Chris Banes * @return The Dialog's ActionBar, or null if it does not have one. 6916e8d4dd91083260223c007c797e46bc8f631055Chris Banes */ 7016e8d4dd91083260223c007c797e46bc8f631055Chris Banes public ActionBar getSupportActionBar() { 7116e8d4dd91083260223c007c797e46bc8f631055Chris Banes return getDelegate().getSupportActionBar(); 7216e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 7316e8d4dd91083260223c007c797e46bc8f631055Chris Banes 7416e8d4dd91083260223c007c797e46bc8f631055Chris Banes @Override 7516e8d4dd91083260223c007c797e46bc8f631055Chris Banes public void setContentView(@LayoutRes int layoutResID) { 7616e8d4dd91083260223c007c797e46bc8f631055Chris Banes getDelegate().setContentView(layoutResID); 7716e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 7816e8d4dd91083260223c007c797e46bc8f631055Chris Banes 7916e8d4dd91083260223c007c797e46bc8f631055Chris Banes @Override 8016e8d4dd91083260223c007c797e46bc8f631055Chris Banes public void setContentView(View view) { 8116e8d4dd91083260223c007c797e46bc8f631055Chris Banes getDelegate().setContentView(view); 8216e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 8316e8d4dd91083260223c007c797e46bc8f631055Chris Banes 8416e8d4dd91083260223c007c797e46bc8f631055Chris Banes @Override 8516e8d4dd91083260223c007c797e46bc8f631055Chris Banes public void setContentView(View view, ViewGroup.LayoutParams params) { 8616e8d4dd91083260223c007c797e46bc8f631055Chris Banes getDelegate().setContentView(view, params); 8716e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 8816e8d4dd91083260223c007c797e46bc8f631055Chris Banes 8916e8d4dd91083260223c007c797e46bc8f631055Chris Banes @Override 9016e8d4dd91083260223c007c797e46bc8f631055Chris Banes public void setTitle(CharSequence title) { 9116e8d4dd91083260223c007c797e46bc8f631055Chris Banes super.setTitle(title); 9216e8d4dd91083260223c007c797e46bc8f631055Chris Banes getDelegate().setTitle(title); 9316e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 9416e8d4dd91083260223c007c797e46bc8f631055Chris Banes 9516e8d4dd91083260223c007c797e46bc8f631055Chris Banes @Override 9616e8d4dd91083260223c007c797e46bc8f631055Chris Banes public void setTitle(int titleId) { 9716e8d4dd91083260223c007c797e46bc8f631055Chris Banes super.setTitle(titleId); 9816e8d4dd91083260223c007c797e46bc8f631055Chris Banes getDelegate().setTitle(getContext().getString(titleId)); 9916e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 10016e8d4dd91083260223c007c797e46bc8f631055Chris Banes 10116e8d4dd91083260223c007c797e46bc8f631055Chris Banes @Override 10216e8d4dd91083260223c007c797e46bc8f631055Chris Banes public void addContentView(View view, ViewGroup.LayoutParams params) { 10316e8d4dd91083260223c007c797e46bc8f631055Chris Banes getDelegate().addContentView(view, params); 10416e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 10516e8d4dd91083260223c007c797e46bc8f631055Chris Banes 10616e8d4dd91083260223c007c797e46bc8f631055Chris Banes @Override 10716e8d4dd91083260223c007c797e46bc8f631055Chris Banes protected void onStop() { 10816e8d4dd91083260223c007c797e46bc8f631055Chris Banes super.onStop(); 10916e8d4dd91083260223c007c797e46bc8f631055Chris Banes getDelegate().onStop(); 11016e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 11116e8d4dd91083260223c007c797e46bc8f631055Chris Banes 11216e8d4dd91083260223c007c797e46bc8f631055Chris Banes /** 11316e8d4dd91083260223c007c797e46bc8f631055Chris Banes * Enable extended support library window features. 11416e8d4dd91083260223c007c797e46bc8f631055Chris Banes * <p> 11516e8d4dd91083260223c007c797e46bc8f631055Chris Banes * This is a convenience for calling 11616e8d4dd91083260223c007c797e46bc8f631055Chris Banes * {@link android.view.Window#requestFeature getWindow().requestFeature()}. 11716e8d4dd91083260223c007c797e46bc8f631055Chris Banes * </p> 11816e8d4dd91083260223c007c797e46bc8f631055Chris Banes * 11916e8d4dd91083260223c007c797e46bc8f631055Chris Banes * @param featureId The desired feature as defined in {@link android.view.Window} or 12016e8d4dd91083260223c007c797e46bc8f631055Chris Banes * {@link android.support.v4.view.WindowCompat}. 12116e8d4dd91083260223c007c797e46bc8f631055Chris Banes * @return Returns true if the requested feature is supported and now enabled. 12216e8d4dd91083260223c007c797e46bc8f631055Chris Banes * 12316e8d4dd91083260223c007c797e46bc8f631055Chris Banes * @see android.app.Dialog#requestWindowFeature 12416e8d4dd91083260223c007c797e46bc8f631055Chris Banes * @see android.view.Window#requestFeature 12516e8d4dd91083260223c007c797e46bc8f631055Chris Banes */ 12616e8d4dd91083260223c007c797e46bc8f631055Chris Banes public boolean supportRequestWindowFeature(int featureId) { 12716e8d4dd91083260223c007c797e46bc8f631055Chris Banes return getDelegate().requestWindowFeature(featureId); 12816e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 12916e8d4dd91083260223c007c797e46bc8f631055Chris Banes 13016e8d4dd91083260223c007c797e46bc8f631055Chris Banes /** 13116e8d4dd91083260223c007c797e46bc8f631055Chris Banes * @hide 13216e8d4dd91083260223c007c797e46bc8f631055Chris Banes */ 13316e8d4dd91083260223c007c797e46bc8f631055Chris Banes public void invalidateOptionsMenu() { 13416e8d4dd91083260223c007c797e46bc8f631055Chris Banes getDelegate().invalidateOptionsMenu(); 13516e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 13616e8d4dd91083260223c007c797e46bc8f631055Chris Banes 13716e8d4dd91083260223c007c797e46bc8f631055Chris Banes /** 13816e8d4dd91083260223c007c797e46bc8f631055Chris Banes * @return The {@link AppCompatDelegate} being used by this Dialog. 13916e8d4dd91083260223c007c797e46bc8f631055Chris Banes */ 14016e8d4dd91083260223c007c797e46bc8f631055Chris Banes public AppCompatDelegate getDelegate() { 14116e8d4dd91083260223c007c797e46bc8f631055Chris Banes if (mDelegate == null) { 14216e8d4dd91083260223c007c797e46bc8f631055Chris Banes mDelegate = AppCompatDelegate.create(this, this); 14316e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 14416e8d4dd91083260223c007c797e46bc8f631055Chris Banes return mDelegate; 14516e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 14616e8d4dd91083260223c007c797e46bc8f631055Chris Banes 14716e8d4dd91083260223c007c797e46bc8f631055Chris Banes private static int getThemeResId(Context context, int themeId) { 14816e8d4dd91083260223c007c797e46bc8f631055Chris Banes if (themeId == 0) { 14916e8d4dd91083260223c007c797e46bc8f631055Chris Banes // If the provided theme is 0, then retrieve the dialogTheme from our theme 15016e8d4dd91083260223c007c797e46bc8f631055Chris Banes TypedValue outValue = new TypedValue(); 15116e8d4dd91083260223c007c797e46bc8f631055Chris Banes context.getTheme().resolveAttribute(R.attr.dialogTheme, outValue, true); 15216e8d4dd91083260223c007c797e46bc8f631055Chris Banes themeId = outValue.resourceId; 15316e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 15416e8d4dd91083260223c007c797e46bc8f631055Chris Banes return themeId; 15516e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 15616e8d4dd91083260223c007c797e46bc8f631055Chris Banes 15716e8d4dd91083260223c007c797e46bc8f631055Chris Banes @Override 15816e8d4dd91083260223c007c797e46bc8f631055Chris Banes public void onSupportActionModeStarted(ActionMode mode) { 15916e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 16016e8d4dd91083260223c007c797e46bc8f631055Chris Banes 16116e8d4dd91083260223c007c797e46bc8f631055Chris Banes @Override 16216e8d4dd91083260223c007c797e46bc8f631055Chris Banes public void onSupportActionModeFinished(ActionMode mode) { 16316e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 164547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes 165547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes @Nullable 166547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes @Override 167547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes public ActionMode onWindowStartingSupportActionMode(ActionMode.Callback callback) { 168547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes return null; 169547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes } 17016e8d4dd91083260223c007c797e46bc8f631055Chris Banes} 171