Android系统Settings设置模块

Settings设置模块UI介绍

FrameWork开发之路首先得玩得转系统APP,个人是在Android5.0的基础上进行定制,Settings模块分为两个部分:
packages\app\Settings 下的APP代码部分
frameworks/base/packages/SettingsProvider/ 数据库
frameworks/base/core/java/android/provider/Settings.java
首先从APP代码部分入手,UI界面架构是有3部分组成实现可配置可扩展,先理解PreferenceFragment, PreferenceScreen,PreferenceCategory, Preference的关系,介绍的最详细的就是谷歌官方文档了,参照链接
我这边首先将的是如何自定义PreferenceCategory和自定义Preference,首先来看系统如何来操作的,参考设置存储部分的界面
这里写图片描述

packages\apps\Settings\src\com\android\settings\deviceinfo\Memory.java就是fragment界面
###fragment核心代码块

@Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);

        final Context context = getActivity();
        '''preferenceFragment布局文件'''
        addPreferencesFromResource(R.xml.device_info_memory);

       for (StorageVolume volume : storageVolumes) {
            if (mMemoryExts.isAddPhysicalCategory(volume)) {
                addCategory(StorageVolumePreferenceCategory.buildForPhysical(context, volume));
            }
        }
    }

    private void addCategory(StorageVolumePreferenceCategory category) {
        mCategories.add(category);
        '''add多个category模块'''
        getPreferenceScreen().addPreference(category);
        category.init();
    }
对应的XMl,device_info_xml文件内容:

`<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
    android:title="@string/storage_settings"
    settings:keywords="@string/keywords_storage">
 </PreferenceScreen>


可以看出默认存储器,遥控存储器,总容量都是作为preference合并到一个category,然后add到preferenceScreen里面,下面来看PreferenceCategory怎么自定义,packages\apps\Settings\src\com\android\settings\deviceinfo下的StorageVolumePreferenceCategory.java

public class StorageVolumePreferenceCategory extends PreferenceCategory {
 private StorageVolumePreferenceCategory(Context context, StorageVolume volume) {
        super(context);

        mVolume = volume;
        mMeasure = StorageMeasurement.getInstance(context, volume);
        mResources = context.getResources();
        mStorageManager = StorageManager.from(context);
        mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);

        mCategoryExts = new StorageVolumePreferenceCategoryExts(context, mVolume);
        mCategoryExts.setVolumeTitle(this);
    }

    private StorageItemPreference buildItem(int titleRes, int colorRes) {
        return new StorageItemPreference(getContext(), titleRes, colorRes);
    }

    public void init() {
        final Context context = getContext();
        '''遥控器存储作为自定义的Preference'''
        mUsageBarPreference = new UsageBarPreference(context);
        mUsageBarPreference.setOrder(ORDER_USAGE_BAR);
        addPreference(mUsageBarPreference);
        '''总容量作为自定义的Preference'''
        mItemTotal = buildItem(R.string.memory_size, 0);
        mItemAvailable = buildItem(R.string.memory_available, R.color.memory_avail);
        addPreference(mItemTotal);
        addPreference(mItemAvailable);
        '''各个类别文件存储作为自定义的Preference'''
        mItemApps = buildItem(R.string.memory_apps_usage, R.color.memory_apps_usage);
        mItemDcim = buildItem(R.string.memory_dcim_usage, R.color.memory_dcim);
        mItemMusic = buildItem(R.string.memory_music_usage, R.color.memory_music);
        mItemDownloads = buildItem(R.string.memory_downloads_usage, R.color.memory_downloads);
        mItemCache = buildItem(R.string.memory_media_cache_usage, R.color.memory_cache);
        mItemMisc = buildItem(R.string.memory_media_misc_usage, R.color.memory_misc);

        mItemCache.setKey(KEY_CACHE);

        /** M: CR ALPS01309473, Set storageItem keys.@{*/
        mItemApps.setKey(KEY_APPS);
        mItemDcim.setKey(KEY_DCIM);
        mItemMusic.setKey(KEY_MUSIC);
        mItemDownloads.setKey(KEY_DOWNLOADS);
        mItemMisc.setKey(KEY_MISC);
        /** @} */

        final boolean showDetails = mVolume == null || mVolume.isPrimary();
        if (showDetails) {
            if (showUsers) {
                addPreference(new PreferenceHeader(context, currentUser.name));
            }
           '''Preference 添加到Category的过程'''
            addPreference(mItemApps);
            addPreference(mItemDcim);
            addPreference(mItemMusic);
            addPreference(mItemDownloads);
            addPreference(mItemCache);
            addPreference(mItemMisc);
        }
     }

}

下面看如何自定义各种UI效果的Preference,本质就是自定义View披上一层外套,从简单的入手,音量设置的preference个人认为好理解
\packages\apps\Settings\src\com\android\audioprofile\AudioProfilePreference.java

public class AudioProfilePreference extends Preference {
 public AudioProfilePreference(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);

        mContext = context;

        mInflater = (LayoutInflater) mContext
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        // get the title from audioprofile_settings.xml
         '''Preference属性Title的设置'''
        if (super.getTitle() != null) {
            mPreferenceTitle = super.getTitle().toString();
        }

        // get the summary from audioprofile_settings.xml
          '''Preference属性Summary副标题的设置'''
        if (super.getSummary() != null) {
            mPreferenceSummary = super.getSummary().toString();
        }

        mProfileManager = (AudioProfileManager) context
                .getSystemService(Context.AUDIO_PROFILE_SERVICE);
      '''Preference属性Key本质就是SharedPreference种的Key设置'''
        mKey = getKey();

        mExt = UtilsExt.getAudioProfilePlgin(context);
    }
    '''PreferenceUI效果'''
    @Override
    public View onCreateView(ViewGroup parent) {
        Xlog.d(XLOGTAG, TAG + "onCreateView " + getKey());
        View view = mExt.createView(R.layout.audio_profile_item);

        mCheckboxButton = (RadioButton) mExt
                .getPrefRadioButton(R.id.radiobutton);
        mTextView = (TextView) mExt.getPreferenceTitle(R.id.profiles_text);
        mSummary = (TextView) mExt.getPreferenceSummary(R.id.profiles_summary);
      }

}

看一下Preference的UI xml文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:gravity="center_vertical"
    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
    >

    <LinearLayout android:id="@android:id/widget_frame"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical"/>  
        <RadioButton 
            android:id="@+id/radiobutton" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:layout_gravity="center"
            android:orientation="vertical"
            android:focusable="false"/>
     />

哈哈,本质就是自定义View了
还有一个小的知识点:官方文档介绍PreferenceScreen跳转Activity的时候没有介绍到Intent怎么给Activity传值,所以我就贴上这个小的知识点

<PreferenceScreen android:key="toggle_storage_settings"
                      android:title="@string/storage_settings">
            <intent android:action="settings.advanced.fragment"
                    android:targetPackage="com.android.settings">
            <extra android:name="Zhongqi.Shao" android:value="com.android.settings.deviceinfo.Memory"/>
            </intent>
    </PreferenceScreen> 

到这应该理解Settings UI效果中的每一个元素关系,现在可以看Settings布局UI效果的实现原理

这里写图片描述

packages\apps\Settings\src\com\android\settings\SettingsActivity.java
启动的Activity是继承SettingsActivity的Settings.java,参见SettingsActivity.onCreate()函数本质就是Framelayout切换Fragment的效

    @Override
    protected void onCreate(Bundle savedState) {
        super.onCreate(savedState);
        '''就是空空的FrameLayout'''
         setContentView(mIsShowingDashboard ?
                R.layout.settings_main_dashboard : R.layout.settings_main_prefs);
           '''中间代码省略'''       
          switchToFragment(DashboardSummary.class.getName(), null, false, false,
                        mInitialTitleResId, mInitialTitle, false);
      }

下面来看packages\apps\Settings\src\com\android\settings\dashboardDashboardSummary.java的代码

private void rebuildUI(Context context) {
        long start = System.currentTimeMillis();
        final Resources res = getResources();

        mDashboard.removeAllViews();
        '''又回到SettingsActivity.getDashboardCategories()'''  
        List<DashboardCategory> categories =
                ((SettingsActivity) context).getDashboardCategories(true);
 }

'''SettingsActivity中getDashboardCategories()实现'''  
public List<DashboardCategory> getDashboardCategories(boolean forceRefresh) {
        if (forceRefresh || mCategories.size() == 0) {
            buildDashboardCategories(mCategories);
        }
        return mCategories;
 }

  private void buildDashboardCategories(List<DashboardCategory> categories) {
        categories.clear();
        '''重点 通过解析xml来实现配置加载fragment'''  
        loadCategoriesFromResource(R.xml.dashboard_categories, categories);
        updateTilesList(categories);
    }
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<dashboard-categories
        xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- WIRELESS and NETWORKS -->
    <dashboard-category
            android:id="@+id/wireless_section"
            android:title="@string/header_category_wireless_networks" >

        <!-- Wifi -->
        <dashboard-tile
                android:id="@+id/wifi_settings"
                android:title="@string/wifi_settings_title"
                android:fragment="com.android.settings.wifi.WifiSettings"
                android:icon="@drawable/ic_settings_wireless"
                />

        <!--HetComm-->
        <dashboard-tile
                android:id="@+id/hetcomm_settings"
                android:icon="@drawable/ic_settings_hetcomm"
                android:title="@string/hetcom_setting_title">
            <intent android:action="com.android.settings.HETCOMM_SETTINGS" />
        </dashboard-tile>

        <!-- Bluetooth -->
        <dashboard-tile
                android:id="@+id/bluetooth_settings"
                android:title="@string/bluetooth_settings_title"
                android:fragment="com.android.settings.bluetooth.BluetoothSettings"
                android:icon="@drawable/ic_settings_bluetooth2"
                />

        <!-- Hotknot -->
        <dashboard-tile
                android:id="@+id/hotknot_settings"
                android:title="@string/hotknot_settings_title"
                android:fragment="com.mediatek.settings.hotknot.HotKnotSettings"
                android:icon="@drawable/ic_settings_hotknot" 
                />

        <!-- SIM Cards -->
        <dashboard-tile
                android:id="@+id/sim_settings"
                android:title="@string/sim_settings_title"
                android:fragment="com.android.settings.sim.SimSettings"
                android:icon="@drawable/ic_sim_sd"
                />

        <!-- Data Usage -->
        <dashboard-tile
                android:id="@+id/data_usage_settings"
                android:title="@string/data_usage_summary_title"
                android:fragment="com.android.settings.DataUsageSummary"
                android:icon="@drawable/ic_settings_data_usage"
                />

        <!-- Operator hook -->
        <!--modify by zhongqi.shao on 2016-09-12 start
        <dashboard-tile
                android:id="@+id/operator_settings"
                android:fragment="com.android.settings.WirelessSettings" >
            <intent android:action="com.android.settings.OPERATOR_APPLICATION_SETTING" />
        </dashboard-tile>

        <dashboard-tile
                android:id="@+id/wireless_settings"
                android:title="@string/radio_controls_title"
                android:fragment="com.android.settings.WirelessSettings"
                android:icon="@drawable/ic_settings_more"

                />modify by zhongqi.shao on 2016-09-12 end-->

    </dashboard-category>

    <!-- DEVICE -->
    <dashboard-category
            android:id="@+id/device_section"
            android:title="@string/header_category_device" >

        <!-- Home -->
        <dashboard-tile
                android:id="@+id/home_settings"
                android:title="@string/home_settings"
                android:fragment="com.android.settings.HomeSettings"
                android:icon="@drawable/ic_settings_home"
                />

        <!-- Display -->
        <dashboard-tile
                android:id="@+id/display_settings"
                android:title="@string/display_settings"
                android:fragment="com.android.settings.DisplaySettings"
                android:icon="@drawable/ic_settings_display"
                />

        <!-- Notifications -->
        <dashboard-tile
                android:id="@+id/notification_settings"
                android:title="@string/notification_settings"
                android:fragment="com.mediatek.audioprofile.AudioProfileSettings"
                android:icon="@drawable/ic_settings_notifications"
                />

        <!--modify by zhongqi.shao on 2016-09-13 start-->
        <!-- Storage -->
        <!--<dashboard-tile
                android:id="@+id/storage_settings"
                android:title="@string/storage_settings"
                android:fragment="com.android.settings.deviceinfo.Memory"
                android:icon="@drawable/ic_settings_storage"
                />-->
        <!--modify by zhongqi.shao on 2016-09-13 end-->

        <!-- Battery -->
        <dashboard-tile
                android:id="@+id/battery_settings"
                android:title="@string/power_usage_summary_title"
                android:fragment="com.android.settings.fuelgauge.PowerUsageSummary"
                android:icon="@drawable/ic_settings_battery"
                />

        <!-- Application Settings -->
        <dashboard-tile
                android:id="@+id/application_settings"
                android:title="@string/applications_settings"
                android:fragment="com.android.settings.applications.ManageApplications"
                android:icon="@drawable/ic_settings_applications"
                />

        <!-- Manage users -->
        <dashboard-tile
                android:id="@+id/user_settings"
                android:title="@string/user_settings_title"
                android:fragment="com.android.settings.users.UserSettings"
                android:icon="@drawable/ic_settings_multiuser"
                />

        <!-- Manage NFC payment apps -->
        <dashboard-tile
                android:id="@+id/nfc_payment_settings"
                android:title="@string/nfc_payment_settings_title"
                android:fragment="com.android.settings.nfc.PaymentSettings"
                android:icon="@drawable/ic_settings_nfc_payment"
                />

        <!-- Manufacturer hook -->
        <!--modify by zhongqi.shao on 2016-09-12
        <dashboard-tile
                android:id="@+id/manufacturer_settings"
                android:fragment="com.android.settings.WirelessSettings">
            <intent android:action="com.android.settings.MANUFACTURER_APPLICATION_SETTING" />
        </dashboard-tile>-->

    </dashboard-category>

    <!-- PERSONAL -->
    <dashboard-category
            android:id="@+id/personal_section"
            android:title="@string/header_category_personal" >

        <!-- Location -->
        <dashboard-tile
                android:id="@+id/location_settings"
                android:title="@string/location_settings_title"
                android:fragment="com.android.settings.location.LocationSettings"
                android:icon="@drawable/ic_settings_location"
                />

        <!-- Security -->
        <dashboard-tile
                android:id="@+id/security_settings"
                android:title="@string/security_settings_title"
                android:fragment="com.android.settings.SecuritySettings"
                android:icon="@drawable/ic_settings_security"
                />

        <!-- Account -->
        <dashboard-tile
                android:id="@+id/account_settings"
                android:title="@string/account_settings_title"
                android:fragment="com.android.settings.accounts.AccountSettings"
                android:icon="@drawable/ic_settings_accounts"
                />

        <!-- Language -->
        <dashboard-tile
                android:id="@+id/language_settings"
                android:title="@string/language_settings"
                android:fragment="com.android.settings.inputmethod.InputMethodAndLanguageSettings"
                android:icon="@drawable/ic_settings_language"
                />

        <!-- Backup and reset -->
        <dashboard-tile
                android:id="@+id/privacy_settings"
                android:title="@string/privacy_settings"
                android:fragment="com.android.settings.PrivacySettings"
                android:icon="@drawable/ic_settings_backup"
                />

    </dashboard-category>


</dashboard-categories>

到这基本UI可以说是过来一遍,下面会来记录我这边是怎么来深度定制

  • 10
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Settings模块Android系统中的一个重要组成部分,它提供了用户对设备进行配置和管理的界面。它是一个完整的应用程序,由多个Activity和Fragment组成,主要包括以下几个部分: 1. 系统设置:包括网络、声音、显示、电池、存储、安全等设置,用户可以根据自己的需要对系统进行设置。 2. 应用设置:包括已安装应用的管理和配置,用户可以查看应用信息、权限、通知、存储、数据使用情况等。 3. 用户设置:包括用户账户和个人资料的管理和配置,用户可以添加、删除、切换用户账户,还可以修改个人资料、语言、时区等。 4. 开发者选项:为开发者提供了一些高级设置和调试工具,例如USB调试、CPU使用情况、布局边界等。 5. 关于手机:提供了设备的基本信息,包括设备型号、Android版本、内核版本、基带版本等。 Android Settings模块的实现主要依赖于Android框架中的SettingsProvider和Settings应用程序。SettingsProvider是一个ContentProvider,为Settings应用程序提供数据源,包括系统设置、应用设置、用户设置等。Settings应用程序则负责展示这些数据并提供用户交互界面。 总的来说,Android Settings模块为用户提供了方便、实用的设备配置和管理功能,同时为开发者提供了一些高级设置和调试工具,是Android系统中非常重要的一个组成部分。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值