一、系统设置首页(一级菜单):
1、Settings
之所以要在此定义空的Activity,是为了外部应用能直接跳转到XX_SettingsActivity界面,因为如果只是fragment的话,外部是没法跳转到fragment界面的,跳转到XX_SettingsActivity时,会执行其父类SettingsActivity.java中的方法,并根据XX_SettingsActivity在清单文件中的注册信息, 它的meta-data的值,找到XX_SettingsActivity对应的fragment(XX_Settings),显示出fragment界面,实现借壳。
2、AndroidManifest.xml
Settings主界面Activity使用的是Settings.java,子界面Activity使用的是SubSettings.java,Settings与SubSetting中的内部类都是空Activity(没有重写七大生命周期方法),都继承于SettingsActivity.
从AndroidManifest.xml文件中得知主页面是.homepage.SettingsHomepageActivity。
以WifiSettings为例
3、SettingsHomepageActivity
①onCreate
②showFragment
封装方法中进行了加载fragment的实现
4、TopLevelSettings
TopLevelSettings继承自抽象类DashboardFragment, 实现抽象方法getPreferenceScreenResId()并返回preference的配置文件即可完成静态配置。
TopLevelSettings类中还有一个比较重要的就是在onAttach()方法中调用了父类DashboardFragment的onAttach()方法,这个方法主要是加载preference controllers。
5、top_level_settings.xml
主标签是一个<PreferenceScreen>标签,里有多个<Preference>标签。每个<Preference>标签对应设置首页的每一个设置项。
key | 配置项的主键 |
title | 配置项的标题 |
summary | 要标题下面的文字 |
icon | 前面的图标 |
order | 用来做排序的,值越小则排行越靠前 |
fragment | 点击该item要跳转的界面 |
controller | 该item的控制器,控制它的内容展示,是否可用,也可以控制它的点击事件等。 |
5、DashboardFragment
①onCreatePreferences
②refreshAllPreferences
③displayResourceTiles
addPreferencesFromResource方法是将preferenceScreen下所有Preference添加到ArrayList中,然后再根据此集合构建生成PreferenceGroupAdapter,最后将此adapter设置到listview中,完成数据绑定,从而完成界面加载。
④refreshDashboardTiles
⑤onAttach
@Override public 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 //从 xml 定义加载首选项控制器 final List<BasePreferenceController> controllersFromXml = PreferenceControllerListHelper .getPreferenceControllersFromXml(context, getPreferenceScreenResId()); // Filter xml-based controllers in case a similar controller is created from code already. //过滤基于 xml 的控制器,以防已经从代码创建了类似的控制器。 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. //为 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); } }
二、系统设置二级菜单实现
1、SubSettings
系统设置的二级菜单界面Activity是SubSettings类,SubSettings类虽然是一个Activity但是它是一个空的Activity,它不继承Activity7大生命周期。
2、SettingsActivity
①onCreate
布局文件:settings_main_prefs
启动Fragment
②getMetaData
以WifiSettingsActivity为例
③getIntent
④getStartingFragmentClass
⑤launchSettingFragment
⑥switchToFragment
3、settings_main_prefs.xml
布局文件由<SwitchBar>和<FrameLayout>和<RelativeLayout>标签组成,<RelativeLayout>标签默认是隐藏的。根据<FrameLayout>标签的id可以判断这个标签就是二级菜单栏的主界面内容。