En su mayor parte, la adición de los resúmenes de preferencias es relativamente sencillo, ya que implica sólo añadir el android:summary
atributo a la preferencia respectiva con el recurso de cadena apropiado. Sin embargo, si los subtítulos deben actualizarse dinámicamente, es posible que sea necesario un controlador de preferencias personalizado.
Subtítulos estáticos
Para agregar un subtítulo estático a una preferencia:
- Añadir el
android:summary
atributo a la preferencia. Por ejemplo, para agregar un resumen de preferencia la pantalla L0 configuración, añadir algo como lo siguiente a la preferencia de los atributos:android:summary="@string/display_settings_summary"
Por ejemplo, considere este ejemplo de código de preferencia completo:
<Preference android:fragment="com.android.car.settings.display.DisplaySettingsFragment" android:icon="@drawable/ic_settings_display" android:key="@string/pk_display_settings_entry" android:title="@string/display_settings" android:summary="@string/display_settings_summary" settings:controller="com.android.car.settings.common.DefaultRestrictionsPreferenceController"/>
Subtítulos dinámicos
Subtítulos especificados con el android:summary
de atributos son estáticos por lo que no se puede actualizar la base de ciertas condiciones. Para subtítulos dinámicos, debe modificar el controlador de preferencias para la preferencia. El siguiente ejemplo modifica la preferencia de ubicación L0 para tener un subtítulo que especifica si la ubicación está activada o desactivada y, si está activada, indica cuántas aplicaciones tienen actualmente acceso a la ubicación.
- Definir las nuevas cadenas:
<!-- Summary for Location settings when location is off [CHAR LIMIT=NONE] --> <string name="location_settings_summary_location_off">Off</string> <!-- Summary for Location settings when location is on, explaining how many apps have location permission [CHAR LIMIT=NONE]--> <plurals name="location_settings_summary_location_on"> <item quantity="one">On - <xliff:g id="count">%1$d</xliff:g> app has access to location</item> <item quantity="other">On - <xliff:g id="count">%1$d</xliff:g> apps have access to location</item> </plurals> <!-- Location settings, loading the number of apps which have location permission [CHAR LIMIT=30] --> <string name="location_settings_loading_app_permission_stats">Loading\u2026</string>
- Crear un nuevo PreferenceController,
LocationEntryPreferenceController
, para configurar y cambiar el texto resumen de la ubicación de preferencia de forma dinámica:public class LocationEntryPreferenceController extends PreferenceController<Preference> { private static final Logger LOG = new Logger(LocationEntryPreferenceController.class); private static final IntentFilter INTENT_FILTER_LOCATION_MODE_CHANGED = new IntentFilter(LocationManager.MODE_CHANGED_ACTION); private final Context mContext; private final LocationManager mLocationManager; /** Total number of apps that have location permissions. */ private int mNumTotal = -1; private int mNumTotalLoading = 0; private AtomicInteger mLoadingInProgress = new AtomicInteger(0); private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { refreshUi(); } }; public LocationEntryPreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions) { super(context, preferenceKey, fragmentController, uxRestrictions); mContext = context; mLocationManager = (LocationManager) getContext().getSystemService( Service.LOCATION_SERVICE); } @Override protected Class<Preference> getPreferenceType() { return Preference.class; } @Override protected void onStartInternal() { getContext().registerReceiver(mReceiver, INTENT_FILTER_LOCATION_MODE_CHANGED); } @Override protected void onStopInternal() { getContext().unregisterReceiver(mReceiver); } @Override protected void updateState(Preference preference) { super.updateState(preference); updateSummary(preference); if (!mLocationManager.isLocationEnabled() || mLoadingInProgress.get() != 0) { return; } mNumTotalLoading = 0; // Retrieve a list of users inside the current user profile group. List<UserHandle> users = mContext.getSystemService( UserManager.class).getUserProfiles(); mLoadingInProgress.set(users.size()); for (UserHandle user : users) { Context userContext = createPackageContextAsUser(mContext, user.getIdentifier()); if (userContext == null) { if (mLoadingInProgress.decrementAndGet() == 0) { setLocationAppCount(preference, mNumTotalLoading); } continue; } PermissionControllerManager permController = userContext.getSystemService(PermissionControllerManager.class); permController.countPermissionApps( Arrays.asList(ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION), PermissionControllerManager.COUNT_ONLY_WHEN_GRANTED, (numApps) -> { mNumTotalLoading += numApps; if (mLoadingInProgress.decrementAndGet() == 0) { setLocationAppCount(preference, mNumTotalLoading); } }, null); } } @VisibleForTesting void setLocationAppCount(Preference preference, int numApps) { mNumTotal = numApps; updateSummary(preference); } private void updateSummary(Preference preference) { String summary = ""; if (mLocationManager.isLocationEnabled()) { if (mNumTotal == -1) { summary = mContext.getString(R.string.location_settings_loading_app_permission_stats); } else { summary = mContext.getResources().getQuantityString( R.plurals.location_settings_summary_location_on, mNumTotal, mNumTotal); } } else { summary = mContext.getString(R.string.location_settings_summary_location_off); } preference.setSummary(summary); } private Context createPackageContextAsUser(Context context, int userId) { try { return context.createPackageContextAsUser( context.getPackageName(), 0 /* flags */, UserHandle.of(userId)); } catch (PackageManager.NameNotFoundException e) { LOG.e("Failed to create user context", e); } return null; } }
Para este controlador de muestra:
- Si la ubicación está desactivada, texto del resumen se establece en el
location_settings_summary_location_off
cadena. - Si la ubicación está habilitada, se agrega la cantidad de aplicaciones que tienen permiso de ubicación. Si bien se trata de cargar, la
location_settings_loading_app_permission_stats
se muestra cadena. Cuando se cargan los datos, el controlador establece el resumen allocation_settings_summary_location_on
cadena con el número de aplicaciones con acceso especificados. - Cuando se inicia el controlador de preferencias, el controlador registra un receptor y actualiza el estado de preferencias cuando cambia el estado de ubicación.
- Si la ubicación está desactivada, texto del resumen se establece en el
- Modificar el archivo XML fragmento para unir el nuevo controlador a la preferencia relevante:
<Preference android:fragment="com.android.car.settings.location.LocationSettingsFragment" android:icon="@drawable/ic_settings_location" android:key="@string/pk_location_settings_entry" android:title="@string/location_settings_title" settings:controller="com.android.car.settings.location.LocationEntryPreferenceController"/>