1.主界面frameworks/base/packages/SettingsLib/res/layout/settings_with_drawer
packages\apps\Settings\AndroidManifest.xml ,关键字android.intent.category.LAUNCHER,其实现类为Settings
<activity-alias android:name="Settings"
android:taskAffinity="com.android.settings"
android:label="@string/settings_label_launcher"
android:launchMode="singleTask"
android:targetActivity="Settings"> //目标文件及实现类
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="android.app.shortcuts" android:resource="@xml/shortcuts"/>
</activity-alias>
Settings.java总共有124个子类,继承SettingsActivity,SettingsActivity继承SettingsDrawerActivity,查看SettingsDrawerActivity,加载了布局文件settings_with_drawer,位于frameworks/base/packages/SettingsLib/res/layout/
主界面包括action_bar和两个FrameLayout content_header_container 和content_frame
侧拉栏为一个ListView left_drawer
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
<!-- The main content view -->
<LinearLayout
android:id="@+id/content_parent" >
<FrameLayout">
<Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/action_bar" />
</FrameLayout>
<FrameLayout
android:id="@+id/content_header_container" />
<FrameLayout
android:id="@+id/content_frame" />
</LinearLayout>
<!-- The navigation drawer -->
<ListView android:id="@+id/left_drawer" />
</android.support.v4.widget.DrawerLayout>
分析SettingsDrawerActivity可以知道
content_header_container通过setContentHeaderView设置,在DashboardContainerFragment中的onResume调用
content_frame通过setContentView设置
left_drawer通过适配器SettingsDrawerAdapter设置
返回到SettingsActivity的OnCreate,
if (intent.hasExtra(EXTRA_LAUNCH_ACTIVITY_ACTION)) {
startActivity(new Intent(mActivityAction));} //主ACTIVITY
mIsShowingDashboard = className.equals(Settings.class.getName())
|| className.equals(Settings.WirelessSettings.class.getName())
|| className.equals(Settings.DeviceSettings.class.getName())
|| className.equals(Settings.PersonalSettings.class.getName())
|| className.equals(Settings.WirelessSettings.class.getName()); //决定加载哪个布局文件
setContentView(mIsShowingDashboard ? R.layout.settings_main_dashboard : R.layout.settings_main_prefs);
2.packages/apps/Settings/res/layout/settings_main_dashboard.xml
当为WirelessSettings,DeviceSettings,PersonalSettings时进行调用,settings_main_dashboard中只有一个FrameLayout main_content
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_content"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:background="@color/material_grey_300"
/>
返回到SettingsActivity的OnCreate
//OnCreate
switchToFragment(DashboardContainerFragment.class.getName() //传进DashboardContainerFragment
//switchToFragment
transaction.replace(R.id.main_content, f);//将main_content替换为DashboardContainerFragment
查看DashboardContainerFragment中的onCreateView,给dashboard_container中的pager添加了适配器DashboardViewPagerAdapter,监听器TabChangeListener,并赋给R.layout.dashboard_container_header
ublic View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
final View content = inflater.inflate(R.layout.dashboard_container, parent, false);
mViewPager = (RtlCompatibleViewPager) content.findViewById(R.id.pager); //获取到dashboard_container中的pager
mPagerAdapter = new DashboardViewPagerAdapter(getContext(),
getChildFragmentManager(), mViewPager);
mViewPager.setAdapter(mPagerAdapter);
mViewPager.addOnPageChangeListener(
new TabChangeListener((SettingsActivity) getActivity()));
// check if support tab needs to be selected
final String selectedTab = getArguments().
getString(EXTRA_SELECT_SETTINGS_TAB, ARG_SUMMARY_TAB);
if (TextUtils.equals(selectedTab, ARG_SUPPORT_TAB)) {
mViewPager.setCurrentItem(INDEX_SUPPORT_FRAGMENT);
} else {
mViewPager.setCurrentItem(INDEX_SUMMARY_FRAGMENT);//设置为0
}
mHeaderView = inflater.inflate(R.layout.dashboard_container_header, parent, false);
((SlidingTabLayout) mHeaderView).setViewPager(mViewPager);//赋值给R.layout.dashboard_container_header
return content;
}
查看DashboardViewPagerAdapter,继承FragmentPagerAdapter.java,在getItem中返回DashboardSummary
查看DashboardSummary,在onCreate中创建了SummaryLoader
在onCreateView 返回了dashboard
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.dashboard, container, false);
}
在onViewCreated设置了适配器DashboardAdapter
ublic void onViewCreated(View view, Bundle bundle) {
mDashboard = (FocusRecyclerView) view.findViewById(R.id.dashboard_container);
mLayoutManager = new LinearLayoutManager(getContext());
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mDashboard.setLayoutManager(mLayoutManager);//设置布局为垂直线性布局
mDashboard.setHasFixedSize(true);
mDashboard.setListener(this);
mDashboard.addItemDecoration(new DashboardDecorator(getContext()));//设置分隔线
mAdapter = new DashboardAdapter(getContext(), mSuggestionParser, bundle,
mConditionManager.getConditions());
mDashboard.setAdapter(mAdapter);//设置适配器为DashboardAdapter
mSummaryLoader.setAdapter(mAdapter);
ConditionAdapterUtils.addDismiss(mDashboard);
if (DEBUG_TIMING) Log.d(TAG, "onViewCreated took "
+ (System.currentTimeMillis() - startTime) + " ms");
rebuildUI();
}
3.packages/apps/Settings/res/layout/dashboard_tile_switch.xml
每一行的布局
查看DashboardAdapter,继承RecyclerView
在onCreateViewHolder中加载了布局文件packages/apps/Settings/res/layout/dashboard_tile_switch.xml
public DashboardItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new DashboardItemHolder(LayoutInflater.from(parent.getContext()).inflate(
viewType, parent, false), (viewType == R.layout.dashboard_tile_switch));
}
//dashboard_tile_switch.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dashboard_tile_switch" >
<ImageView
android:id="@android:id/icon" /> //图标
<RelativeLayout>
<LinearLayout
android:orientation="vertical">
<TextView android:id="@android:id/title" />
<TextView android:id="@android:id/summary" />
</LinearLayout>
<Switch android:id="@+id/switchWidget" />
</RelativeLayout>
</LinearLayout>
``
`
在onBindViewHolder进行显示
```java
public void onBindViewHolder(DashboardItemHolder holder, int position) {
switch (mTypes.get(position)) {
case R.layout.dashboard_category://对应类别
onBindCategory(holder, (DashboardCategory) mItems.get(position));
break;
case R.layout.dashboard_tile://对应每个item
final Tile tile = (Tile) mItems.get(position);
onBindTile(holder, tile);
holder.itemView.setTag(tile);
holder.itemView.setOnClickListener(this);//点击事件
break;
case R.layout.dashboard_tile_switch:
.....;
case R.layout.suggestion_header:
...;
case R.layout.suggestion_tile:
...;
case R.layout.see_all:
...;
case R.layout.condition_card:
...;
}
}
onClick中每个Item点击调用的是((SettingsActivity) mContext).openTile((Tile) v.getTag());
4. rebuildUI
返回到DashboardSummary中的onViewCreated,这里会调用rebuildUI
private void rebuildUI() {
if (!isAdded()) {
Log.w(TAG, "Cannot build the DashboardSummary UI yet as the Fragment is not added");
return;
}
List<DashboardCategory> categories =
((SettingsActivity) getActivity()).getDashboardCategories(); //获取的categories为
mAdapter.setCategories(categories); //这里设置
// recheck to see if any suggestions have been changed.
new SuggestionLoader().execute();
}
分析getDashboardCategories ,调用逻辑为
SettingsDrawerActivity.java中的getDashboardCategories
–>TileUtils.getCategories(this, sTileCache); //传进的sTileCache为一个空的HashMap
→getTilesForAction
–>List results = pm.queryIntentActivitiesAsUser //获取AndroidManifest.xml
List<ResolveInfo> results = pm.queryIntentActivitiesAsUser(intent,
PackageManager.GET_META_DATA, user.getIdentifier());
ActivityInfo activityInfo = resolved.activityInfo;
Bundle metaData = activityInfo.metaData; //解析meta-data节点