Settings的显示流程

        Settings的界面如下:

                                                                              

        你知道这些条目是怎么显示出来的, 点击某个条目又是进入到哪里了呢? 下面我们来分析分析。


        从AndroidManifest里可以看出,上面的页面对应的是Settings.java,我把它定义为主界面吧,我们来看看它的代码:

就是定义里了很多Activity,实现部分都是空的,父类帮它们实现了所有的功能。他们的父类都是SettingsActivity,Settings自己的父类也是SettingsActivity,

而SettingsActivity是继承SettingsDrawerActivity的。


        启动主界面自然会调用它的onCreate,没有!那自然就会调用它父类SettingsActivity的onCreate。上关键代码:

         


        getMetaData代码:

             注:public static final String META_DATA_KEY_FRAGMENT_CLASS = "com.android.settings.FRAGMENT_CLASS";

                        

        getMetaData就是从AndroidManifest里得到Activity定义的<meta-data 打头的信息,然后获得"com.android.settings.FRAGMENT_CLASS"的值。

对于主界面来说它没有定义"com.android.settings.FRAGMENT_CLASS"的值,那么mFragmentClass就是空的。继续上onCreate的代码:


       第一次进入到主界面时mIsShowingDashboard是等于true的,那么就会swtich到DashboardContainerFragment。上DashboardContainerFragment关键代码:

                 

        这里返回的是DashboardSummary。DashboardSummary里有一个FocusRecyclerView对象mDashboard,

Settings里的每个item就是显示在这个RecyclerView里的,我们稍后在研究这个RecyclerView。

DashboardSummary的onCrreate代码:

            

SettingsDrawerActivity的getDashboardCategories

TileUtils的getCategories:


        getTilesForAction里会调用getTilesForIntent,getTilesForIntent里会调用queryIntentActivitiesAsUser来查找符合条件的activity的<meta-data 信息。

这里的条件指的是:

                1)特定的包名。

                2)Activity的定义中,<intent-filter 有指定的<action参数。

        看看getTilesForIntent部分代码:

        在这个函数里,我加了打印,部分结果如下:

我来看看它对应activity的定义部分:


这里title的值还要说下,如果在<meta-data 里定义了“com.android.settings.title”,那title的值就是它对应的值。

如果没定义“com.android.settings.title”,title的值就是android:lable的值。

我们再回到TileUtils的getCategories里面,执行完getTilesForAction后的部分。createCategory就是创建一个大项,

这里就是创建了4个大项,分别是:Wireless & networks、Device、Personal和System。createCategory里有个List<Tile>链表,

存放的是它下面挂的Tile。比如Wireless&networks下挂的就是Wi-Fi、Bluetooth、Data usage和More。

TileUtils的getCategories的最后两次调用了Collections.sort,就是根据权重对大项和大项里的Tile进行排序,权重大的显示在前面。


到这里Setting里要显示的内容算是得到了,那是怎么显示在UI上的呢?我们继续研究。


来看ashboardSummary来的onViewCreated函数:

得到recycleView,设置它的Adapter,然后调用rebuildUI,接着都会调用mAdapter.setCategoriesAndSuggestions(categories, tiles),

setCategoriesAndSuggestions里会调用recountItems,recountItems的部分代码如下:

countItem表示的就是要显示前面解析出来的大项和大项里的tile,然后调用notifyDataSetChanged,那settints所有的内容就是显示出来了。

来看看DashboardAdapter的onBindViewHolder。

onBindCategory就是在相应的位置显示"Wireless&networks"、"Device"、"Personal"、“System“ 这几个字符串。

onBindTile就是显示如”Wireless&networks“下面的子项的:Wi-Fi、Bluetooth、Date usage、More。这里调用了setOnClickListerner,

那肯定就是我们按Enter键对应的代码了,后面再研究。


SettingsActivity的onCreate函数执行完后,会执行onStart函数,onStart里会执行updateTilesList,然后执行doUpdateTilesList。

doUpdateTilesList里调用了很多setTileEnabled,然后会进入到SettingsDrawerActivity的setTileEnabled。


        从两处代码可以看出,可以控制某个Item是否显示在UI上。举个栗子,如果我不想让Wi-Fi显示出来,就把下面高亮部分替换成false就行了。


SettingsDrawerActivity的setTileEnabled的最后调用了onCategoriesChanged。

个mCategoryListeners是在哪赋值的呢? 是在DashboardSummary的onStart里。这样就会调用DashboardSummary里的onCategoriesChanged。

onCategoriesChanged里直接调用了rebuildUI,相当于settings界面又刷新了一次。


Settings界面显示出来了,当我们进入到某个Item时是什么个流程呢?

之前说了DashboardAdapter的onBindViewHolder:

明显,我们要去看看DashboardAdapter的onClick。

会进入到第一个if里,调用SettingsDrawerActivity的openTitle。

这里的tile.intent我们前面已经得到了的,里面有ActivityInfo的packageName和name,这里就是打开对应的activity了。

比如我进入Display就是启动了Settings类里面的DisplaySettingsActivity。


这样我们又会调用SettingsActivity的onCreate。这次的流程就和第一次进入Settings界面有点不一样了。

这次mFragmentClass有值了,mIsShowingDashboard为false了!这次会得到当前activity对应的Fragment

(Display对应的就是”com.android.settings.DisplaySettings“),显示这个Fragment的内容。具体内容我没往下看,讲不出来,抱歉!

onCreate执行完之后,还是会调用doUpdateTilesList。最开始我很困惑,为什么每次进入到Item都会调用这个函数,

而且UI上显现的内容与这个函数里的控制的内容毫不关系呢。后来才知道只有Settings主界面对应的DashboardSummary

调用了addCategoryListener。也就是说doUpdateTilesList这次调用没鸟用。


  到此结束。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值