Android系统Settings设置模块 - Go语言中文社区

Android系统Settings设置模块


Settings设置模块UI介绍

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

packagesappsSettingssrccomandroidsettingsdeviceinfoMemory.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怎么自定义,packagesappsSettingssrccomandroidsettingsdeviceinfo下的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个人认为好理解
packagesappsSettingssrccomandroidaudioprofileAudioProfilePreference.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效果的实现原理

这里写图片描述

packagesappsSettingssrccomandroidsettingsSettingsActivity.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);
      }

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

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/szqsdq/article/details/52537281
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-03-08 17:15:46
  • 阅读 ( 1494 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢