Settings 布局简析

来源:互联网 发布:js encoder编码器 编辑:程序博客网 时间:2024/05/19 15:20

Android M 

布局

packages/apps/Settings/res/layout/dashboard.xml

装载dashboard-category的一个容器


packages/apps/Settings/res/layout/dashboard_categories.xml

dashboard category


packages/apps/Settings/res/layout/dashboard_tile.xml

dashboard-tile布局


<dashboard-category

            android:id="@+id/device_section"

            android:title="@string/header_category_device" >

        <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"

                />

           。。。。。。

</dashboard-category>


元素dashboard-category 指一类别

元素dashboard-tile指类别中的某一项


android:fragment="com.android.settings.deviceinfo.Memory"指定对应的activity

package/app/Settings/res/device_info_memory.xml指定android:fragment布局文件

<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>


代码


加载dashboard-category容器布局

packages/apps/Settings/src/com/android/settings/dashboard/ DashboardSummary.java


public View onCreateView(LayoutInflater inflater, ViewGroup container,

                             Bundle savedInstanceState) {

        mExt = UtilsExt.getMiscPlugin(this.getActivity());

        mLayoutInflater = inflater;

 

        final View rootView = inflater.inflate(R.layout.dashboard, container, false);

        mDashboard = (ViewGroup) rootView.findViewById(R.id.dashboard_container);

 

        return rootView;

}


循环加载dashboard-category和dashboard-tile

packages/apps/Settings/src/com/android/settings/dashboard/ DashboardSummary.java


private void rebuildUI(Context context) {

List<DashboardCategory> categories =

                ((SettingsActivity) context).getDashboardCategories(true);

        final int count = categories.size();

        for (int n = 0; n < count; n++) {

            DashboardCategory category = categories.get(n);

            View categoryView = mLayoutInflater.inflate(R.layout.dashboard_category, mDashboard,

                    false);

            TextView categoryLabel = (TextView) categoryView.findViewById(R.id.category_title);

            categoryLabel.setText(category.getTitle(res));

            ViewGroup categoryContent =

                    (ViewGroup) categoryView.findViewById(R.id.category_content);

            final int tilesCount = category.getTilesCount();

            for (int i = 0; i < tilesCount; i++) {

                DashboardTile tile = category.getTile(i);

。。。。。。。。

}

。。。。。。。。

}


fragment 继承关系

点击DashboardTile跳转到对应fragment activity,从ENTRY_FRAGMENTS找或直接指定名字。


packages/apps/Settings/src/com/android/settings/Settings.java


public class Settings extends SettingsActivity {

      。。。。。。。。。。。

public static class HomeSettingsActivity extends SettingsActivity { /* empty */ }

    public static class DisplaySettingsActivity extends SettingsActivity { /* empty */ }

public static class DeviceInfoSettingsActivity extends SettingsActivity { /* empty */ }

。。。。。。。。。。。。。

}



packages/apps/Settings/src/com/android/settings/SettingsActivity.java

    private static final int MSG_BUILD_CATEGORIES = 1;

    private Handler mHandler = new Handler() {

        @Override

        public void handleMessage(Message msg) {

            switch (msg.what) {

                case MSG_BUILD_CATEGORIES: {

                    final boolean forceRefresh = msg.getData().getBoolean(MSG_DATA_FORCE_REFRESH);

                    if (forceRefresh) {

                        buildDashboardCategories(mCategories);

                    }

                } break;

            }

        }

    };

    private void buildDashboardCategories(List<DashboardCategory> categories) {

        categories.clear();

        loadCategoriesFromResource(R.xml.dashboard_categories, categories);

        updateTilesList(categories);

    }

    private void updateTilesList(List<DashboardCategory> target) {

        

final int size = target.size();

        for (int i = 0; i < size; i++) {

            DashboardCategory category = target.get(i);

            // Ids are integers, so downcasting is ok

            int id = (int) category.id;

            int n = category.getTilesCount() - 1;

            while (n >= 0) {

                DashboardTile tile = category.getTile(n);

                boolean removeTile = false;

                id = (int) tile.id;

                if (id == R.id.operator_settings || id == R.id.manufacturer_settings) {

                    if (!Utils.updateTileToSpecificActivityFromMetaDataOrRemove(this, tile)) {

                        removeTile = true;

                    }

                }

                if (UserHandle.MU_ENABLED && UserHandle.myUserId() != 0

                        && !ArrayUtils.contains(SETTINGS_FOR_RESTRICTED, id)) {

                    removeTile = true;

                }

                。。。。。。。。

 

                if (removeTile && n < category.getTilesCount()) {

                    category.removeTile(n);

                }

                n--;

            }

     }

    private int[] SETTINGS_FOR_RESTRICTED = {

            R.id.wireless_section,

            R.id.wifi_settings,

            R.id.bluetooth_settings,

            R.id.data_usage_settings,

          。。。。。。

}

private static final String[] ENTRY_FRAGMENTS = {

            WirelessSettings.class.getName(),

            WifiSettings.class.getName(),

            AdvancedWifiSettings.class.getName(),

            SavedAccessPointsWifiSettings.class.getName(),

            BluetoothSettings.class.getName(),

            DeviceInfoSettings.class.getName(),

            TetherSettings.class.getName(),

         。。。。。。。。

}

protected void onCreate(Bundle savedState) {

         。。。。。。。。。。。

switchToFragment(DashboardSummary.class.getName(), null, false, false,

                        mInitialTitleResId, mInitialTitle, false);

   。。。。。。。。

}



点击DashboardTile跳转到对应fragment activity,从ENTRY_FRAGMENTS找或直接指定名字。

AndroidManifest.xml meta-data DeviceInfoSettingsActivity 与DeviceInfoSettings关联起来


        <activity android:name="Settings$DeviceInfoSettingsActivity"

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />

                <action android:name="android.settings.DEVICE_INFO_SETTINGS" />

                <category android:name="android.intent.category.DEFAULT" />

                <category android:name="android.intent.category.VOICE_LAUNCH" />

            </intent-filter>

            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"

                android:value="com.android.settings.DeviceInfoSettings" />

            <meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID"

                android:resource="@id/about_settings" />

            <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"

                android:value="true" />

        </activity>



 

函数updateTilesList(List<DashboardCategory> target)参数List<DashboardCategory> target代表package/app/Settings/xml/dashboard_categories.xml

DashboardCategory category = target.get(i);代表元素dashboard-category指定的一类别

DashboardTile tile = category.getTile(n);代表元素dashboard-tile指类别中的一项

接下来是对整个dashboard_categories.xml进行循环解析,以确定哪些dashboard-tile需要隐藏还是要显示。

最后将需要显示的dashboard-category判断是否存在数组SETTINGS_FOR_RESTRICTED中,以进一步判断是否隐藏还是显示

 

if (UserHandle.MU_ENABLED && UserHandle.myUserId() != 0

                        && !ArrayUtils.contains(SETTINGS_FOR_RESTRICTED, id)) {

                    removeTile = true;

                }



AndroidN 上有写差别,布局都是动态的,其它的一样。









原创粉丝点击