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 static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
20 
21 import android.app.Dialog;
22 import android.content.Context;
23 import android.os.Bundle;
24 import android.util.TypedValue;
25 import android.view.View;
26 import android.view.ViewGroup;
27 
28 import androidx.annotation.IdRes;
29 import androidx.annotation.LayoutRes;
30 import androidx.annotation.Nullable;
31 import androidx.annotation.RestrictTo;
32 import androidx.appcompat.R;
33 import androidx.appcompat.view.ActionMode;
34 
35 /**
36  * Base class for AppCompat themed {@link android.app.Dialog}s.
37  */
38 public class AppCompatDialog extends Dialog implements AppCompatCallback {
39 
40     private AppCompatDelegate mDelegate;
41 
AppCompatDialog(Context context)42     public AppCompatDialog(Context context) {
43         this(context, 0);
44     }
45 
AppCompatDialog(Context context, int theme)46     public AppCompatDialog(Context context, int theme) {
47         super(context, getThemeResId(context, theme));
48 
49         // This is a bit weird, but Dialog's are typically created and setup before being shown,
50         // which means that we can't rely on onCreate() being called before a content view is set.
51         // To workaround this, we call onCreate(null) in the ctor, and then again as usual in
52         // onCreate().
53         getDelegate().onCreate(null);
54 
55         // Apply AppCompat's DayNight resources if needed
56         getDelegate().applyDayNight();
57     }
58 
AppCompatDialog(Context context, boolean cancelable, OnCancelListener cancelListener)59     protected AppCompatDialog(Context context, boolean cancelable,
60             OnCancelListener cancelListener) {
61         super(context, cancelable, cancelListener);
62     }
63 
64     @Override
onCreate(Bundle savedInstanceState)65     protected void onCreate(Bundle savedInstanceState) {
66         getDelegate().installViewFactory();
67         super.onCreate(savedInstanceState);
68         getDelegate().onCreate(savedInstanceState);
69     }
70 
71     /**
72      * Support library version of {@link android.app.Dialog#getActionBar}.
73      *
74      * <p>Retrieve a reference to this dialog's ActionBar.
75      *
76      * @return The Dialog's ActionBar, or null if it does not have one.
77      */
getSupportActionBar()78     public ActionBar getSupportActionBar() {
79         return getDelegate().getSupportActionBar();
80     }
81 
82     @Override
setContentView(@ayoutRes int layoutResID)83     public void setContentView(@LayoutRes int layoutResID) {
84         getDelegate().setContentView(layoutResID);
85     }
86 
87     @Override
setContentView(View view)88     public void setContentView(View view) {
89         getDelegate().setContentView(view);
90     }
91 
92     @Override
setContentView(View view, ViewGroup.LayoutParams params)93     public void setContentView(View view, ViewGroup.LayoutParams params) {
94         getDelegate().setContentView(view, params);
95     }
96 
97     @SuppressWarnings("TypeParameterUnusedInFormals")
98     @Nullable
99     @Override
findViewById(@dRes int id)100     public <T extends View> T findViewById(@IdRes int id) {
101         return getDelegate().findViewById(id);
102     }
103 
104     @Override
setTitle(CharSequence title)105     public void setTitle(CharSequence title) {
106         super.setTitle(title);
107         getDelegate().setTitle(title);
108     }
109 
110     @Override
setTitle(int titleId)111     public void setTitle(int titleId) {
112         super.setTitle(titleId);
113         getDelegate().setTitle(getContext().getString(titleId));
114     }
115 
116     @Override
addContentView(View view, ViewGroup.LayoutParams params)117     public void addContentView(View view, ViewGroup.LayoutParams params) {
118         getDelegate().addContentView(view, params);
119     }
120 
121     @Override
onStop()122     protected void onStop() {
123         super.onStop();
124         getDelegate().onStop();
125     }
126 
127     /**
128      * Enable extended support library window features.
129      * <p>
130      * This is a convenience for calling
131      * {@link android.view.Window#requestFeature getWindow().requestFeature()}.
132      * </p>
133      *
134      * @param featureId The desired feature as defined in {@link android.view.Window} or
135      *                  {@link androidx.core.view.WindowCompat}.
136      * @return Returns true if the requested feature is supported and now enabled.
137      *
138      * @see android.app.Dialog#requestWindowFeature
139      * @see android.view.Window#requestFeature
140      */
supportRequestWindowFeature(int featureId)141     public boolean supportRequestWindowFeature(int featureId) {
142         return getDelegate().requestWindowFeature(featureId);
143     }
144 
145     /**
146      * @hide
147      */
148     @Override
149     @RestrictTo(LIBRARY_GROUP)
invalidateOptionsMenu()150     public void invalidateOptionsMenu() {
151         getDelegate().invalidateOptionsMenu();
152     }
153 
154     /**
155      * @return The {@link AppCompatDelegate} being used by this Dialog.
156      */
getDelegate()157     public AppCompatDelegate getDelegate() {
158         if (mDelegate == null) {
159             mDelegate = AppCompatDelegate.create(this, this);
160         }
161         return mDelegate;
162     }
163 
getThemeResId(Context context, int themeId)164     private static int getThemeResId(Context context, int themeId) {
165         if (themeId == 0) {
166             // If the provided theme is 0, then retrieve the dialogTheme from our theme
167             TypedValue outValue = new TypedValue();
168             context.getTheme().resolveAttribute(R.attr.dialogTheme, outValue, true);
169             themeId = outValue.resourceId;
170         }
171         return themeId;
172     }
173 
174     @Override
onSupportActionModeStarted(ActionMode mode)175     public void onSupportActionModeStarted(ActionMode mode) {
176     }
177 
178     @Override
onSupportActionModeFinished(ActionMode mode)179     public void onSupportActionModeFinished(ActionMode mode) {
180     }
181 
182     @Nullable
183     @Override
onWindowStartingSupportActionMode(ActionMode.Callback callback)184     public ActionMode onWindowStartingSupportActionMode(ActionMode.Callback callback) {
185         return null;
186     }
187 }
188