• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 android.support.v7.preference;
18 
19 import android.app.Dialog;
20 import android.content.Context;
21 import android.content.DialogInterface;
22 import android.os.Bundle;
23 import android.support.annotation.NonNull;
24 import android.support.v4.app.DialogFragment;
25 import android.support.v4.app.Fragment;
26 import android.support.v7.app.AlertDialog;
27 import android.text.TextUtils;
28 import android.view.LayoutInflater;
29 import android.view.View;
30 import android.view.Window;
31 import android.view.WindowManager;
32 import android.widget.TextView;
33 
34 public abstract class PreferenceDialogFragmentCompat extends DialogFragment implements
35         DialogInterface.OnClickListener {
36 
37     protected static final String ARG_KEY = "key";
38 
39     private DialogPreference mPreference;
40 
41     /** Which button was clicked. */
42     private int mWhichButtonClicked;
43 
44     @Override
onCreate(Bundle savedInstanceState)45     public void onCreate(Bundle savedInstanceState) {
46         super.onCreate(savedInstanceState);
47 
48         final Fragment rawFragment = getTargetFragment();
49         if (!(rawFragment instanceof DialogPreference.TargetFragment)) {
50             throw new IllegalStateException("Target fragment must implement TargetFragment" +
51                     " interface");
52         }
53 
54         final DialogPreference.TargetFragment fragment =
55                 (DialogPreference.TargetFragment) rawFragment;
56 
57         final String key = getArguments().getString(ARG_KEY);
58         mPreference = (DialogPreference) fragment.findPreference(key);
59     }
60 
61     @Override
onCreateDialog(Bundle savedInstanceState)62     public @NonNull Dialog onCreateDialog(Bundle savedInstanceState) {
63         final Context context = getActivity();
64         mWhichButtonClicked = DialogInterface.BUTTON_NEGATIVE;
65 
66         final AlertDialog.Builder builder = new AlertDialog.Builder(context)
67                 .setTitle(mPreference.getDialogTitle())
68                 .setIcon(mPreference.getDialogIcon())
69                 .setPositiveButton(mPreference.getPositiveButtonText(), this)
70                 .setNegativeButton(mPreference.getNegativeButtonText(), this);
71 
72         View contentView = onCreateDialogView(context);
73         if (contentView != null) {
74             onBindDialogView(contentView);
75             builder.setView(contentView);
76         } else {
77             builder.setMessage(mPreference.getDialogMessage());
78         }
79 
80         onPrepareDialogBuilder(builder);
81 
82         // Create the dialog
83         final Dialog dialog = builder.create();
84         if (needInputMethod()) {
85             requestInputMethod(dialog);
86         }
87 
88 
89         return builder.create();
90     }
91 
92     /**
93      * Get the preference that requested this dialog. Available after {@link #onCreate(Bundle)} has
94      * been called.
95      *
96      * @return The {@link DialogPreference} associated with this
97      * dialog.
98      */
getPreference()99     public DialogPreference getPreference() {
100         return mPreference;
101     }
102 
103     /**
104      * Prepares the dialog builder to be shown when the preference is clicked.
105      * Use this to set custom properties on the dialog.
106      * <p>
107      * Do not {@link AlertDialog.Builder#create()} or
108      * {@link AlertDialog.Builder#show()}.
109      */
onPrepareDialogBuilder(AlertDialog.Builder builder)110     protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {}
111 
112     /**
113      * Returns whether the preference needs to display a soft input method when the dialog
114      * is displayed. Default is false. Subclasses should override this method if they need
115      * the soft input method brought up automatically.
116      * @hide
117      */
needInputMethod()118     protected boolean needInputMethod() {
119         return false;
120     }
121 
122     /**
123      * Sets the required flags on the dialog window to enable input method window to show up.
124      */
requestInputMethod(Dialog dialog)125     private void requestInputMethod(Dialog dialog) {
126         Window window = dialog.getWindow();
127         window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
128     }
129 
130     /**
131      * Creates the content view for the dialog (if a custom content view is
132      * required). By default, it inflates the dialog layout resource if it is
133      * set.
134      *
135      * @return The content View for the dialog.
136      * @see DialogPreference#setLayoutResource(int)
137      */
onCreateDialogView(Context context)138     protected View onCreateDialogView(Context context) {
139         final int resId = mPreference.getDialogLayoutResource();
140         if (resId == 0) {
141             return null;
142         }
143 
144         LayoutInflater inflater = LayoutInflater.from(context);
145         return inflater.inflate(resId, null);
146     }
147 
148     /**
149      * Binds views in the content View of the dialog to data.
150      * <p>
151      * Make sure to call through to the superclass implementation.
152      *
153      * @param view The content View of the dialog, if it is custom.
154      */
onBindDialogView(View view)155     protected void onBindDialogView(View view) {
156         View dialogMessageView = view.findViewById(android.R.id.message);
157 
158         if (dialogMessageView != null) {
159             final CharSequence message = mPreference.getDialogMessage();
160             int newVisibility = View.GONE;
161 
162             if (!TextUtils.isEmpty(message)) {
163                 if (dialogMessageView instanceof TextView) {
164                     ((TextView) dialogMessageView).setText(message);
165                 }
166 
167                 newVisibility = View.VISIBLE;
168             }
169 
170             if (dialogMessageView.getVisibility() != newVisibility) {
171                 dialogMessageView.setVisibility(newVisibility);
172             }
173         }
174     }
175 
176     @Override
onClick(DialogInterface dialog, int which)177     public void onClick(DialogInterface dialog, int which) {
178         mWhichButtonClicked = which;
179     }
180 
181     @Override
onDismiss(DialogInterface dialog)182     public void onDismiss(DialogInterface dialog) {
183         super.onDismiss(dialog);
184         onDialogClosed(mWhichButtonClicked == DialogInterface.BUTTON_POSITIVE);
185     }
186 
onDialogClosed(boolean positiveResult)187     public abstract void onDialogClosed(boolean positiveResult);
188 }
189