Android N Settings实战开发(1)一,二级界面增加

来源:互联网 发布:.top域名为什么便宜 编辑:程序博客网 时间:2024/06/13 21:36

Android N Settings实战开发(1)一,二级界面增加

首先我相信来看 这篇文章的人可能是从L,M版本过度到N版本的。N版本的Settings确实发生了不小的变化,本系列关于Settings的文章,不只是针对从L,M版本过度到N版本的同学,同时也是针对从N版本作为起点的同学们。

备注:本文会从如何照葫芦画瓢到原理剖析去分两面解释

一:增加一级目录

进入settings界面我们会发现N版本的界面如下
这里写图片描述
首先介绍如何增加一级目录:
其实想想就会发现,一级目录的增加应该很简单,毕竟谷歌面对众多层次不同的同学

实现之前介绍下
Settings的AndrdoidManifest

前面一些权限,就不过多介绍了。

        <activity android:name=".Settings$WirelessSettings"            android:label="@string/header_category_wireless_networks">            <intent-filter android:priority="4">                <action android:name="com.android.settings.category.wireless" />                <category android:name="android.intent.category.DEFAULT" />            </intent-filter>        </activity>        <activity android:name=".Settings$DeviceSettings"            android:label="@string/header_category_device">            <intent-filter android:priority="3">                <action android:name="com.android.settings.category.device" />                <category android:name="android.intent.category.DEFAULT" />            </intent-filter>        </activity>        <activity android:name=".Settings$PersonalSettings"            android:label="@string/header_category_personal">            <intent-filter android:priority="2">                <action android:name="com.android.settings.category.personal" />                <category android:name="android.intent.category.DEFAULT" />            </intent-filter>        </activity>        <activity android:name=".SystemSettings"            android:label="@string/header_category_system">            <intent-filter android:priority="1">                <action android:name="com.android.settings.category.system" />                <category android:name="android.intent.category.DEFAULT" />            </intent-filter>        </activity>

首先能够找到四个注册的Activity
分别是

   .Settings$WirelessSettings   .Settings$DeviceSettings   .Settings$PersonalSettings    .SystemSettings

$符号表示WirelessSettings是Settings的内部类


\alps\packages\apps\Settings\src\com\android\settings目录下的Settings.java中能看到这四大模块内部类的设置

    // Categories.    public static class WirelessSettings extends SettingsActivity { /* empty */ }    public static class DeviceSettings extends SettingsActivity { /* empty */ }    public static class PersonalSettings extends SettingsActivity { /* empty */ }    public static class SystemSettings extends SettingsActivity { /* empty */ }

四个类分别对应四大模块(无线设置,设备设置,个人设置,系统设置)
备注:其实应该是五大模块还有个模块是suggestion模块
priority=”n” 数字n代表优先级n的数字越靠大越靠前,在修改四大模块的优先级之后,可以mmm模块编译然后adb install -r +安装包,安装到真机中观察下效果(亲测位置确实会变化)

(坑1)提前埋下一个坑,四大类的每个小模块之间的顺序是否是也是按照优先级排列的呢?模块编译到手机里顺序是否会变化呢?

看完模块的Activity是怎么在AndroidManifest中注册的之后,我们看下四大门派中各个堂口是怎么设置的。我们知道我们在实现一个对用户功能界面的时候,有两种实现方式分别是Activity和Fragment。

1)一级目录菜单—–Acitivity

Activity的界面加在以及菜单中是最简单    
  <activity android:name=".fuzhu.ThreeScreenShotActivity"                android:taskAffinity=""                android:label="@string/fuzhu_fuction"                android:icon="@drawable/ic_settings_three_screenshot"                >            <intent-filter android:priority="1">                <action android:name="android.settings.THREESHOT" />                <action android:name="com.android.settings.THREESHOT" />                <category android:name="android.intent.category.DEFAULT" />            </intent-filter>            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.DEFAULT" />                <category android:name="android.intent.category.VOICE_LAUNCH" />                <category android:name="com.android.settings.SHORTCUT" />            </intent-filter>            <intent-filter android:priority="9">                <action android:name="com.android.settings.action.SETTINGS" />            </intent-filter>            <meta-data android:name="com.android.settings.category"                android:value="com.android.settings.category.personal" />            <meta-data android:name="com.android.settings.ACTIVITY_ACTION"                android:value="com.android.settings.fuzhu.ThreeScreenShot" />            <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"                android:value="true" />        </activity>   

AndroidManifest中ThreeScreenShotActivity注册如上。
直接在\packages\apps\Settings\src\com\android\settings\fuzhu
中加入ThreeScreenShotActivity.class实现类就可以了。

<intent-filter android:priority="9">

代表这个小模块在Settings-personal中的位置关系(数字越大越靠前)
(填坑1):在尝试修改priority=”9”会发现,mmm模块编译安装到手机之后发现位置没有改变啊。这时候可能很多读者在想又是一个瞎B说不负责任的博猪。其实这个priority=”9”的判断是在frameworks中进行处理的,所以只有编译frameworks之后才会生效。

2)一级目录菜单—–Fragment

如果是用Fragment去实现的话分如下几步(比大象放冰箱麻烦一丢丢)
a:AndroidManifest注册

<activity android:name="Settings$ThreeScreenShotActivity"                android:taskAffinity=""                android:label="@string/fuzhu_fuction"                android:icon="@drawable/ic_settings_three_screenshot"                >            <intent-filter android:priority="1">                <action android:name="android.settings.THREESHOT" />                <action android:name="com.android.settings.THREESHOT" />                <category android:name="android.intent.category.DEFAULT" />            </intent-filter>            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.DEFAULT" />                <category android:name="android.intent.category.VOICE_LAUNCH" />                <category android:name="com.android.settings.SHORTCUT" />            </intent-filter>            <intent-filter android:priority="9">                <action android:name="com.android.settings.action.SETTINGS" />            </intent-filter>            <meta-data android:name="com.android.settings.category"                android:value="com.android.settings.category.personal" />            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"                android:value="com.android.settings.fuzhu.ThreeScreenShot" />            <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"                android:value="true" />        </activity> 

b:实现Fragment,实现Settings的SettingsPreferenceFragment

public class ThreeScreenShot extends SettingsPreferenceFragment implements SwitchBar.OnSwitchChangeListener{}

c:Settings增加空实现静态类

  public static class ThreeScreenShotActivity extends SettingsActivity { /* empty */ }

d:SettingsActivity中加入如下代码:
原因如下:ThreeScreenShotActivity并不是一个Activity文件,只是一个SettingsActivity的子类,且是空实现。之所以要加此空的Activity,是为了外部应用能直接跳转到ThreeScreenShotActivity界面,因为如果只是fragment的话,外部是没法跳转到fragment界面的,跳转到ThreeScreenShotActivity时,会执行其父类SettingsActivity.java中的方法,并根据ThreeScreenShotActivity在清单文件中的注册信息,它的meta-data的值,找到ThreeScreenShotActivity对应的fragment(ThreeScreenShot),显示出fragment界面,实现借壳。
如果中使用的是FRAGMENT_CLASS,一般都会声明成Settings的内部类即 的形式。

private String[] SETTINGS_FOR_RESTRICTED = {     .....     Settings.ThreeScreenShotActivity.class.getName(),};private static final String[] ENTRY_FRAGMENTS = {    .....    ThreeScreenShot.class.getName(),}

e:支持AndroidN版本的Settings分屏
Fragment中重写getMetricsCategory()

   @Override  protected int getMetricsCategory() {       return MetricsEvent.ACTION_THREE_FINGERS_SCREENSHOT;    }

frameworks/base/proto/src/metrics_constants.proto加入字段ACTION_THREE_FINGERS_SCREENSHOT = 411;
实现效果如下:
这里写图片描述

第一篇N版本Settings更新完毕 后续还会继续更新,很感谢在写这篇博客的时候身边同事们的支持。