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