Android Settings 4.4 理解及修改

整体结构


Android 4.4系统的设置应用与常规的apk代码结构一致,没有后续android版本中各种新架构的复杂,即严格的activity界面逻辑与xml文件布局对应,每个功能页面都能比较轻松的找到对应的界面与布局代码。
  1. 入口
    按照常规的apk开发经验,我们可以从源码的AndroidManifest.xml文件里通过搜索android.intent.category.LAUNCHER关键字找到对应的主入口activity:
<activity android:name="Settings"
                android:label="@string/settings_label_launcher"
                android:taskAffinity="com.android.settings"
                android:launchMode="singleTask">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <action android:name="android.settings.SETTINGS" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
 打开Settings.java可以发现这正是一个activity逻辑代码,对应着点击设置应用打开的那个主界面,其继承PreferenceActivity,以列表形式展现子功能项,而整个页面的生成又几乎与一个普通列表的写法一样,因此不得不说4.4版本的设置在写法上极为友善。

2.主界面分析
对于常规activity界面,必然是去找xml布局来帮助理解,这里由于继承自PreferenceActivity自然通过搜索onBuildHeaders找到:

public void onBuildHeaders(List<Header> headers) {
        if (!onIsHidingHeaders()) {
            loadHeadersFromResource(R.xml.settings_headers, headers);
            updateHeaderList(headers);
        }
    }
其布局文件在res/下面找到settings_headers.xml,阅读其代码片可以发现其中每一项header正好与主界面列表项对应且标有注释。
而作为一个列表显示,这些header是每一项的数据,那么UI上是如何完成的呢,列表一般自然是通过构建Adapter来控制每一项的UI:
private static class HeaderAdapter extends ArrayAdapter<Header> {
        static final int HEADER_TYPE_CATEGORY = 0;
        static final int HEADER_TYPE_NORMAL = 1;
        static final int HEADER_TYPE_SWITCH = 2;
        static final int HEADER_TYPE_BUTTON = 3;
这里的HeaderAdapter编写的也比较容易理解,将子项的Ui显示分成几个类别,用switch case语句匹配各自的显示,具体可以阅读其中的getView方法。

3.点击事件
对于每一项Header,比如我点击wifi,页面就将跳转至wifi界面,这里由实现onHeaderClick方法进行:

public void onHeaderClick(Header header, int position) {
        boolean revert = false;
        if (header.id == R.id.account_add) {
            revert = true;
        }

        super.onHeaderClick(header, position);

        if (revert && mLastHeader != null) {
            highlightHeader((int) mLastHeader.id);
        } else {
            mLastHeader = header;
        }
    }
这里可以看到实际上就是回调了父类的onHeaderClick,而在父类PreferenceActivity的onHeaderClick里,逻辑会使用header的fragment信息通过startWithFragment生成子功能UI。

4.自定义修改-删除项
在日常工作中对于Settings的定制增加某个功能项,隐藏现有的某项较为常见,通过刚刚的内容可以知道主界面依照严格的activtiy与xml形式。
那么比如我要隐藏掉 打印 这个功能,直接在settings_headers.xml删除对应header会引起编译错误,设置visibility无效,因此比较好的做法是在Settings.java里通过逻辑代码来隐藏。
在updateHeaderList方法里可以阅读逻辑理解其对header列表数据的控制,那么删除某项就比较简单,仿照着写:

else if (id == R.id.date_time_settings) {
                target.remove(i);
            }

5.自定义修改-增加功能项
这里以之前做过的一个功能为例,即有个客户想在4.4系统上加一个自动开关机选项在设置里,那么这里只介绍如何加入一个空的功能界面:
首先设置的整个架构已有,参照其他子项的构成,自然是在settings_headers.xml中加入自定义功能header,以自动开关机为例:

<!-- Schedule Power -->
+    <header
+        android:id="@+id/schedule_power_settings"
+        android:fragment="com.android.settings.schedulePower.SchedulePowerSettings"
+        android:icon="@drawable/ic_settings_display"
+        android:title="@string/schedule_power_settings_title" />```

    这里一些string,icon资源就不具体位置了,这里的header就会被解析进入到Settings.java里的逻辑。
    为了统一,也仿照其他header,在Settings.java的SETTINGS_FOR_RESTRICTED数组里加入:
  • R.id.schedule_power_settings,
    继而只缺对应的fragment,同样仿照其他header对应的文件,如果不知道怎么写,甚至可以复制其代码,改下名字,删掉所有实现与私有方法,就得到了一个干净的仿照fragment。
    我这里即创建SchedulePowerSettings.java

public class SchedulePowerSettings extends PreferenceFragment{
“`
然后编写布局文件,UI,逻辑实现,和写一个普通fragment并无区别,完成以上步骤,便可以在设置应用里嵌入自己的自动开关机像功能。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值