Android 5.1 Contacts源码分析:PeopleActivity
Posted ximsfei
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 5.1 Contacts源码分析:PeopleActivity相关的知识,希望对你有一定的参考价值。
1. PeopleActivity主界面UI显示
下图为联系人主界面(PeopleActivity)的类图:
PeopleActivity除了实现了类图中的四个接口,还实现了View.OnCreateContextMenuListener和View.OnClickListener,其中Activity源码中已经实现了OnCreateContextMenuListener:
public class Activity extends ContextThemeWrapper
implements LayoutInflater.Factory2,
Window.Callback, KeyEvent.Callback,
OnCreateContextMenuListener, ComponentCallbacks2,
Window.OnWindowDismissedCallback
故子类中并不需要去实现OnCreateContextMenuListener了,只需要重写
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)
该方法,并调用registerForContextMenu(View view)和unregisterForContextMenu(View view)即可。
跟主界面UI息息相关的类主要有
ActionBarAdapter:Adapter for the action bar at the top of the Contacts activity
ViewPagerTabs:ActionBar中添加Tab及其点击事件,联系人、收藏。
以及几个内部类:
private class TabPagerListener implements ViewPager.OnPageChangeListener
private class TabPagerAdapter extends PagerAdapter
上图为PeopleActivity UI显示的部分时序图
在createViewsAndFragments中:
private void createViewsAndFragments(Bundle savedState)
// Disable the ActionBar so that we can use a Toolbar. This needs to be called before
// setContentView().
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.people_activity);
final FragmentManager fragmentManager = getFragmentManager();
// Hide all tabs (the current tab will later be reshown once a tab is selected)
final FragmentTransaction transaction = fragmentManager.beginTransaction();
mTabTitles = new String[TabState.COUNT];
mTabTitles[TabState.FAVORITES] = getString(R.string.favorites_tab_label);
mTabTitles[TabState.ALL] = getString(R.string.all_contacts_tab_label);
mTabPager = getView(R.id.tab_pager);
mTabPagerAdapter = new TabPagerAdapter();
mTabPager.setAdapter(mTabPagerAdapter);
mTabPager.setOnPageChangeListener(mTabPagerListener);
// Configure toolbar and toolbar tabs. If in landscape mode, we configure tabs differntly.
final Toolbar toolbar = getView(R.id.toolbar);
setActionBar(toolbar);
final ViewPagerTabs portraitViewPagerTabs
= (ViewPagerTabs) findViewById(R.id.lists_pager_header);
ViewPagerTabs landscapeViewPagerTabs = null;
if (portraitViewPagerTabs == null)
landscapeViewPagerTabs = (ViewPagerTabs) getLayoutInflater().inflate(
R.layout.people_activity_tabs_lands, toolbar, /* attachToRoot = */ false);
mViewPagerTabs = landscapeViewPagerTabs;
else
mViewPagerTabs = portraitViewPagerTabs;
mViewPagerTabs.setViewPager(mTabPager);
final String FAVORITE_TAG = "tab-pager-favorite";
final String ALL_TAG = "tab-pager-all";
// Create the fragments and add as children of the view pager.
// The pager adapter will only change the visibility; it'll never create/destroy
// fragments.
// However, if it's after screen rotation, the fragments have been re-created by
// the fragment manager, so first see if there're already the target fragments
// existing.
mFavoritesFragment = (ContactTileListFragment)
fragmentManager.findFragmentByTag(FAVORITE_TAG);
mAllFragment = (DefaultContactBrowseListFragment)
fragmentManager.findFragmentByTag(ALL_TAG);
if (mFavoritesFragment == null)
mFavoritesFragment = new ContactTileListFragment();
mAllFragment = new DefaultContactBrowseListFragment();
transaction.add(R.id.tab_pager, mFavoritesFragment, FAVORITE_TAG);
transaction.add(R.id.tab_pager, mAllFragment, ALL_TAG);
mFavoritesFragment.setListener(mFavoritesFragmentListener);
mAllFragment.setOnContactListActionListener(new ContactBrowserActionListener());
// Hide all fragments for now. We adjust visibility when we get onSelectedTabChanged()
// from ActionBarAdapter.
transaction.hide(mFavoritesFragment);
transaction.hide(mAllFragment);
transaction.commitAllowingStateLoss();
fragmentManager.executePendingTransactions();
// Setting Properties after fragment is created
mFavoritesFragment.setDisplayType(DisplayType.STREQUENT);
mActionBarAdapter = new ActionBarAdapter(this, this, getActionBar(),
portraitViewPagerTabs, landscapeViewPagerTabs, toolbar);
mActionBarAdapter.initialize(savedState, mRequest);
// Add shadow under toolbar
ViewUtil.addRectangularOutlineProvider(findViewById(R.id.toolbar_parent), getResources());
// Configure action button
final View floatingActionButtonContainer = findViewById(
R.id.floating_action_button_container);
ViewUtil.setupFloatingActionButton(floatingActionButtonContainer, getResources());
final ImageButton floatingActionButton = (ImageButton) findViewById(R.id.floating_action_button);
floatingActionButton.setOnClickListener(this);
invalidateOptionsMenuIfNeeded();
从Activity.java源码中可以看到:
public void setActionBar(@Nullable Toolbar toolbar)
if (getActionBar() instanceof WindowDecorActionBar)
throw new IllegalStateException("This Activity already has an action bar supplied " +
"by the window decor. Do not request Window.FEATURE_ACTION_BAR and set " +
"android:windowActionBar to false in your theme to use a Toolbar instead.");
ToolbarActionBar tbab = new ToolbarActionBar(toolbar, getTitle(), this);
mActionBar = tbab;
mWindow.setCallback(tbab.getWrappedWindowCallback());
mActionBar.invalidateOptionsMenu();
public void setContentView(View view, ViewGroup.LayoutParams params)
getWindow().setContentView(view, params);
initWindowDecorActionBar();
private void initWindowDecorActionBar()
Window window = getWindow();
// Initializing the window decor can change window feature flags.
// Make sure that we have the correct set before performing the test below.
window.getDecorView();
if (isChild() || !window.hasFeature(Window.FEATURE_ACTION_BAR) || mActionBar != null)
return;
mActionBar = new WindowDecorActionBar(this);
mActionBar.setDefaultDisplayHomeAsUpEnabled(mEnableDefaultActionBarUp);
mWindow.setDefaultIcon(mActivityInfo.getIconResource());
mWindow.setDefaultLogo(mActivityInfo.getLogoResource());
我们想要在Activity中使用ToolBar,必须调用getWindow().requestFeature(Window.FEATURE_NO_TITLE);去掉默认的ActionBar,否则会抛出异常,并且在setContentView()中会初始化系统的ActionBar,所以想要去掉默认ActionBar,该方法必须在setContentView()之前调用。
mTabTitles = new String[TabState.COUNT];
mTabTitles[TabState.FAVORITES] = getString(R.string.favorites_tab_label);
mTabTitles[TabState.ALL] = getString(R.string.all_contacts_tab_label);
PeopleActivity的ViewPager中有两个页面,一个是收藏页面(ContactTileListFragment),另一个是所有联系人页面(DefaultContactBrowseListFragment)。
类似的我从Android4.4源码中提取过一个Demo:
在Android中使用ViewPager实现左右滑动页面
PeopleActivity Menu:
public boolean onCreateOptionsMenu(Menu menu)
if (!areContactsAvailable())
// If contacts aren't available, hide all menu items.
return false;
super.onCreateOptionsMenu(menu);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.people_options, menu);
return true;
在onPrepareOptionsMenu(Menu menu)中会根据是否为搜索模式(isSearchMode),当前在那个页面中(mActionBarAdapter.getCurrentTab())决定菜单的显示情况。
以上是关于Android 5.1 Contacts源码分析:PeopleActivity的主要内容,如果未能解决你的问题,请参考以下文章
Android 5.1 Contacts源码分析:Contacts模块ListView Adapter结构
Android 5.1 Contacts源码分析:Contacts模块Fargment结构
Android 5.1 Contacts源码分析:PeopleActivity
Android 5.1系统源码Wifi模块中wifiSettings源码分析