Settings中主界面加载流程(一级菜单)
1 SettingsHomepageActivity
在这个之中的onCreate方法有
showFragment(new TopLevelSettings(), R.id.main_content);
启动了TopLevelSettings这个类,此类又是继承于DashboardFragment。先去查看它本身的构造方法。
2 TopLevelSettings
public TopLevelSettings() { final Bundle args = new Bundle(); // Disable the search icon because this page uses a full search view in
actionbar. args.putBoolean(NEED_SEARCH_ICON_IN_ACTION_BAR, false); setArguments(args);}
可以看到通过构造方法传递了一个参数,从注释中可以看出,该参数的用意是由于主界面使用完整的搜索视图所以在主界面的actionbar中隐藏了搜索图标。然后再根据framgments生命周期先来看onAttach()方法:。然后再去查看该类中的onAttach方法。
@Overridepublic void onAttach(Context context) { super.onAttach(context); use(SupportPreferenceController.class).setActivity(getActivity());}
它因为是继承DashboardFragment,我去看该父类的onAttach方法。
3 DashboardFragment
@Overridepublic void onAttach(Context context) { super.onAttach(context); mSuppressInjectedTileKeys =
Arrays.asList(context.getResources().getStringArray( R.array.config_suppress_injected_tile_keys)); mDashboardFeatureProvider = FeatureFactory.getFactory(context). getDashboardFeatureProvider(context); // Load preference controllers from code final List<AbstractPreferenceController> controllersFromCode = createPreferenceControllers(context); // Load preference controllers from xml definition final List<BasePreferenceController> controllersFromXml =
PreferenceControllerListHelper .getPreferenceControllersFromXml(context, getPreferenceScreenResId()); // Filter xml-based controllers in case a similar controller is created from
code already. final List<BasePreferenceController> uniqueControllerFromXml = PreferenceControllerListHelper.filterControllers( controllersFromXml, controllersFromCode); // Add unique controllers to list. if (controllersFromCode != null) { mControllers.addAll(controllersFromCode); } mControllers.addAll(uniqueControllerFromXml); // And wire up with lifecycle. final Lifecycle lifecycle = getSettingsLifecycle(); uniqueControllerFromXml.forEach(controller -> { if (controller instanceof LifecycleObserver) { lifecycle.addObserver((LifecycleObserver) controller); } }); // Set metrics category for BasePreferenceController. final int metricCategory = getMetricsCategory(); mControllers.forEach(controller -> { if (controller instanceof BasePreferenceController) { ((BasePreferenceController)
controller).setMetricsCategory(metricCategory); } }); mPlaceholderPreferenceController = new DashboardTilePlaceholderPreferenceController(context); mControllers.add(mPlaceholderPreferenceController); for (AbstractPreferenceController controller : mControllers) { addPreferenceController(controller); }}
通过方法注释可以知道该方法主要是完成preference controllers的加载。再去看该类的oncreate方法。
在这里有一个mDashboardFeatureProvider,它提供的数据就是一级菜单这些
@Overridepublic void onCreate(Bundle icicle) { super.onCreate(icicle); // Set ComparisonCallback so we get better animation when list changes. getPreferenceManager().setPreferenceComparisonCallback( new PreferenceManager.SimplePreferenceComparisonCallback()); if (icicle != null) { // Upon rotation configuration change we need to update preference states
before any // editing dialog is recreated (that would happen before onResume is
called). updatePreferenceStates(); }}
可以通过注释看见,是设置ComparisonCallback,以便在列表获得更好的动画。
第一次进入时,icicle为null,根据log定位发现,其后调用DashboardFragment.java的onCreatePrefern方法(这个是我打印了log)
@Overridepublic void onCreatePreferences(Bundle savedInstanceState, String rootKey) { Log.d("wuzhangxiao", "wuzhangxiao onCreatePreferences"); checkUiBlocker(mControllers); refreshAllPreferences(getLogTag()); mControllers.stream() .map(controller -> (Preference)
findPreference(controller.getPreferenceKey())) .filter(Objects::nonNull) .forEach(preference -> { // Give all controllers a chance to handle click. /** * 给所有控制器一个处理点击的机会。 */ preference.getExtras().putInt(CATEGORY, getMetricsCategory()); });}
这个里面给所有的菜单点击事件,再去查看refreshAllPreferences方法。
/** * Refresh all preference items, including both static prefs from xml, and dynamic
items from * DashboardCategory. * 刷新所有首选项,包括来自 xml 的静态首选项和来自 DashboardCategory 的动态项目。 */
private void refreshAllPreferences(final String tag) { final PreferenceScreen screen = getPreferenceScreen(); // First remove old preferences. /** * 首先删除旧的偏好。 */ if (screen != null) { // Intentionally do not cache PreferenceScreen because it will be recreated
later. /** * 有意不要缓存 PreferenceScreen,因为稍后会重新创建它。 */ screen.removeAll(); } // Add resource based tiles. /** * 添加基于资源的图块。 */ displayResourceTiles(); refreshDashboardTiles(tag); final Activity activity = getActivity(); if (activity != null) { Log.d(tag, "All preferences added, reporting fully drawn"); activity.reportFullyDrawn(); } updatePreferenceVisibility(mPreferenceControllers);}
刷新所有preference items,包括来自xml的静态preference和来自DashboardCategory的动态preference,静态xml定义的prefs(调用displayResourceTiles()方法),动态DashboardCategory动态加载(调用refreshDashboardTiles(TAG)方法,其中TAG为 “TopLevelSettings”)。displayResourceTiles():此方法主要是从xml资源文件中加载显示prefs
再去查看该方法调用了一个方法。displayResourceTiles,此方法主要从xml资源文件中加载prefs。
/** * Displays resource based tiles. * 显示基于资源的图块。 */
private void displayResourceTiles() { final int resId = getPreferenceScreenResId(); if (resId <= 0) { return; } addPreferencesFromResource(resId); final PreferenceScreen screen = getPreferenceScreen(); screen.setOnExpandButtonClickListener(this); displayResourceTilesToScreen(screen);}
我去查看getPreferenceScreenResId,我又发现它这个方法是
@Overrideprotected abstract int getPreferenceScreenResId();
它又由TopLevelSettings继承,该类肯定会去实现
TopLevelSettings
`@Overrideprotected int getPreferenceScreenResId() { return R.xml.top_level_settings;}
`布局就开始去显示了。 但是在这里我有个疑问,因为在这个布局中有着许多的菜单,但是没有显示完全,肯定还有别的方式进行显示。再回去看displayResourceTiles