• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 package com.android.settingslib.utils;
17 import android.annotation.IntDef;
18 import android.annotation.StringRes;
19 import android.app.AlertDialog;
20 import android.app.Dialog;
21 import android.content.Context;
22 import android.graphics.drawable.Drawable;
23 import android.view.LayoutInflater;
24 import android.view.View;
25 import android.view.WindowManager;
26 import android.view.accessibility.AccessibilityEvent;
27 import android.widget.Button;
28 import android.widget.ImageView;
29 import android.widget.LinearLayout;
30 import android.widget.TextView;
31 
32 import com.android.settingslib.R;
33 
34 import java.lang.annotation.Retention;
35 import java.lang.annotation.RetentionPolicy;
36 
37 /**
38  * This class is used to create custom dialog with icon, title, message and custom view that are
39  * horizontally centered.
40  */
41 public class CustomDialogHelper {
42 
43     @Retention(RetentionPolicy.SOURCE)
44     @IntDef({ICON, TITLE, MESSAGE, LAYOUT, BACK_BUTTON, NEGATIVE_BUTTON, POSITIVE_BUTTON})
45     public @interface LayoutComponent {}
46 
47     @Retention(RetentionPolicy.SOURCE)
48     @IntDef({BACK_BUTTON, NEGATIVE_BUTTON, POSITIVE_BUTTON})
49     public @interface LayoutButton {}
50 
51     public static final int ICON = 0;
52     public static final int TITLE = 1;
53     public static final int MESSAGE = 2;
54     public static final int LAYOUT = 3;
55     public static final int BACK_BUTTON = 4;
56     public static final int NEGATIVE_BUTTON = 5;
57     public static final int POSITIVE_BUTTON = 6;
58     private View mDialogContent;
59     private Dialog mDialog;
60     private Context mContext;
61     private LayoutInflater mLayoutInflater;
62     private ImageView mDialogIcon;
63     private TextView mDialogTitle;
64     private TextView mDialogMessage;
65     private LinearLayout mCustomLayout;
66     private Button mPositiveButton;
67     private Button mNegativeButton;
68     private Button mBackButton;
69 
CustomDialogHelper(Context context)70     public CustomDialogHelper(Context context) {
71         mContext = context;
72         mLayoutInflater = LayoutInflater.from(context);
73         mDialogContent = mLayoutInflater.inflate(R.layout.dialog_with_icon, null);
74         mDialogIcon = mDialogContent.findViewById(R.id.dialog_with_icon_icon);
75         mDialogTitle = mDialogContent.findViewById(R.id.dialog_with_icon_title);
76         mDialogMessage = mDialogContent.findViewById(R.id.dialog_with_icon_message);
77         mCustomLayout = mDialogContent.findViewById(R.id.custom_layout);
78         mPositiveButton = mDialogContent.findViewById(R.id.button_ok);
79         mNegativeButton = mDialogContent.findViewById(R.id.button_cancel);
80         mBackButton = mDialogContent.findViewById(R.id.button_back);
81         createDialog();
82     }
83 
84     /**
85      * Creates dialog with content defined in constructor.
86      */
createDialog()87     private void createDialog() {
88         mDialog = new AlertDialog.Builder(mContext)
89                 .setView(mDialogContent)
90                 .setCancelable(true)
91                 .create();
92         mDialog.getWindow()
93                 .setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
94     }
95 
96     /**
97      * Sets title and listener for positive button.
98      */
setPositiveButton(@tringRes int resid, View.OnClickListener onClickListener)99     public CustomDialogHelper setPositiveButton(@StringRes int resid,
100             View.OnClickListener onClickListener) {
101         setButton(POSITIVE_BUTTON, resid, onClickListener);
102         return this;
103     }
104 
105     /**
106      * Sets positive button text.
107      */
setPositiveButtonText(@tringRes int resid)108     public CustomDialogHelper setPositiveButtonText(@StringRes int resid) {
109         mPositiveButton.setText(resid);
110         return this;
111     }
112 
113     /**
114      * Sets title and listener for negative button.
115      */
setNegativeButton(@tringRes int resid, View.OnClickListener onClickListener)116     public CustomDialogHelper setNegativeButton(@StringRes int resid,
117             View.OnClickListener onClickListener) {
118         setButton(NEGATIVE_BUTTON, resid, onClickListener);
119         return this;
120     }
121 
122     /**
123      * Sets negative button text.
124      */
setNegativeButtonText(@tringRes int resid)125     public CustomDialogHelper setNegativeButtonText(@StringRes int resid) {
126         mNegativeButton.setText(resid);
127         return this;
128     }
129 
130     /**
131      * Sets title and listener for back button.
132      */
setBackButton(@tringRes int resid, View.OnClickListener onClickListener)133     public CustomDialogHelper setBackButton(@StringRes int resid,
134             View.OnClickListener onClickListener) {
135         setButton(BACK_BUTTON, resid, onClickListener);
136         return this;
137     }
138 
139     /**
140      * Sets title for back button.
141      */
setBackButtonText(@tringRes int resid)142     public CustomDialogHelper setBackButtonText(@StringRes int resid) {
143         mBackButton.setText(resid);
144         return this;
145     }
146 
setButton(@ayoutButton int whichButton, @StringRes int resid, View.OnClickListener listener)147     private void setButton(@LayoutButton int whichButton, @StringRes int resid,
148             View.OnClickListener listener) {
149         switch (whichButton) {
150             case POSITIVE_BUTTON :
151                 mPositiveButton.setText(resid);
152                 mPositiveButton.setVisibility(View.VISIBLE);
153                 mPositiveButton.setOnClickListener(listener);
154                 break;
155             case NEGATIVE_BUTTON:
156                 mNegativeButton.setText(resid);
157                 mNegativeButton.setVisibility(View.VISIBLE);
158                 mNegativeButton.setOnClickListener(listener);
159                 break;
160             case BACK_BUTTON:
161                 mBackButton.setText(resid);
162                 mBackButton.setVisibility(View.VISIBLE);
163                 mBackButton.setOnClickListener(listener);
164                 break;
165             default:
166                 break;
167         }
168     }
169 
170 
171     /**
172      * Modifies state of button.
173      * //TODO: modify method to allow setting state for any button.
174      */
setButtonEnabled(boolean enabled)175     public CustomDialogHelper setButtonEnabled(boolean enabled) {
176         mPositiveButton.setEnabled(enabled);
177         return this;
178     }
179 
180     /**
181      * Sets title of the dialog.
182      */
setTitle(@tringRes int resid)183     public CustomDialogHelper setTitle(@StringRes int resid) {
184         mDialogTitle.setText(resid);
185         return this;
186     }
187 
188     /**
189      * Sets message of the dialog.
190      */
setMessage(@tringRes int resid)191     public CustomDialogHelper setMessage(@StringRes int resid) {
192         mDialogMessage.setText(resid);
193         return this;
194     }
195 
196     /**
197      * Sets message padding of the dialog.
198      */
setMessagePadding(int dp)199     public CustomDialogHelper setMessagePadding(int dp) {
200         mDialogMessage.setPadding(dp, dp, dp, dp);
201         return this;
202     }
203 
204     /**
205      * Sets icon of the dialog.
206      */
setIcon(Drawable icon)207     public CustomDialogHelper setIcon(Drawable icon) {
208         mDialogIcon.setImageDrawable(icon);
209         return this;
210     }
211 
212     /**
213      * Removes all views that were previously added to the custom layout part.
214      */
clearCustomLayout()215     public CustomDialogHelper clearCustomLayout() {
216         mCustomLayout.removeAllViews();
217         return this;
218     }
219 
220     /**
221      * Hides custom layout.
222      */
hideCustomLayout()223     public void hideCustomLayout() {
224         mCustomLayout.setVisibility(View.GONE);
225     }
226 
227     /**
228      * Shows custom layout.
229      */
showCustomLayout()230     public void showCustomLayout() {
231         mCustomLayout.setVisibility(View.VISIBLE);
232     }
233 
234     /**
235      * Adds view to custom layout.
236      */
addCustomView(View view)237     public CustomDialogHelper addCustomView(View view) {
238         mCustomLayout.addView(view);
239         return this;
240     }
241 
242     /**
243      * Returns dialog.
244      */
getDialog()245     public Dialog getDialog() {
246         return mDialog;
247     }
248 
249     /**
250      * Sets visibility of layout component.
251      * @param element part of the layout visibility of which is being changed.
252      * @param isVisible true if visibility is set to View.VISIBLE
253      * @return this
254      */
setVisibility(@ayoutComponent int element, boolean isVisible)255     public CustomDialogHelper setVisibility(@LayoutComponent int element, boolean isVisible) {
256         int visibility;
257         if (isVisible) {
258             visibility = View.VISIBLE;
259         } else {
260             visibility = View.GONE;
261         }
262         switch (element) {
263             case ICON:
264                 mDialogIcon.setVisibility(visibility);
265                 break;
266             case TITLE:
267                 mDialogTitle.setVisibility(visibility);
268                 break;
269             case MESSAGE:
270                 mDialogMessage.setVisibility(visibility);
271                 break;
272             case BACK_BUTTON:
273                 mBackButton.setVisibility(visibility);
274                 break;
275             case NEGATIVE_BUTTON:
276                 mNegativeButton.setVisibility(visibility);
277                 break;
278             case POSITIVE_BUTTON:
279                 mPositiveButton.setVisibility(visibility);
280                 break;
281             default:
282                 break;
283         }
284         return this;
285     }
286 
287     /**
288      * Requests focus on dialog title when used. Used to let talkback know that the dialog content
289      * is updated and needs to be read from the beginning.
290      */
requestFocusOnTitle()291     public void requestFocusOnTitle() {
292         mDialogTitle.requestFocus();
293         mDialogTitle.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
294     }
295 }
296