概述

Android L的settings界面实现和Android4.4版本有很大的不同,在Android L中,setting是使用dashboard等控件进行了重新实现。具体流程如下。

初始化流程

Android L Settings模块首界面为Settings,继承自SettingsActivity,而SettingsActivity继承自Activity。

首先看一下Settings.java代码,可以发现它没有重写任何SettingsActiviy的方法,也没有增加任何自己的方法,唯独增加了许多静态内部类,如:

   /* * Settings subclasses for launching independently. */    public static class BluetoothSettingsActivity extends SettingsActivity { /* empty */ }    public static class WirelessSettingsActivity extends SettingsActivity { /* empty */ }    public static class SimSettingsActivity extends SettingsActivity { /* empty */ }    // ......

看注释可以知道,这些子类是为了启动特定独立的Settings选项而创建的,例如在某个应用里需要设置蓝牙那么只需要启动 BluetoothSettingsActivity 就可以了。

所以,Settings模块的启动流程直接看SettingsActivity就行了。

SettingsActivity

onCreate方法是Activity的生命周期第一步,带注释的onCreate()源码如下:

  @Override    protected void onCreate(Bundle savedState) {        super.onCreate(savedState);        // 用来获取Activity的额外数据mFragmentClass,直接启动Settings模块不会获得这个数据        getMetaData();        final Intent intent = getIntent();        if (intent.hasExtra(EXTRA_UI_OPTIONS)) {            getWindow().setUiOptions(intent.getIntExtra(EXTRA_UI_OPTIONS, 0));        }        mDevelopmentPreferences = getSharedPreferences(DevelopmentSettings.PREF_FILE,                Context.MODE_PRIVATE);        // Getting Intent properties can only be done after the super.onCreate(...)        final String initialFragmentName = intent.getStringExtra(EXTRA_SHOW_FRAGMENT);        mIsShortcut = isShortCutIntent(intent) || isLikeShortCutIntent(intent) ||                intent.getBooleanExtra(EXTRA_SHOW_FRAGMENT_AS_SHORTCUT, false);        final ComponentName cn = intent.getComponent();        final String className = cn.getClassName();        mIsShowingDashboard = className.equals(Settings.class.getName());        // This is a "Sub Settings" when:        // - this is a real SubSettings        // - or :settings:show_fragment_as_subsetting is passed to the Intent        final boolean isSubSettings = className.equals(SubSettings.class.getName()) ||                intent.getBooleanExtra(EXTRA_SHOW_FRAGMENT_AS_SUBSETTING, false);        // If this is a sub settings, then apply the SubSettings Theme for the ActionBar content insets        if (isSubSettings) {            // Check also that we are not a Theme Dialog as we don't want to override them            final int themeResId = getThemeResId();            if (themeResId != R.style.Theme_DialogWhenLarge &&                    themeResId != R.style.Theme_SubSettingsDialogWhenLarge) {                setTheme(R.style.Theme_SubSettings);            }        }        // 设置contentview        setContentView(mIsShowingDashboard ?                R.layout.settings_main_dashboard : R.layout.settings_main_prefs);        // 获取framelayout控件        mContent = (ViewGroup) findViewById(R.id.main_content);        getFragmentManager().addOnBackStackChangedListener(this);        if (mIsShowingDashboard) {            Index.getInstance(getApplicationContext()).update();        }        if (savedState != null) {            // We are restarting from a previous saved state; used that to initialize, instead            // of starting fresh.            mSearchMenuItemExpanded = savedState.getBoolean(SAVE_KEY_SEARCH_MENU_EXPANDED);            mSearchQuery = savedState.getString(SAVE_KEY_SEARCH_QUERY);            setTitleFromIntent(intent);            ArrayList<DashboardCategory> categories =                    savedState.getParcelableArrayList(SAVE_KEY_CATEGORIES);            if (categories != null) {                mCategories.clear();                mCategories.addAll(categories);                setTitleFromBackStack();            }            mDisplayHomeAsUpEnabled = savedState.getBoolean(SAVE_KEY_SHOW_HOME_AS_UP);            mDisplaySearch = savedState.getBoolean(SAVE_KEY_SHOW_SEARCH);            mHomeActivitiesCount = savedState.getInt(SAVE_KEY_HOME_ACTIVITIES_COUNT,                    1 /* one home activity by default */);        } else {            // 第一次启动            if (!mIsShowingDashboard) {                // Search is shown we are launched thru a Settings "shortcut". UP will be shown                // only if it is a sub settings                if (mIsShortcut) {                    mDisplayHomeAsUpEnabled = isSubSettings;                    mDisplaySearch = false;                } else if (isSubSettings) {                    mDisplayHomeAsUpEnabled = true;                    mDisplaySearch = true;                } else {                    mDisplayHomeAsUpEnabled = false;                    mDisplaySearch = false;                }                setTitleFromIntent(intent);                Bundle initialArguments = intent.getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS);                switchToFragment(initialFragmentName, initialArguments, true, false,                        mInitialTitleResId, mInitialTitle, false);            } else {                // No UP affordance if we are displaying the main Dashboard                mDisplayHomeAsUpEnabled = false;                // Show Search affordance                mDisplaySearch = true;                mInitialTitleResId = R.string.dashboard_title;                // 跳转到DashboardSummary,这是构造UI真正的地方                switchToFragment(DashboardSummary.class.getName(), null, false, false,                        mInitialTitleResId, mInitialTitle, false);            }        }        mActionBar = getActionBar();        if (mActionBar != null) {            mActionBar.setDisplayHomeAsUpEnabled(mDisplayHomeAsUpEnabled);            mActionBar.setHomeButtonEnabled(mDisplayHomeAsUpEnabled);        }        mSwitchBar = (SwitchBar) findViewById(R.id.switch_bar);        // see if we should show Back/Next buttons        if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, false)) {            View buttonBar = findViewById(R.id.button_bar);            if (buttonBar != null) {                buttonBar.setVisibility(View.VISIBLE);                Button backButton = (Button)findViewById(R.id.back_button);                backButton.setOnClickListener(new OnClickListener() {                    public void onClick(View v) {                        setResult(RESULT_CANCELED, getResultIntentData());                        finish();                    }                });                Button skipButton = (Button)findViewById(R.id.skip_button);                skipButton.setOnClickListener(new OnClickListener() {                    public void onClick(View v) {                        setResult(RESULT_OK, getResultIntentData());                        finish();                    }                });                mNextButton = (Button)findViewById(R.id.next_button);                mNextButton.setOnClickListener(new OnClickListener() {                    public void onClick(View v) {                        setResult(RESULT_OK, getResultIntentData());                        finish();                    }                });                // set our various button parameters                if (intent.hasExtra(EXTRA_PREFS_SET_NEXT_TEXT)) {                    String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_NEXT_TEXT);                    if (TextUtils.isEmpty(buttonText)) {                        mNextButton.setVisibility(View.GONE);                    }                    else {                        mNextButton.setText(buttonText);                    }                }                if (intent.hasExtra(EXTRA_PREFS_SET_BACK_TEXT)) {                    String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_BACK_TEXT);                    if (TextUtils.isEmpty(buttonText)) {                        backButton.setVisibility(View.GONE);                    }                    else {                        backButton.setText(buttonText);                    }                }                if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_SKIP, false)) {                    skipButton.setVisibility(View.VISIBLE);                }            }        }        mHomeActivitiesCount = getHomeActivitiesCount();    }

DashboardSummary

dashboard中文意思是仪表盘,这里是指DashboardSummary就是用来显示Settings所有选项的。而DashboardSummary是个Fragment,所以先执行了onCreateView方法。

在onCreateView中,就是inflate了一个View返回,这个view的布局如下:

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/dashboard" android:layout_width="match_parent" android:layout_height="match_parent" <!-- 设置滑动那个bar的样式 -->    android:scrollbarStyle="outsideOverlay"    android:clipToPadding="false">        <LinearLayout  android:id="@+id/dashboard_container" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center_horizontal" android:paddingStart="@dimen/dashboard_padding_start" android:paddingEnd="@dimen/dashboard_padding_end" android:paddingTop="@dimen/dashboard_padding_top" android:paddingBottom="@dimen/dashboard_padding_bottom" android:orientation="vertical" /></ScrollView>

DashboardSummary走完onCreateView方法后会走onResume,onResume会通过handler发送一个消息来构建UI界面的方法rebuildUI,然后一路下来又会调用到SettingsActivity的loadCategoriesFromResource(R.xml.dashboard_categories, categories);

这个dashboard_categories.xml其实是布局的内容的抽象,通过这个xml文件解析出来能够填充每一项的资源内容。

小结

总结内容如下:

  1. onCreate完成的任务是切换DashboardSummary这个Fragment,然后从dashboard_categories.xml中读取预先配置好的文件来初始化Settings节目。
  2. AndroidL中舍弃了Header类,取而代之的是DashboardCategory和DashboardTile类。

UI修改

可以看出,如果我们想要改变Settings的UI,那我们主要需要改动如下几个自定义View和布局文件,分别是:

自定义view:

  1. DashboardContainerView
  2. DashboardTileView

布局文件:

  1. dashboard.xml,全局的xml布局文件。
  2. dashboard_category.xml,乘放tile的布局文件。
  3. dashboard_tile.xml,每个tile的布局文件。

更多相关文章

  1. android 没有root下实现软件自动更新的一些思路和方法
  2. Android(安卓)studio 3.0.1 莫名其妙 R报错啦!(check logs for det
  3. Android(安卓)开发建立经验分享...
  4. Android用Intent启动Activity的方法
  5. ProGuard惯用法
  6. android kill process 杀死进程的方法
  7. Android(安卓)自定义类库打包jar! 谁说不可以打包res 文件?
  8. Android关闭SdcardFS
  9. [Android]Fragment进行show和hide时候刷新数据

随机推荐

  1. Android建立dialog
  2. Android录制屏幕的实现方法
  3. Android学习App调试的几个命令实践
  4. Android数据保存之SharedPreference
  5. [置顶] Activity启动模式 及 Intent Flag
  6. React Native如何适配iOS \ Android样式
  7. 外形设计有亮点,日本电讯商 KDDI 发布多款
  8. Android vs iPhone icon设计指南
  9. Android Studio无法启动的解决方案 canno
  10. Android基础之内存溢出