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