En general, agregar resúmenes de preferencias es relativamente sencillo, ya que
Solo debes agregar el atributo android:summary
a la preferencia respectiva
con el recurso de cadenas adecuado. Sin embargo, si los subtítulos deben actualizarse de forma dinámica,
puede ser necesario un controlador de preferencias personalizado.
Subtítulos estáticos
Para agregar un subtítulo estático a una preferencia, haz lo siguiente:
- Agrega el atributo
android:summary
a la preferencia. Por ejemplo, para agregar un resumen a la preferencia de configuración de la pantalla L0, agrega algo como lo siguiente al de preferencias:android:summary="@string/display_settings_summary"
Por ejemplo, considera esta muestra de código de preferencia completa:
<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
Los subtítulos especificados con el atributo android:summary
son estáticos, por lo que no pueden hacerlo.
se actualicen
en función de ciertas condiciones. Para los subtítulos dinámicos, debes modificar la preferencia
de la preferencia. En el siguiente ejemplo, se modifica la preferencia de ubicación de L0 para
tener un subtítulo que especifique si la ubicación está activada o desactivada y, de ser así, indicar cuántas apps
tienen acceso a la ubicación en este momento.
- Define 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>
- Crea un nuevo PreferenceController,
LocationEntryPreferenceController
, en establecer y cambiar dinámicamente el texto del resumen de las preferencias de ubicación: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á inhabilitada, el texto de resumen se establece como
location_settings_summary_location_off
. - Si la ubicación está habilitada, se agrega la cantidad de apps que tienen permiso de ubicación. Mientras que
se está cargando la cadena
location_settings_loading_app_permission_stats
, que se muestra. Cuando se cargan los datos, el controlador establece el resumen en La cadenalocation_settings_summary_location_on
con la cantidad de apps con de acceso especificado. - Cuando se inicia el controlador de preferencias, el controlador registra un receptor y actualiza el estado de las preferencias cuando cambia el estado de la ubicación.
- Si la ubicación está inhabilitada, el texto de resumen se establece como
- Modifica el archivo XML del fragmento para conectar 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"/>