android - masivos - cómo crear un grupo nuevo en gmail
¿Cómo crear grupos de encabezados de preferencia en la actividad de preferencia de Android? (5)
Este es un ejemplo de categoría de preferencia, puede usar la categoría de preferencia y establecer el fragmento respectivo y lograrlo. Avíseme si entendí mal su caso.
Aquí está el diseño de muestra
<PreferenceCategory android:title="Heading1">
<Preference
android:title="title1"
android:summary="summary1"
android:key="keyName"/>
<Preference
android:title="title2"
android:summary="summary2"
android:key="keyName"/>
</PreferenceCategory>
<PreferenceCategory android:title="Heading2">
<Preference
android:title="title3"
android:summary="summary3"
android:key="keyName"/>
</PreferenceCategory>
Estoy usando encabezados de preferencias para crear la actividad de configuración usando PreferenceActivity
Estoy tratando de dividir los encabezados en categorías / grupos, como este (hay categorías Wireless & Networks, Device, Personal, ...):
De todos modos, incluso el sitio de Desarrolladores de Android trata sobre esta forma de crear actividad de preferencias, no pude encontrar la manera de crear la misma actividad de preferencias que tienen en la imagen. Lo único que logré hacer es una simple lista de encabezados de preferencias.
Lo único que he encontrado es this , pero funciona un poco ... extraño. Así que eso no parece ser una opción.
Así que mi pregunta es: ¿Cómo crear PreferenceActivity
usando encabezados de preferencia con la posibilidad de dividir los encabezados en categorías y con la posibilidad de usar los interruptores de encendido / apagado maestro?
Algunos de mis codigos:
preferences_headers.xml :
<?xml version="1.0" encoding="utf-8"?>
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
<header
android:fragment="cz.vse.myevents.activity.SettingsActivity$EventsFragment"
android:title="@string/settings_events"
android:icon="@android:drawable/ic_menu_agenda" />
<header
android:fragment="cz.vse.myevents.activity.SettingsActivity$OrganizationsFragment"
android:title="@string/settings_subscribed_organizations"
android:icon="@android:drawable/ic_menu_view" />
</preference-headers>
ConfiguraciónActividad :
@Override
public void onBuildHeaders(List<Header> target) {
super.onBuildHeaders(target);
loadHeadersFromResource(R.xml.preference_headers, target);
}
No estoy publicando fragmentos de recursos, creo que es innecesario.
Esto es en realidad bastante sencillo. Por lo que encontré, la raíz PreferenceActivity
sí no admite agregarle títulos de categoría / sección, parece que solo puede agregar Header
s, lo que no es muy interesante.
Entonces, lo primero que debe hacer es no hacer ningún trabajo pesado en su propia PreferenceActivity
y dirigirse directamente a cargar un PreferenceFragment
:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle("Settings");
// Display the fragment as the main content.
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new PreferencesFragment())
.commit();
}
public static class PreferencesFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.prefs);
}
}
Una vez que haya hecho esto, ahora puede hacer todo el trabajo en su PreferenceFragment
, ¡y la gran noticia es que ahora puede usar categorías !
El archivo R.xml.prefs debería tener este aspecto:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory
android:summary="Login credentials"
android:title="Login credentials" >
<EditTextPreference
android:key="username"
android:summary="Username"
android:title="Username" />
<EditTextPreference
android:key="password"
android:summary="Password"
android:title="Password" />
</PreferenceCategory>
<PreferenceCategory
android:summary="Settings"
android:title="Settings" >
<CheckBoxPreference
android:key="persist"
android:summary="Yes/No"
android:title="Keep me signed in" />
</PreferenceCategory>
</PreferenceScreen>
Simplemente cree una Categoría de PreferenceCategory
para cada nueva categoría que desee agregar.
Implementación de AOSP settings_headers.xml:
<preference-headers
xmlns:android="http://schemas.android.com/apk/res/android">
<!-- WIRELESS and NETWORKS -->
<header android:title="@string/header_category_wireless_networks" />
<!-- Wifi -->
<header
android:id="@+id/wifi_settings"
android:fragment="com.android.settings.wifi.WifiSettings"
android:title="@string/wifi_settings_title"
android:icon="@drawable/ic_settings_wireless" />
<!-- Bluetooth -->
<header
android:id="@+id/bluetooth_settings"
android:fragment="com.android.settings.bluetooth.BluetoothSettings"
android:title="@string/bluetooth_settings_title"
android:icon="@drawable/ic_settings_bluetooth2" />
<!-- Data Usage -->
<header
android:id="@+id/data_usage_settings"
android:fragment="com.android.settings.DataUsageSummary"
android:title="@string/data_usage_summary_title"
android:icon="@drawable/ic_settings_data_usage" />
<!-- Operator hook -->
<header
android:fragment="com.android.settings.WirelessSettings"
android:id="@+id/operator_settings">
<intent android:action="com.android.settings.OPERATOR_APPLICATION_SETTING" />
</header>
<!-- Other wireless and network controls -->
<header
android:id="@+id/wireless_settings"
android:title="@string/radio_controls_title"
android:breadCrumbTitle="@string/wireless_networks_settings_title"
android:fragment="com.android.settings.WirelessSettings"
android:icon="@drawable/empty_icon" />
<!-- Ethernet -->
<header
android:id="@+id/ethernet_settings"
android:title="@string/eth_radio_ctrl_title"
android:icon="@drawable/ic_settings_ethernet"
android:fragment="com.android.settings.ethernet.EthernetSettings"/>
<!-- DEVICE -->
<header android:title="@string/header_category_device" />
<!-- Sound -->
<header
android:id="@+id/sound_settings"
android:icon="@drawable/ic_settings_sound"
android:fragment="com.android.settings.SoundSettings"
android:title="@string/sound_settings" />
<!-- Display -->
<header
android:id="@+id/display_settings"
android:icon="@drawable/ic_settings_display"
android:fragment="com.android.settings.DisplaySettings"
android:title="@string/display_settings" />
<!-- Storage -->
<header
android:id="@+id/storage_settings"
android:fragment="com.android.settings.deviceinfo.Memory"
android:icon="@drawable/ic_settings_storage"
android:title="@string/storage_settings" />
<!-- Battery -->
<header
android:id="@+id/battery_settings"
android:fragment="com.android.settings.fuelgauge.PowerUsageSummary"
android:icon="@drawable/ic_settings_battery"
android:title="@string/power_usage_summary_title" />
<!-- Application Settings -->
<header
android:fragment="com.android.settings.applications.ManageApplications"
android:icon="@drawable/ic_settings_applications"
android:title="@string/applications_settings"
android:id="@+id/application_settings" />
<!-- TEMPORARY FACTORY STARTER WILL BE REMOVED WITH UPDATED SETTINGS -->
<header
android:icon="@drawable/ic_settings_applications"
android:title="Factory"
android:id="@+id/application_settings" >
<intent android:action="android.intent.action.MAIN"
android:targetPackage="com.jamdeo.tv.sample.factory"
android:targetClass="com.jamdeo.tv.sample.factory.TvFactoryMainActivity" />
</header>
<!-- Manufacturer hook -->
<header
android:fragment="com.android.settings.WirelessSettings"
android:id="@+id/manufacturer_settings">
<intent android:action="com.android.settings.MANUFACTURER_APPLICATION_SETTING" />
</header>
<!-- PERSONAL -->
<header android:title="@string/header_category_personal" />
<!-- Data Sync. The settings activity will ensure this is resolved to an
activity on the system image, otherwise it will remove this
preference. -->
<header
android:fragment="com.android.settings.accounts.ManageAccountsSettings"
android:icon="@drawable/ic_settings_sync"
android:title="@string/sync_settings"
android:id="@+id/sync_settings" />
<!-- Location -->
<header
android:fragment="com.android.settings.LocationSettings"
android:icon="@drawable/ic_settings_location"
android:title="@string/location_settings_title"
android:id="@+id/location_settings" />
<!-- Security -->
<header
android:fragment="com.android.settings.SecuritySettings"
android:icon="@drawable/ic_settings_security"
android:title="@string/security_settings_title"
android:id="@+id/security_settings" />
<!-- Language -->
<header
android:id="@+id/language_settings"
android:fragment="com.android.settings.inputmethod.InputMethodAndLanguageSettings"
android:icon="@drawable/ic_settings_language"
android:title="@string/language_settings" />
<!-- Backup and reset -->
<header
android:fragment="com.android.settings.PrivacySettings"
android:icon="@drawable/ic_settings_backup"
android:title="@string/privacy_settings"
android:id="@+id/privacy_settings" />
<!-- SYSTEM -->
<header android:title="@string/header_category_system" />
<!-- Dock -->
<header
android:id="@+id/dock_settings"
android:fragment="com.android.settings.DockSettings"
android:icon="@drawable/ic_settings_dock"
android:title="@string/dock_settings" />
<!-- Date & Time -->
<header
android:id="@+id/date_time_settings"
android:fragment="com.android.settings.DateTimeSettings"
android:icon="@drawable/ic_settings_date_time"
android:title="@string/date_and_time_settings_title" />
<!-- Accessibility feedback -->
<header
android:id="@+id/accessibility_settings"
android:fragment="com.android.settings.AccessibilitySettings"
android:icon="@drawable/ic_settings_accessibility"
android:title="@string/accessibility_settings" />
<!-- Development -->
<header
android:id="@+id/development_settings"
android:fragment="com.android.settings.DevelopmentSettings"
android:icon="@drawable/ic_settings_development"
android:title="@string/development_settings_title" />
<!-- About Device -->
<header
android:id="@+id/about_settings"
android:fragment="com.android.settings.DeviceInfoSettings"
android:icon="@drawable/ic_settings_about"
android:title="@string/about_settings" />
</preference-headers>
Solo usa <header>
solo con el atributo de android:title
.
Para elaborar la respuesta de T. Folsom , aquí está mi implementación:
res / layout / preferences_header_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/activatedBackgroundIndicator"
android:baselineAligned="false"
android:gravity="center_vertical"
android:minHeight="48dp"
android:paddingRight="?android:attr/scrollbarSize" >
<LinearLayout
android:layout_width="@dimen/header_icon_width"
android:layout_height="wrap_content"
android:layout_marginLeft="6dip"
android:layout_marginRight="6dip" >
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</LinearLayout>
<RelativeLayout
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_marginBottom="6dip"
android:layout_marginLeft="2dip"
android:layout_marginRight="6dip"
android:layout_marginTop="6dip"
android:layout_weight="1" >
<TextView
android:id="@+android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@android:id/title"
android:ellipsize="end"
android:maxLines="2"
android:textAppearance="?android:attr/textAppearanceSmall" />
</RelativeLayout>
</LinearLayout>
res / values / dimens.xml
<resources>
<dimen name="header_icon_width">28dp</dimen>
</resources>
en su clase de PreferenceActivity:
@Override
protected void onCreate(Bundle savedInstanceState) {
if (savedInstanceState != null) {
/*
* the headers must be restored before the super call in order
* to be ready for the call to setListAdapter()
*/
if (savedInstanceState.containsKey("headers")) {
setHeaders((ArrayList<Header>)savedInstanceState.getSerializable("headers"));
}
}
// as suggest by https://.com/questions/15551673/android-headers-categories-in-preferenceactivity-with-preferencefragment
if(onIsMultiPane()) getIntent().putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT, PreferencesFragment.class.getName());
super.onCreate(savedInstanceState);
...
}
@Override
protected void onResume() {
super.onResume();
// https://.com/questions/15551673/android-headers-categories-in-preferenceactivity-with-preferencefragment
// Select the displayed fragment in the headers (when using a tablet) :
// This should be done by Android, it is a bug fix
if(getHeaders() != null) {
final String displayedFragment = getIntent().getStringExtra(EXTRA_SHOW_FRAGMENT);
if (displayedFragment != null) {
for (final Header header : getHeaders()) {
if (displayedFragment.equals(header.fragment)) {
switchToHeader(header);
break;
}
}
}
}
...
}
/**
* Populate the activity with the top-level headers.
*/
@Override
public void onBuildHeaders(List<Header> target) {
// we have to save the headers as the API call getHeaders() is hidden.
setHeaders(target);
loadHeadersFromResource(R.xml.settings_headers, target);
}
private List<Header> headers;
private void setHeaders(List<Header> headers) {
this.headers = headers;
}
private List<Header> getHeaders() {
return headers;
}
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putSerializable("headers", (ArrayList<PreferenceActivity.Header>)headers);
super.onSaveInstanceState(outState);
}
@Override
public void setListAdapter(ListAdapter adapter) {
if (adapter == null) {
super.setListAdapter(null);
} else {
super.setListAdapter(new HeaderAdapter(this, getHeaders()));
}
}
private static class HeaderAdapter extends ArrayAdapter<Header> {
static final int HEADER_TYPE_CATEGORY = 0;
static final int HEADER_TYPE_NORMAL = 1;
private static final int HEADER_TYPE_COUNT = HEADER_TYPE_NORMAL + 1;
private static class HeaderViewHolder {
ImageView icon;
TextView title;
TextView summary;
}
private LayoutInflater mInflater;
static int getHeaderType(Header header) {
if (header.fragment == null && header.intent == null) {
return HEADER_TYPE_CATEGORY;
} else {
return HEADER_TYPE_NORMAL;
}
}
@Override
public int getItemViewType(int position) {
Header header = getItem(position);
return getHeaderType(header);
}
@Override
public boolean areAllItemsEnabled() {
return false; // because of categories
}
@Override
public boolean isEnabled(int position) {
return getItemViewType(position) != HEADER_TYPE_CATEGORY;
}
@Override
public int getViewTypeCount() {
return HEADER_TYPE_COUNT;
}
@Override
public boolean hasStableIds() {
return true;
}
public HeaderAdapter(Context context, List<Header> objects) {
super(context, 0, objects);
mInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
HeaderViewHolder holder;
Header header = getItem(position);
int headerType = getHeaderType(header);
View view = null;
if (convertView == null) {
holder = new HeaderViewHolder();
switch (headerType) {
case HEADER_TYPE_CATEGORY:
view = new TextView(getContext(), null,
android.R.attr.listSeparatorTextViewStyle);
holder.title = (TextView) view;
break;
case HEADER_TYPE_NORMAL:
view = mInflater.inflate(R.layout.preference_header_item,
parent, false);
holder.icon = (ImageView) view.findViewById(R.id.icon);
holder.title = (TextView) view
.findViewById(android.R.id.title);
holder.summary = (TextView) view
.findViewById(android.R.id.summary);
break;
}
view.setTag(holder);
} else {
view = convertView;
holder = (HeaderViewHolder) view.getTag();
}
// All view fields must be updated every time, because the view may
// be recycled
switch (headerType) {
case HEADER_TYPE_CATEGORY:
holder.title.setText(header.getTitle(getContext()
.getResources()));
break;
case HEADER_TYPE_NORMAL:
holder.icon.setImageResource(header.iconRes);
holder.title.setText(header.getTitle(getContext()
.getResources()));
CharSequence summary = header.getSummary(getContext()
.getResources());
if (!TextUtils.isEmpty(summary)) {
holder.summary.setVisibility(View.VISIBLE);
holder.summary.setText(summary);
} else {
holder.summary.setVisibility(View.GONE);
}
break;
}
return view;
}
}
Con todo este código en su lugar, crear encabezados es simplemente:
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android" >
<header android:title="atitle" />
</preference-headers>
Espero que esto ayude a alguien. Sé que me llevó algo de tiempo trabajar correctamente.
Parece que la mejor solución es la creación de tres bloques de código diferentes: uno para pre-Honeycomb, uno para post-Honeycomb y otro para tabletas.
El uso de encabezados preferenciales es efectivo solo en tabletas, por lo que permanecen solo en tabletas. No se utiliza agrupación aquí.
Los encabezados de Preferencia en post-Honeycomb son un poco inútiles, por lo que lo mejor es el uso de la PreferenceScreen
típica en un PreferenceFragment
. Los grupos se pueden hacer fácilmente por PreferenceCategory
.
Y, finalmente, para Pre-Honeycomb, la forma obsoleta sin usar PrefrenceFragment
es la única.
Lamentablemente, hay mucha duplicación de código, pero la biblioteca UnifiedPreference
mencionada en la respuesta de Leandros tiene errores: ignora PreferenceFragment
completo, por lo que es inútil (al menos para mí).