* Base fragment for dashboard style UI containing a list of static and dynamic setting items.
*/
public abstract class DashboardFragment extends SettingsPreferenceFragment
implements SettingsDrawerActivity.CategoryListener, Indexable,
SummaryLoader.SummaryConsumer {
private static final String TAG = "DashboardFragment";
private final Map<Class, PreferenceController> mPreferenceControllers =
new ArrayMap<>();
private final Set<String> mDashboardTilePrefKeys = new ArraySet<>();
protected ProgressiveDisclosureMixin mProgressiveDisclosureMixin;
protected DashboardFeatureProvider mDashboardFeatureProvider;
private DashboardTilePlaceholderPreferenceController mPlaceholderPreferenceController;
private boolean mListeningToCategoryChange;
private SummaryLoader mSummaryLoader;
@Override
public void onAttach(Context context) {
super.onAttach(context);
mDashboardFeatureProvider =
FeatureFactory.getFactory(context).getDashboardFeatureProvider(context);
mProgressiveDisclosureMixin = mDashboardFeatureProvider
.getProgressiveDisclosureMixin(context, this, getArguments());
getLifecycle().addObserver(mProgressiveDisclosureMixin);
List<PreferenceController> controllers = getPreferenceControllers(context);
if (controllers == null) {
controllers = new ArrayList<>();
}
mPlaceholderPreferenceController =
new DashboardTilePlaceholderPreferenceController(context);
controllers.add(mPlaceholderPreferenceController);
for (PreferenceController controller : controllers) {
addPreferenceController(controller);
}
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
getPreferenceManager().setPreferenceComparisonCallback(
new PreferenceManager.SimplePreferenceComparisonCallback());
}
@Override
public void onCategoriesChanged() {
final DashboardCategory category =
mDashboardFeatureProvider.getTilesForCategory(getCategoryKey());
if (category == null) {
return;
}
refreshDashboardTiles(getLogTag());
}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
super.onCreatePreferences(savedInstanceState, rootKey);
refreshAllPreferences(getLogTag());
}
* 更新所有的Preference项, 包含从xml中加载的固定选项和从DashboardCategory中动态加载的选项。
*/
private void refreshAllPreferences(final String TAG) {
if (getPreferenceScreen() != null) {
getPreferenceScreen().removeAll();
}
displayResourceTiles();
mProgressiveDisclosureMixin.collapse(getPreferenceScreen());
refreshDashboardTiles(TAG);
}
@Override
public void onStart() {
super.onStart();
final DashboardCategory category =
mDashboardFeatureProvider.getTilesForCategory(getCategoryKey());
if (category == null) {
return;
}
if (mSummaryLoader != null) {
mSummaryLoader.setListening(true);
}
final Activity activity = getActivity();
if (activity instanceof SettingsDrawerActivity) {
mListeningToCategoryChange = true;
((SettingsDrawerActivity) activity).addCategoryListener(this);
}
}
@Override
public void notifySummaryChanged(Tile tile) {
final String key = mDashboardFeatureProvider.getDashboardKeyForTile(tile);
final Preference pref = mProgressiveDisclosureMixin.findPreference(
getPreferenceScreen(), key);
pref.setSummary(tile.summary);
}
@Override
public void onResume() {
super.onResume();
updatePreferenceStates();
}
* Update state of each preference managed by PreferenceController.
*/
protected void updatePreferenceStates() {
Collection<PreferenceController> controllers = mPreferenceControllers.values();
final PreferenceScreen screen = getPreferenceScreen();
for (PreferenceController controller : controllers) {
if (!controller.isAvailable()) {
continue;
}
final String key = controller.getPreferenceKey();
final Preference preference = mProgressiveDisclosureMixin.findPreference(screen, key);
controller.updateState(preference);
}
}
@Override
public boolean onPreferenceTreeClick(Preference preference) {
Collection<PreferenceController> controllers = mPreferenceControllers.values();
mMetricsFeatureProvider.logDashboardStartIntent(
getContext(), preference.getIntent(), getMetricsCategory());
for (PreferenceController controller : controllers) {
if (controller.handlePreferenceTreeClick(preference)) {
return true;
}
}
return super.onPreferenceTreeClick(preference);
}
@Override
public void onStop() {
super.onStop();
if (mSummaryLoader != null) {
mSummaryLoader.setListening(false);
}
if (mListeningToCategoryChange) {
final Activity activity = getActivity();
if (activity instanceof SettingsDrawerActivity) {
((SettingsDrawerActivity) activity).remCategoryListener(this);
}
mListeningToCategoryChange = false;
}
}
protected <T extends PreferenceController> T getPreferenceController(Class<T> clazz) {
PreferenceController controller = mPreferenceControllers.get(clazz);
return (T) controller;
}
protected void addPreferenceController(PreferenceController controller) {
mPreferenceControllers.put(controller.getClass(), controller);
}
* 获取PreferenceScreen的资源Id,由子类实现
*/
protected abstract int getPreferenceScreenResId();
* 获取PreferenceController列表,由子类实现
*/
protected abstract List<PreferenceController> getPreferenceControllers(Context context);
* 是否显示Tile,默认为true
*/
protected boolean displayTile(Tile tile) {
return true;
}
* 显示ResourceTile,从ScreenResId中加载PreferenceScreen
*/
private void displayResourceTiles() {
final int resId = getPreferenceScreenResId();
if (resId <= 0) {
return;
}
addPreferencesFromResource(resId);
final PreferenceScreen screen = getPreferenceScreen();
Collection<PreferenceController> controllers = mPreferenceControllers.values();
for (PreferenceController controller : controllers) {
controller.displayPreference(screen);
}
}
* 更新由DashboardCategory管理支撑的Preference
*/
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
void refreshDashboardTiles(final String TAG) {
final PreferenceScreen screen = getPreferenceScreen();
final DashboardCategory category =
mDashboardFeatureProvider.getTilesForCategory(getCategoryKey());
if (category == null) {
Log.d(TAG, "NO dashboard tiles for " + TAG);
return;
}
List<Tile> tiles = category.tiles;
if (tiles == null) {
return;
}
final List<String> remove = new ArrayList<>(mDashboardTilePrefKeys);
if (mSummaryLoader != null) {
mSummaryLoader.release();
}
final Context context = getContext();
mSummaryLoader = new SummaryLoader(getActivity(), getCategoryKey());
mSummaryLoader.setSummaryConsumer(this);
final TypedArray a = context.obtainStyledAttributes(new int[]{
android.R.attr.colorControlNormal});
final int tintColor = a.getColor(0, context.getColor(android.R.color.white));
a.recycle();
final String pkgName = context.getPackageName();
for (Tile tile : tiles) {
final String key = mDashboardFeatureProvider.getDashboardKeyForTile(tile);
if (TextUtils.isEmpty(key)) {
continue;
}
if (!displayTile(tile)) {
continue;
}
if (pkgName != null && tile.intent != null
&& !pkgName.equals(tile.intent.getComponent().getPackageName())) {
tile.icon.setTint(tintColor);
}
if (mDashboardTilePrefKeys.contains(key)) {
final Preference preference = mProgressiveDisclosureMixin.findPreference(
screen, key);
mDashboardFeatureProvider.bindPreferenceToTile(getActivity(), getMetricsCategory(),
preference, tile, key, mPlaceholderPreferenceController.getOrder());
} else {
final Preference pref = new Preference(getPrefContext());
mDashboardFeatureProvider.bindPreferenceToTile(getActivity(), getMetricsCategory(),
pref, tile, key, mPlaceholderPreferenceController.getOrder());
mProgressiveDisclosureMixin.addPreference(screen, pref);
mDashboardTilePrefKeys.add(key);
}
remove.remove(key);
}
for (String key : remove) {
mDashboardTilePrefKeys.remove(key);
mProgressiveDisclosureMixin.removePreference(screen, key);
}
mSummaryLoader.setListening(true);
}
}