Android系统Settings设置模块

来源:互联网 发布:深入浅出wpf 源码 编辑:程序博客网 时间:2024/04/28 01:11

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可以说是过来一遍,下面会来记录我这边是怎么来深度定制

0 0
原创粉丝点击