16904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler/*
26904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Copyright (C) 2015 The Android Open Source Project
36904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler *
46904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Licensed under the Apache License, Version 2.0 (the "License");
56904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * you may not use this file except in compliance with the License.
66904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * You may obtain a copy of the License at
76904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler *
86904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler *      http://www.apache.org/licenses/LICENSE-2.0
96904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler *
106904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * Unless required by applicable law or agreed to in writing, software
116904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * distributed under the License is distributed on an "AS IS" BASIS,
126904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * See the License for the specific language governing permissions and
146904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler * limitations under the License
156904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler */
166904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
176904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerpackage android.support.v14.preference;
186904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
196904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.app.AlertDialog;
206904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.app.Dialog;
216904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.app.DialogFragment;
226904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.app.Fragment;
236904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.content.Context;
246904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.content.DialogInterface;
256904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.os.Bundle;
266904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.support.annotation.NonNull;
276904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.support.v7.preference.DialogPreference;
286904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.text.TextUtils;
296904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.view.LayoutInflater;
306904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.view.View;
316904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.view.Window;
326904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.view.WindowManager;
336904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerimport android.widget.TextView;
346904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
356904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantlerpublic abstract class PreferenceDialogFragment extends DialogFragment implements
366904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        DialogInterface.OnClickListener {
376904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
386904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    protected static final String ARG_KEY = "key";
396904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
406904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    private DialogPreference mPreference;
416904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
426904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    /** Which button was clicked. */
436904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    private int mWhichButtonClicked;
446904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
456904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    @Override
466904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    public void onCreate(Bundle savedInstanceState) {
476904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        super.onCreate(savedInstanceState);
486904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
496904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        final Fragment rawFragment = getTargetFragment();
506904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        if (!(rawFragment instanceof DialogPreference.TargetFragment)) {
516904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            throw new IllegalStateException("Target fragment must implement TargetFragment" +
526904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                    " interface");
536904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
546904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
556904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        final DialogPreference.TargetFragment fragment =
566904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                (DialogPreference.TargetFragment) rawFragment;
576904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
586904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        final String key = getArguments().getString(ARG_KEY);
596904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        mPreference = (DialogPreference) fragment.findPreference(key);
606904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
616904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
626904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    @Override
636904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    public @NonNull
646904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    Dialog onCreateDialog(Bundle savedInstanceState) {
656904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        final Context context = getActivity();
666904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        mWhichButtonClicked = DialogInterface.BUTTON_NEGATIVE;
676904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
686904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        final AlertDialog.Builder builder = new AlertDialog.Builder(context)
696904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                .setTitle(mPreference.getDialogTitle())
706904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                .setIcon(mPreference.getDialogIcon())
716904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                .setPositiveButton(mPreference.getPositiveButtonText(), this)
726904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                .setNegativeButton(mPreference.getNegativeButtonText(), this);
736904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
746904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        View contentView = onCreateDialogView(context);
756904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        if (contentView != null) {
766904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            onBindDialogView(contentView);
776904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            builder.setView(contentView);
786904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        } else {
796904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            builder.setMessage(mPreference.getDialogMessage());
806904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
816904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
826904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        onPrepareDialogBuilder(builder);
836904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
846904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        // Create the dialog
856904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        final Dialog dialog = builder.create();
866904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        if (needInputMethod()) {
876904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            requestInputMethod(dialog);
886904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
896904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
906904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
916904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        return builder.create();
926904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
936904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
946904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    /**
956904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * Get the preference that requested this dialog. Available after {@link #onCreate(Bundle)} has
966904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * been called.
976904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     *
986904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * @return The {@link DialogPreference} associated with this
996904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * dialog.
1006904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     */
1016904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    public DialogPreference getPreference() {
1026904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        return mPreference;
1036904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
1046904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1056904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    /**
1066904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * Prepares the dialog builder to be shown when the preference is clicked.
1076904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * Use this to set custom properties on the dialog.
1086904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * <p>
1096904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * Do not {@link AlertDialog.Builder#create()} or
1106904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * {@link AlertDialog.Builder#show()}.
1116904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     */
1126904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {}
1136904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1146904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    /**
1156904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * Returns whether the preference needs to display a soft input method when the dialog
1166904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * is displayed. Default is false. Subclasses should override this method if they need
1176904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * the soft input method brought up automatically.
1186904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * @hide
1196904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     */
1206904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    protected boolean needInputMethod() {
1216904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        return false;
1226904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
1236904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1246904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    /**
1256904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * Sets the required flags on the dialog window to enable input method window to show up.
1266904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     */
1276904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    private void requestInputMethod(Dialog dialog) {
1286904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        Window window = dialog.getWindow();
1296904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
1306904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
1316904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1326904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    /**
1336904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * Creates the content view for the dialog (if a custom content view is
1346904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * required). By default, it inflates the dialog layout resource if it is
1356904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * set.
1366904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     *
1376904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * @return The content View for the dialog.
1386904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * @see DialogPreference#setLayoutResource(int)
1396904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     */
1406904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    protected View onCreateDialogView(Context context) {
1416904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        final int resId = mPreference.getDialogLayoutResource();
1426904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        if (resId == 0) {
1436904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            return null;
1446904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
1456904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1466904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        LayoutInflater inflater = LayoutInflater.from(context);
1476904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        return inflater.inflate(resId, null);
1486904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
1496904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1506904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    /**
1516904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * Binds views in the content View of the dialog to data.
1526904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * <p>
1536904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * Make sure to call through to the superclass implementation.
1546904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     *
1556904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     * @param view The content View of the dialog, if it is custom.
1566904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler     */
1576904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    protected void onBindDialogView(View view) {
1586904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        View dialogMessageView = view.findViewById(android.R.id.message);
1596904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1606904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        if (dialogMessageView != null) {
1616904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            final CharSequence message = mPreference.getDialogMessage();
1626904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            int newVisibility = View.GONE;
1636904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1646904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            if (!TextUtils.isEmpty(message)) {
1656904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                if (dialogMessageView instanceof TextView) {
1666904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                    ((TextView) dialogMessageView).setText(message);
1676904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                }
1686904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1696904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                newVisibility = View.VISIBLE;
1706904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            }
1716904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1726904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            if (dialogMessageView.getVisibility() != newVisibility) {
1736904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler                dialogMessageView.setVisibility(newVisibility);
1746904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler            }
1756904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        }
1766904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
1776904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1786904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    @Override
1796904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    public void onClick(DialogInterface dialog, int which) {
1806904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        mWhichButtonClicked = which;
1816904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
1826904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1836904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    @Override
1846904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    public void onDismiss(DialogInterface dialog) {
1856904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        super.onDismiss(dialog);
1866904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler        onDialogClosed(mWhichButtonClicked == DialogInterface.BUTTON_POSITIVE);
1876904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    }
1886904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler
1896904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler    public abstract void onDialogClosed(boolean positiveResult);
1906904f67c96a28a0e5966b4fb6d37a0ad5f136858Tony Mantler}
191