SettingsPreferenceFragment.java revision 9c8bde576ab18fcfe653587f3e63604430c8791c
1/*
2 * Copyright (C) 2010 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
17package com.android.settings;
18
19import android.app.Activity;
20import android.app.Dialog;
21import android.app.DialogFragment;
22import android.content.ContentResolver;
23import android.content.Intent;
24import android.content.pm.PackageManager;
25import android.content.res.Resources;
26import android.os.Bundle;
27import android.preference.PreferenceActivity;
28import android.preference.PreferenceFragment;
29import android.text.TextUtils;
30import android.util.Log;
31import android.view.View;
32import android.view.View.OnClickListener;
33import android.widget.Button;
34
35/**
36 * Base class for Settings fragments, with some helper functions and dialog management.
37 */
38public class SettingsPreferenceFragment extends PreferenceFragment {
39
40    private static final String TAG = "SettingsPreferenceFragment";
41
42    // Originally from PreferenceActivity.
43    private static final String EXTRA_PREFS_SHOW_BUTTON_BAR = "extra_prefs_show_button_bar";
44    private static final String EXTRA_PREFS_SHOW_SKIP = "extra_prefs_show_skip";
45    private static final String EXTRA_PREFS_SET_NEXT_TEXT = "extra_prefs_set_next_text";
46    private static final String EXTRA_PREFS_SET_BACK_TEXT = "extra_prefs_set_back_text";
47
48    private SettingsDialogFragment mDialogFragment;
49
50    private OnStateListener mOnStateListener;
51
52    private Button mNextButton;
53
54    interface OnStateListener {
55
56        void onCreated(SettingsPreferenceFragment fragment);
57
58        void onDestroyed(SettingsPreferenceFragment fragment);
59    }
60
61    public void setOnStateListener(OnStateListener listener) {
62        mOnStateListener = listener;
63    }
64
65    @Override
66    public void onActivityCreated(Bundle savedInstanceState) {
67        super.onActivityCreated(savedInstanceState);
68        if (mOnStateListener != null) {
69            mOnStateListener.onCreated(this);
70        }
71
72        setupButtonBar();
73    }
74
75    @Override
76    public void onDestroy() {
77        super.onDestroy();
78        if (mOnStateListener != null) {
79            mOnStateListener.onDestroyed(this);
80        }
81    }
82
83    // Some helpers for functions used by the settings fragments when they were activities
84
85    /**
86     * Returns the ContentResolver from the owning Activity.
87     */
88    protected ContentResolver getContentResolver() {
89        return getActivity().getContentResolver();
90    }
91
92    /**
93     * Returns the specified system service from the owning Activity.
94     */
95    protected Object getSystemService(final String name) {
96        return getActivity().getSystemService(name);
97    }
98
99    /**
100     * Returns the Resources from the owning Activity.
101     */
102    protected Resources getResources() {
103        return getActivity().getResources();
104    }
105
106    /**
107     * Returns the PackageManager from the owning Activity.
108     */
109    protected PackageManager getPackageManager() {
110        return getActivity().getPackageManager();
111    }
112
113    // Dialog management
114
115    protected void showDialog(int dialogId) {
116        if (mDialogFragment != null) {
117            Log.e(TAG, "Old dialog fragment not null!");
118        }
119        mDialogFragment = new SettingsDialogFragment(this, dialogId);
120        mDialogFragment.show(getActivity(), Integer.toString(dialogId));
121    }
122
123    public Dialog onCreateDialog(int dialogId) {
124        return null;
125    }
126
127    protected void removeDialog(int dialogId) {
128        if (mDialogFragment != null && mDialogFragment.getDialogId() == dialogId
129                && mDialogFragment.isVisible()) {
130            mDialogFragment.dismiss();
131        }
132        mDialogFragment = null;
133    }
134
135    static class SettingsDialogFragment extends DialogFragment {
136        private int mDialogId;
137
138        private SettingsPreferenceFragment mFragment;
139
140        SettingsDialogFragment(SettingsPreferenceFragment fragment, int dialogId) {
141            mDialogId = dialogId;
142            mFragment = fragment;
143        }
144
145        @Override
146        public Dialog onCreateDialog(Bundle savedInstanceState) {
147            return mFragment.onCreateDialog(mDialogId);
148        }
149
150        public int getDialogId() {
151            return mDialogId;
152        }
153    }
154
155    protected boolean hasNextButton() {
156        return mNextButton != null;
157    }
158
159    protected Button getNextButton() {
160        return mNextButton;
161    }
162
163    /**
164     * Sets up Button Bar possibly required in the Fragment. Probably available only in
165     * phones.
166     *
167     * Previously {@link PreferenceActivity} had the capability as hidden functionality.
168     */
169    private void setupButtonBar() {
170        // Originally from PreferenceActivity, which has had button bar inside its layout.
171        final Activity activity = getActivity();
172        final Intent intent = activity.getIntent();
173        final View buttonBar = activity.findViewById(com.android.internal.R.id.button_bar);
174        if (!intent.getBooleanExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, false) || buttonBar == null) {
175            return;
176        }
177
178        buttonBar.setVisibility(View.VISIBLE);
179        View tmpView = activity.findViewById(com.android.internal.R.id.back_button);
180        if (tmpView != null) {
181            // TODO: Assume this is pressed only in single pane, finishing current Activity.
182            try {
183                final Button backButton = (Button)tmpView;
184                backButton.setOnClickListener(new OnClickListener() {
185                    public void onClick(View v) {
186                        activity.setResult(Activity.RESULT_CANCELED);
187                        activity.finish();
188                    }
189                });
190                if (intent.hasExtra(EXTRA_PREFS_SET_BACK_TEXT)) {
191                    String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_BACK_TEXT);
192                    if (TextUtils.isEmpty(buttonText)) {
193                        backButton.setVisibility(View.GONE);
194                    }
195                    else {
196                        backButton.setText(buttonText);
197                    }
198                }
199            } catch (ClassCastException e) {
200                Log.w(TAG, "The view originally for back_button is used not as Button. " +
201                        "Ignored.");
202            }
203        }
204
205        tmpView = activity.findViewById(com.android.internal.R.id.skip_button);
206        if (tmpView != null) {
207            try {
208                final Button skipButton = (Button)tmpView;
209                skipButton.setOnClickListener(new OnClickListener() {
210                    public void onClick(View v) {
211                        activity.setResult(Activity.RESULT_OK);
212                        activity.finish();
213                    }
214                });
215                if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_SKIP, false)) {
216                    skipButton.setVisibility(View.VISIBLE);
217                }
218            } catch (ClassCastException e) {
219                Log.w(TAG, "The view originally for skip_button is used not as Button. " +
220                        "Ignored.");
221            }
222        }
223
224        tmpView = activity.findViewById(com.android.internal.R.id.next_button);
225        if (tmpView != null) {
226            try {
227                mNextButton = (Button)tmpView;
228                mNextButton.setOnClickListener(new OnClickListener() {
229                    public void onClick(View v) {
230                        activity.setResult(Activity.RESULT_OK);
231                        activity.finish();
232                    }
233                });
234                // set our various button parameters
235                if (intent.hasExtra(EXTRA_PREFS_SET_NEXT_TEXT)) {
236                    String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_NEXT_TEXT);
237                    if (TextUtils.isEmpty(buttonText)) {
238                        mNextButton.setVisibility(View.GONE);
239                    }
240                    else {
241                        mNextButton.setText(buttonText);
242                    }
243                }
244            } catch (ClassCastException e) {
245                Log.w(TAG, "The view originally for next_button is used not as Button. " +
246                        "Ignored.");
247                mNextButton = null;
248            }
249        }
250    }
251}
252