您的位置:首页 > 移动开发 > Android开发

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

2017-11-27 15:06 323 查看

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更新完毕 后续还会继续更新,很感谢在写这篇博客的时候身边同事们的支持。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: