I'm quite new to Android's Preference system and I am currently facing a problem.
As advised by Android Guide (http://developer.android.com/guide/topics/ui/settings.html), I use Preference Fragment. Thus, my SettingsActivity contains some stuff (headers like title, tabs, etc.) and the PreferenceFragment below.
The thing is when I click on a preference associated to a "sub" PreferenceScreen, the "new preference screen" does not respect my fragment's layout but instead it fills the entire activity.
Here's an example: let's say I have a PreferenceFragment that invokes addPreferenceFromResource(R.xml.preferences). preferences.xml does contain a "Change password" preference, which is a PreferenceScreen containing 3 TextEditPreference.
preferences.xml
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<EditTextPreference android:title="@string/pref_one"/>
<EditTextPreference android:title="@string/pref_two"/>
<PreferenceScreen android:title="@string/pref_change_password">
<EditTextPreference android:title="@string/pref_current_pass"
android:inputType="textPassword"
android:hint="@string/hint_current_password" />
<EditTextPreference android:title="@string/pref_new_pass"
android:inputType="textPassword"
android:hint="@string/hint_new_password" />
<EditTextPreference android:title="@string/pref_confirm_new_pass"
android:inputType="textPassword"
android:hint="@string/hint_confirm_new_password" />
</PreferenceScreen>
</PreferenceScreen>
So when I click on the PreferenceScreen, it does this:
How can I do that? Thank you in advance for your answers!
Okay so, after a deep dive in Android Reference, I found the solution.
It appears that when a sub PreferenceScreen is clicked, a Dialog containing the new Preference objects is opened, not a new Activity or whatever.
Thus the solution is to retrieve the dialog and to make it fits into the original PreferenceFragment's layout. To do so, I used the onPreferenceTreeClick callback method to detect if a PreferenceScreen is clicked:
public class SettingsFragment extends PreferenceFragment {
// onCreate and other stuff...
@Override
public boolean onPreferenceTreeClick (PreferenceScreen preferenceScreen,
Preference preference) {
// Initiating Dialog's layout when any sub PreferenceScreen clicked
if(preference.getClass() == PreferenceScreen.class) {
// Retrieving the opened Dialog
Dialog dialog = ((PreferenceScreen) preference).getDialog();
if(dialog == null) return false;
initDialogLayout(dialog); // Initiate the dialog's layout
}
return true;
}
private void initDialogLayout(Dialog dialog) {
View fragmentView = getView();
// Get absolute coordinates of the PreferenceFragment
int fragmentViewLocation [] = new int[2];
fragmentView.getLocationOnScreen(fragmentViewLocation);
// Set new dimension and position attributes of the dialog
WindowManager.LayoutParams wlp = dialog.getWindow().getAttributes();
wlp.x = fragmentViewLocation[0]; // 0 for x
wlp.y = fragmentViewLocation[1]; // 1 for y
wlp.width = fragmentView.getWidth();
wlp.height = fragmentView.getHeight();
dialog.getWindow().setAttributes(wlp);
// Set flag so that you can still interact with objects outside the dialog
dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
}
}
And that's it, that made the trick. Please comment if you think there is a better way.