Settings菜单项点击事件解析
问题:每个一级菜单项和二级菜单项的触发跳转的点击事件在哪里呢?
支持跳转进下一层的菜单项(包括一级菜单项和二级菜单项),他们都会有一个对应controller。而这个controller都是extends BasePreferenceController,他们可以重写handlePreferenceTreeClick()这个方法类似于来控制是否放行跳转进入下一个菜单项的。
同理,他们若有fragment,framgnet也都是extends DashboardFragment,他们可以重写onPreferenceTreeClick(),这个方法即是不论是一级菜单项页面也还还是二级菜单项页面也好,还是三级…,点击某个菜单项后进入的点击事件的处理方法了!
public abstract class DashboardFragment {
@Override
public boolean onPreferenceTreeClick(Preference preference) {
//所有的一级菜单项本来是在TopLevelSettings.java加载。但是TopLevelSettings.java没有重写onPreferenceTreeClick,
//所以正在起作用的为父类DashboardFragment.java的onPreferenceTreeClick,onPreferenceTreeClick的作用是加载所有
//一级菜单项对应的controller控制器,然后遍历得到每个一级菜单项的controller控制器,每个控制器都会执行controller.handlePreferenceTreeClick(preference)
//表示比如你点击的是“关于手机”android:key="top_level_about_device"的preference,那么就是TopLevelAboutDevicePreferenceController.handlePreferenceTreeClick(preference(关于手机的preference))
//是否返回true要看TopLevelAboutDevicePreferenceController重写的handlePreferenceTreeClick()逻辑,若handlePreferenceTreeClick的逻辑重写了允许跳转的条件,没达到就是不允许跳转进入下一层菜单项。
//没有重写就是走到BasePreferenceController的handlePreferenceTreeClick(){ 里面执行的内容为new SubSettingLauncher(preference.getContext().....,大概意思应该是表示去创建了一个子启动器来做响应逻辑}
Log.d("DashboardFragment",preference.getKey());
final Collection<List<AbstractPreferenceController>> controllers =
mPreferenceControllers.values();
for (List<AbstractPreferenceController> controllerList : controllers) {
for (AbstractPreferenceController controller : controllerList) {
if (controller.handlePreferenceTreeClick(preference)) {
// log here since calling super.onPreferenceTreeClick will be skipped
writePreferenceClickMetric(preference);
return true;
}
}
}
return super.onPreferenceTreeClick(preference);
}
}
通过打log日志中查看输出:
我们点击一级菜单项”关于手机” 输出以下日志,发现DashboradFragment和BasePreferenceController的xxxPreferenceTreeClick都是得到了执行 (提前在java类里面写上Log.d()日志,这里就不演示了)
我们点击了”关于手机”里面的”软件版本、急救信息、法律信息”等二级菜单项,结果看到了以下日志输出
DashboradFragment的onPreferenceTreeClick是得到了执行,BasePreferenceController的handlePreferenceTreeClick()也是得到了执行,然后会遍历到同层级的所有controller,若这些controller重写了handlePreferenceTreeClick(),那么也会得到执行,所以日志的输出结果如下所示
比如我们点击"急救信息",会出现"软件版本"的菜单项对应类的handlePreferenceTreeClick的输出:
点击"软件版本",也会执行其他同级菜单项controller的handkexxxxclick()方法:
总结:
- 具体的菜单项点击事件发生后执行的业务逻辑,就要看你直接或间接继承DashboardFragment后的类,然后重写的onPreferenceTreeClick做了什么了
- 当然这个业务逻辑也可以放到Fragment对应的Controller控制器的handlePreferenceTreeClick()方法中(因为会执行到这个地方),如果要修改的Fragment没有对应的Controller,可以自己选择新建添加一个给它。