Materialized dialogs and preferences (#330)

* Changed platform AlertDialogs and preference.* to support lib counterparts
- added dependencies: support/preference-v7 for PreferenceFragmentCompat
  and Preference subclasses, support/preference-v14 for the
  MultiSelectListPreference
- simplified some AlertDialog.Builder calls and added non-null annotations
  to DialogFragment#onCreateDialog(Bundle) overrides to shut the IDE up
- UIUtils: changed static member avatarColorsIdx to local var because it's
  only used in one place and the value isn't cached
- layout/dialog_send_text: removed view vertical margins as they take
  way too much space for nothing.
- strings: shortened english preference titles
- themes: added PrefTheme and changed preference title font size to medium
  from large
- preferences: changed CheckBoxPreference to SwitchPreferenceCompat. these
  don't have the same issue described in #233 (tested in kitkat).

* Changed platform PreferenceManager in RemoteActivity to support pref

* Fixed M permissions

* Split prefs into 2 groups as per material design guidelines

* Changed prefs theme to v14.material

* Moved container padding to individual prefs; removed pref-v7 dependency
- this makes the item dividers touch the screen edges which i think looks
  better
- don't need to require preference-v7 because preference-v14 already
  does

* Moved PrefTheme attributes *{Start,End} to v17 override

* Fixed crash caused by rotating twice while a dialog is active

* Changed wording as suggested
This commit is contained in:
Mon Zafra 2017-01-04 16:37:13 +08:00 committed by Synced Synapse
parent 07be6da2ad
commit 6e347b6b36
17 changed files with 153 additions and 124 deletions

View File

@ -109,6 +109,7 @@ dependencies {
compile 'com.android.support:support-v4:25.1.0'
compile 'com.android.support:appcompat-v7:25.1.0'
compile 'com.android.support:cardview-v7:25.1.0'
compile 'com.android.support:preference-v14:25.1.0'
compile 'com.android.support:support-v13:25.1.0'
compile 'com.fasterxml.jackson.core:jackson-databind:2.5.2'

View File

@ -16,11 +16,12 @@
package org.xbmc.kore.ui.generic;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
/**
* Dialog fragment that presents a list options to the user.
@ -121,6 +122,7 @@ public class GenericSelectDialog
*
* @return Dialog to select calendars
*/
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

View File

@ -16,11 +16,12 @@
package org.xbmc.kore.ui.generic;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
@ -94,6 +95,7 @@ public class SendTextDialogFragment extends DialogFragment {
* @param savedInstanceState Saved state
* @return Created dialog
*/
@NonNull
@Override
@SuppressWarnings("InflateParams")
public Dialog onCreateDialog(Bundle savedInstanceState) {

View File

@ -16,7 +16,6 @@
package org.xbmc.kore.ui.sections.audio;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.content.res.TypedArray;
@ -30,6 +29,7 @@ import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;

View File

@ -15,15 +15,16 @@
*/
package org.xbmc.kore.ui.sections.hosts;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@ -371,11 +372,11 @@ public class HostListFragment extends Fragment {
return frag;
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.delete_xbmc)
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.delete_xbmc)
.setMessage(R.string.delete_xbmc_confirm)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
@ -386,9 +387,8 @@ public class HostListFragment extends Fragment {
public void onClick(DialogInterface dialog, int id) {
mListener.onDialogNegativeClick();
}
});
// Create the AlertDialog object and return it
return builder.create();
})
.create();
}
}
}

View File

@ -20,11 +20,11 @@ import android.graphics.Point;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.v4.text.TextDirectionHeuristicsCompat;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.preference.PreferenceManager;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.KeyEvent;

View File

@ -5,12 +5,12 @@ package org.xbmc.kore.ui.sections.settings;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.view.View;
@ -25,11 +25,10 @@ import org.xbmc.kore.R;
public class AboutDialogFragment
extends DialogFragment {
@NonNull
@Override
@SuppressWarnings("InflateParams")
public Dialog onCreateDialog(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Activity activity = getActivity();
View mainView = activity.getLayoutInflater().inflate(R.layout.fragment_about, null);
@ -46,18 +45,9 @@ public class AboutDialogFragment
about.setText(Html.fromHtml(getString(R.string.about_desc)));
about.setMovementMethod(LinkMovementMethod.getInstance());
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Build the dialog
builder.setView(mainView)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dismiss();
}
});
return builder.create();
return new AlertDialog.Builder(activity)
.setView(mainView)
.setPositiveButton(android.R.string.ok, null)
.create();
}
}

View File

@ -18,8 +18,9 @@ package org.xbmc.kore.ui.sections.settings;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
@ -31,11 +32,9 @@ import org.xbmc.kore.utils.UIUtils;
/**
* Presents the Preferences fragment
*/
public class SettingsActivity extends ActionBarActivity{
public class SettingsActivity extends AppCompatActivity {
private static final String TAG = LogUtils.makeLogTag(SettingsActivity.class);
private SettingsFragment settingsFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
@ -50,14 +49,17 @@ public class SettingsActivity extends ActionBarActivity{
Toolbar toolbar = (Toolbar)findViewById(R.id.default_toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
assert actionBar != null;
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setTitle(R.string.settings);
// Display the fragment as the main content.
settingsFragment = new SettingsFragment();
getFragmentManager().beginTransaction()
.replace(R.id.fragment_container, settingsFragment)
.commit();
FragmentManager fm = getSupportFragmentManager();
if (fm.findFragmentByTag("settings-fragment") == null) {
fm.beginTransaction()
.replace(R.id.fragment_container, new SettingsFragment(), "settings-fragment")
.commit();
}
}
@Override

View File

@ -20,15 +20,13 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.MultiSelectListPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.preference.TwoStatePreference;
import android.support.annotation.NonNull;
import android.support.v13.app.FragmentCompat;
import android.support.v4.app.TaskStackBuilder;
import android.support.v4.content.ContextCompat;
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceFragmentCompat;
import android.support.v7.preference.TwoStatePreference;
import android.widget.Toast;
import org.xbmc.kore.R;
@ -45,7 +43,7 @@ import java.lang.reflect.Method;
/**
* Simple fragment to display preferences screen
*/
public class SettingsFragment extends PreferenceFragment
public class SettingsFragment extends PreferenceFragmentCompat
implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = LogUtils.makeLogTag(SettingsFragment.class);
@ -53,17 +51,16 @@ public class SettingsFragment extends PreferenceFragment
private int hostId;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
// Get the preference for side menu itens and change its Id to include
// the current host
MultiSelectListPreference sideMenuItens = (MultiSelectListPreference)findPreference(Settings.KEY_PREF_NAV_DRAWER_ITEMS);
Preference sideMenuItems = findPreference(Settings.KEY_PREF_NAV_DRAWER_ITEMS);
hostId = HostManager.getInstance(getActivity()).getHostInfo().getId();
sideMenuItens.setKey(Settings.getNavDrawerItemsPrefKey(hostId));
sideMenuItems.setKey(Settings.getNavDrawerItemsPrefKey(hostId));
// HACK: After changing the key dinamically like above, we need to force the preference
// to read its value. This can be done by calling onSetInitialValue, which is protected,
@ -72,12 +69,12 @@ public class SettingsFragment extends PreferenceFragment
// Furthermore, only do this is nothing is saved yet on the shared preferences,
// otherwise the defaults won't be applied
if (getPreferenceManager().getSharedPreferences().getStringSet(Settings.getNavDrawerItemsPrefKey(hostId), null) != null) {
Class iterClass = sideMenuItens.getClass();
Class iterClass = sideMenuItems.getClass();
try {
@SuppressWarnings("unchecked")
Method m = iterClass.getDeclaredMethod("onSetInitialValue", boolean.class, Object.class);
m.setAccessible(true);
m.invoke(sideMenuItens, true, null);
m.invoke(sideMenuItems, true, null);
} catch (Exception e) {
}
}
@ -108,6 +105,7 @@ public class SettingsFragment extends PreferenceFragment
.unregisterOnSharedPreferenceChangeListener(this);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
// Update summaries
setupPreferences();
@ -127,9 +125,9 @@ public class SettingsFragment extends PreferenceFragment
if (key.equals(Settings.KEY_PREF_PAUSE_DURING_CALLS) &&
(sharedPreferences.getBoolean(Settings.KEY_PREF_PAUSE_DURING_CALLS, Settings.DEFAULT_PREF_PAUSE_DURING_CALLS))) {
if (!hasPhonePermission()) {
FragmentCompat.requestPermissions(this,
new String[] {Manifest.permission.READ_PHONE_STATE},
Utils.PERMISSION_REQUEST_READ_PHONE_STATE);
requestPermissions(
new String[] {Manifest.permission.READ_PHONE_STATE},
Utils.PERMISSION_REQUEST_READ_PHONE_STATE);
}
}
@ -184,7 +182,7 @@ public class SettingsFragment extends PreferenceFragment
@Override
public boolean onPreferenceClick(Preference preference) {
AboutDialogFragment aboutDialog = new AboutDialogFragment();
aboutDialog.show(getActivity().getFragmentManager(), null);
aboutDialog.show(getFragmentManager(), null);
return true;
}
});

View File

@ -16,7 +16,6 @@
package org.xbmc.kore.ui.sections.video;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.content.res.TypedArray;
@ -30,6 +29,7 @@ import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;

View File

@ -15,7 +15,6 @@
*/
package org.xbmc.kore.ui.sections.video;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.content.res.TypedArray;
@ -29,6 +28,7 @@ import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AlertDialog;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;

View File

@ -18,7 +18,6 @@ package org.xbmc.kore.utils;
import android.animation.Animator;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
@ -30,6 +29,7 @@ import android.os.Vibrator;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
@ -140,7 +140,6 @@ public class UIUtils {
}
private static TypedArray characterAvatarColors = null;
private static int avatarColorsIdx = 0;
// private static Random randomGenerator = new Random();
/**
@ -196,10 +195,10 @@ public class UIUtils {
char charAvatar = TextUtils.isEmpty(str) ?
' ' : str.charAt(0);
avatarColorsIdx = TextUtils.isEmpty(str) ? 0 :
Math.max(Character.getNumericValue(str.charAt(0)) +
Character.getNumericValue(str.charAt(str.length() - 1)) +
str.length(), 0) % characterAvatarColors.length();
int avatarColorsIdx = TextUtils.isEmpty(str) ? 0 :
Math.max(Character.getNumericValue(str.charAt(0)) +
Character.getNumericValue(str.charAt(str.length() - 1)) +
str.length(), 0) % characterAvatarColors.length();
int color = characterAvatarColors.getColor(avatarColorsIdx, 0xff000000);
// avatarColorsIdx = randomGenerator.nextInt(characterAvatarColors.length());
return new CharacterDrawable(charAvatar, color);

View File

@ -19,13 +19,14 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:paddingLeft="@dimen/default_padding"
android:paddingRight="@dimen/default_padding">
<EditText
android:id="@+id/text_to_send"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/default_padding"
android:inputType="text"
android:imeOptions="actionSend"
android:hint="@string/text_to_send">
@ -36,7 +37,6 @@
android:id="@+id/send_text_done"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/default_padding"
android:text="@string/finish_after_send"
android:checked="true"/>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2016 Synced Synapse. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<style name="PrefTheme" parent="PreferenceThemeOverlay.v14.Material">
<item name="android:listPreferredItemPaddingStart">@dimen/activity_horizontal_margin</item>
<item name="android:listPreferredItemPaddingRight">@dimen/activity_horizontal_margin</item>
</style>
</resources>

View File

@ -328,13 +328,13 @@
<string name="theme_solarized">Solarized</string>
<string name="theme_solarized_dark">Solarized Dark</string>
<string name="switch_to_remote">Switch to remote after media start</string>
<string name="keep_remote_above_lockscreen">Keep remote above lockscreen</string>
<string name="pref_keep_screen_on">Keep screen on when using remote</string>
<string name="switch_to_remote">Show on media start</string>
<string name="keep_remote_above_lockscreen">Show over lockscreen</string>
<string name="pref_keep_screen_on">Stay awake</string>
<string name="show_notification">Show notification while playing</string>
<string name="pause_during_calls">Pause playing while phone in a call</string>
<string name="use_hardware_volume_keys">Use volume keys to control volume</string>
<string name="vibrate_on_remote">Vibrate on remote button press</string>
<string name="pause_during_calls">Pause during phone call</string>
<string name="use_hardware_volume_keys">Use device volume keys</string>
<string name="vibrate_on_remote">Vibrate on touch</string>
<string name="nav_drawer_items">Side menu shortcuts</string>
<string name="about">About</string>
@ -384,8 +384,8 @@
<string name="single_column">Single column</string>
<string name="multi_column">Multi-column</string>
<string name="download_network_types_title">Download network types</string>
<string name="download_network_types_summary">Allowed network types for media downloads</string>
<string name="download_network_types_title">Restrict media downloads</string>
<string name="download_network_types_summary">Select network types over which media downloads are allowed</string>
<string name="songs">Songs</string>
<string name="read_phone_state_permission_denied">Permission denied. Won\'t be able to pause playback during calls.</string>

View File

@ -23,6 +23,8 @@
<item name="android:windowBackground">@color/dark_background</item>
<!--<item name="android:windowActionBarOverlay">true</item>-->
<item name="preferenceTheme">@style/PrefTheme</item>
<item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
<!-- Set AppCompats color theming attrs -->
@ -151,6 +153,8 @@
<item name="android:colorBackground">@color/light_background</item>
<item name="android:windowBackground">@color/light_background</item>
<item name="preferenceTheme">@style/PrefTheme</item>
<item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
<!-- Set AppCompats color theming attrs -->
@ -346,4 +350,9 @@
<!--<item name="separatorColor">@color/dark_separator</item>-->
</style>
<style name="PrefTheme" parent="PreferenceThemeOverlay.v14.Material">
<item name="android:listPreferredItemPaddingLeft">@dimen/activity_horizontal_margin</item>
<item name="android:listPreferredItemPaddingRight">@dimen/activity_horizontal_margin</item>
</style>
</resources>

View File

@ -14,68 +14,72 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<!--suppress AndroidElementNotAllowed -->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<ListPreference
android:key="pref_theme"
android:title="@string/theme"
android:dialogTitle="@string/theme"
android:entries="@array/themes_array"
android:entryValues="@array/themes_values_array"
android:defaultValue="0"/>
<PreferenceCategory android:title="Remote">
<SwitchPreferenceCompat
android:key="pref_switch_to_remote_after_media_start"
android:title="@string/switch_to_remote"
android:defaultValue="true"/>
<CheckBoxPreference
android:key="pref_switch_to_remote_after_media_start"
android:title="@string/switch_to_remote"
android:defaultValue="true"/>
<SwitchPreferenceCompat
android:key="pref_keep_remote_above_lockscreen"
android:title="@string/keep_remote_above_lockscreen"
android:defaultValue="false"/>
<CheckBoxPreference
android:key="pref_keep_remote_above_lockscreen"
android:title="@string/keep_remote_above_lockscreen"
android:defaultValue="false"/>
<SwitchPreferenceCompat
android:key="pref_use_hardware_volume_keys"
android:title="@string/use_hardware_volume_keys"
android:defaultValue="true"/>
<CheckBoxPreference
android:key="pref_keep_screen_on"
android:title="@string/pref_keep_screen_on"
android:defaultValue="false"/>
<SwitchPreferenceCompat
android:key="pref_vibrate_remote_buttons"
android:title="@string/vibrate_on_remote"
android:defaultValue="false"/>
</PreferenceCategory>
<CheckBoxPreference
android:key="pref_show_notification"
android:title="@string/show_notification"
android:defaultValue="false"/>
<PreferenceCategory android:title="Application">
<ListPreference
android:key="pref_theme"
android:title="@string/theme"
android:entries="@array/themes_array"
android:entryValues="@array/themes_values_array"
android:defaultValue="0"/>
<CheckBoxPreference
android:key="pref_pause_during_calls"
android:title="@string/pause_during_calls"
android:defaultValue="false"/>
<SwitchPreferenceCompat
android:key="pref_keep_screen_on"
android:title="@string/pref_keep_screen_on"
android:defaultValue="false"/>
<CheckBoxPreference
android:key="pref_use_hardware_volume_keys"
android:title="@string/use_hardware_volume_keys"
android:defaultValue="true"/>
<SwitchPreferenceCompat
android:key="pref_show_notification"
android:title="@string/show_notification"
android:defaultValue="false"/>
<CheckBoxPreference
android:key="pref_vibrate_remote_buttons"
android:title="@string/vibrate_on_remote"
android:defaultValue="false"/>
<SwitchPreferenceCompat
android:key="pref_pause_during_calls"
android:title="@string/pause_during_calls"
android:defaultValue="false"/>
<MultiSelectListPreference
android:key="pref_nav_drawer_items"
android:title="@string/nav_drawer_items"
android:entries="@array/entries_nav_drawer_items"
android:entryValues="@array/entry_values_nav_drawer_items"
android:defaultValue="@array/entry_values_nav_drawer_items"/>
<MultiSelectListPreference
android:key="pref_nav_drawer_items"
android:title="@string/nav_drawer_items"
android:entries="@array/entries_nav_drawer_items"
android:entryValues="@array/entry_values_nav_drawer_items"
android:defaultValue="@array/entry_values_nav_drawer_items"/>
<MultiSelectListPreference
android:key="pref_download_conn_types"
android:title="@string/download_network_types_title"
android:summary="@string/download_network_types_summary"
android:entries="@array/entries_download_media_items"
android:entryValues="@array/entry_values_download_media_items"
android:defaultValue="@array/default_values_download_media_items"/>
<MultiSelectListPreference
android:key="pref_download_conn_types"
android:title="@string/download_network_types_title"
android:summary="@string/download_network_types_summary"
android:entries="@array/entries_download_media_items"
android:entryValues="@array/entry_values_download_media_items"
android:defaultValue="@array/default_values_download_media_items"/>
<Preference
android:key="pref_about"
android:title="@string/about"/>
<Preference
android:key="pref_about"
android:title="@string/about"/>
</PreferenceCategory>
</PreferenceScreen>