【Dialer】android6.0拨号界面分析<二>
来源:互联网 发布:淘宝店铺等级怎么查询 编辑:程序博客网 时间:2024/05/20 21:21
题记
大家清明假期快乐!!!!
下面简单介绍下拨号界面运用ViewPager+Fragment实现的主界面。
ViewPager和Fragment
原生拨号应用界面的ViewPager由mViewPager+mViewPagerTabs组成。
mViewPager:ViewPager,用于与容纳fragment,并使用adapter与数据进行交互。
mViewPagerTabs:这里我认为是为了更好的定义ViewPager的Title使用。(相当于更加灵活的ViewPager的“头部”)。
代码如下:
mViewPager的初始化:
// 初始化ViewPager mViewPager = (ViewPager) parentView.findViewById(R.id.lists_pager); mViewPagerAdapter = new ViewPagerAdapter(getChildFragmentManager()); // 设置Adapter,与fragment建立联系 mViewPager.setAdapter(mViewPagerAdapter); mViewPager.setOffscreenPageLimit(TAB_COUNT_WITH_VOICEMAIL - 1); mViewPager.setOnPageChangeListener(this);
ViewPagerAdapter代码如下:
public class ViewPagerAdapter extends FragmentPagerAdapter { public ViewPagerAdapter(FragmentManager fm) { super(fm); } @Override public long getItemId(int position) { return getRtlPosition(position); } @Override public Fragment getItem(int position) { switch (getRtlPosition(position)) { case TAB_INDEX_SPEED_DIAL: mSpeedDialFragment = new SpeedDialFragment(); return mSpeedDialFragment; case TAB_INDEX_RECENTS: mRecentsFragment = new CallLogFragment(CallLogQueryHandler.CALL_TYPE_ALL, MAX_RECENTS_ENTRIES, System.currentTimeMillis() - OLDEST_RECENTS_DATE); return mRecentsFragment; case TAB_INDEX_ALL_CONTACTS: mAllContactsFragment = new AllContactsFragment(); return mAllContactsFragment; case TAB_INDEX_VOICEMAIL: mVoicemailFragment = new CallLogFragment(Calls.VOICEMAIL_TYPE); return mVoicemailFragment; } throw new IllegalStateException("No fragment at position " + position); } **//初始化Fragment; ViewPager.addNewItem() ->instantiateItem->getItem()** @Override public Object instantiateItem(ViewGroup container, int position) { // On rotation the FragmentManager handles rotation. Therefore getItem() isn't called. // Copy the fragments that the FragmentManager finds so that we can store them in // instance variables for later. final Fragment fragment = (Fragment) super.instantiateItem(container, position); if (fragment instanceof SpeedDialFragment) { mSpeedDialFragment = (SpeedDialFragment) fragment; } else if (fragment instanceof CallLogFragment && position == TAB_INDEX_RECENTS) { mRecentsFragment = (CallLogFragment) fragment; } else if (fragment instanceof AllContactsFragment) { mAllContactsFragment = (AllContactsFragment) fragment; } else if (fragment instanceof CallLogFragment && position == TAB_INDEX_VOICEMAIL) { mVoicemailFragment = (CallLogFragment) fragment; } return fragment; } @Override public int getCount() { return mHasActiveVoicemailProvider ? TAB_COUNT_WITH_VOICEMAIL : TAB_COUNT_DEFAULT; } @Override public CharSequence getPageTitle(int position) { return mTabTitles[position]; } }
在每次 ViewPager 需要一个用以显示的 Object 的时候,函数instantiateItem都会被 ViewPager.addNewItem() 调用;函数instantiateItem中判断一下要生成的 Fragment 是否已经生成过了,如果生成过了,就使用旧的,旧的将被 Fragment.attach();如果没有,就调用 getItem() 生成一个新的,新的对象将被 FragmentTransation.add();
上述完成了mViewPager+Fragment的布局。
ViewPagerTabs的使用
ViewPagerTabs代码定义及实现:
//图标 mTabIcons = new int[TAB_COUNT_WITH_VOICEMAIL]; mTabIcons[TAB_INDEX_SPEED_DIAL] = R.drawable.tab_speed_dial; mTabIcons[TAB_INDEX_RECENTS] = R.drawable.tab_recents; mTabIcons[TAB_INDEX_ALL_CONTACTS] = R.drawable.tab_contacts; mTabIcons[TAB_INDEX_VOICEMAIL] = R.drawable.tab_voicemail; //初始化ViewPageTabs。 mViewPagerTabs = (ViewPagerTabs) parentView.findViewById(R.id.lists_pager_header); mViewPagerTabs.setTabIcons(mTabIcons); //mViewPagerTabs与ViewPager进行关联 mViewPagerTabs.setViewPager(mViewPager);
上述代码实现了mViewPagerTabs 和mViewPager关联,那么怎么实现将上方图标设置为mViewPager的Title的呢?下面分析mViewPagerTabs的实现:主要的看函数setViewPager():
public void setViewPager(ViewPager viewPager) { mPager = viewPager; //此处实现添加TAB项,并向addTabs函数传入上面的mViewPagerAdapter。 addTabs(mPager.getAdapter()); }
private void addTabs(PagerAdapter adapter) { mTabStrip.removeAllViews(); final int count = adapter.getCount(); for (int i = 0; i < count; i++) { //设置Tab项 addTab(adapter.getPageTitle(i), i); } }
下述代码就是详细的设置mViewPager的Tab页,并设置Tab页的监听事件。
private void addTab(CharSequence tabTitle, final int position) { View tabView; if (mTabIcons != null && position < mTabIcons.length) { View iconView = new View(getContext()); iconView.setBackgroundResource(mTabIcons[position]); iconView.setContentDescription(tabTitle); tabView = iconView; } else { final TextView textView = new TextView(getContext()); textView.setText(tabTitle); textView.setBackgroundResource(R.drawable.view_pager_tab_background); // Assign various text appearance related attributes to child views. if (mTextStyle > 0) { textView.setTypeface(textView.getTypeface(), mTextStyle); } if (mTextSize > 0) { textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize); } if (mTextColor != null) { textView.setTextColor(mTextColor); } textView.setAllCaps(mTextAllCaps); textView.setGravity(Gravity.CENTER); tabView = textView; } tabView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mPager.setCurrentItem(getRtlPosition(position)); } }); tabView.setOnLongClickListener(new OnTabLongClickListener(position)); tabView.setPadding(mSidePadding, 0, mSidePadding, 0); mTabStrip.addView(tabView, new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT, 1)); // Default to the first child being selected if (position == 0) { mPrevSelected = 0; tabView.setSelected(true); } }
至此也将mViewPagerTabs和mViewPager进行完美结合;mViewPagerTabs的作用就是讲Tab的设置独立出来,方便进行定制和复用。
后记
后续会进行通话记录页面的详细分析,也就是CallLogFragment的详细布局及数据实现。
Keep Moving!!!
- 【Dialer】android6.0拨号界面分析<二>
- 【Dialer】android6.0拨号界面分析<一>
- Dialer拨号定制功能
- Android 内置google dialer后发现拨号后,没有通话界面显示。
- Android原生应用Dialer--界面和数据库整体分析
- Android6.0的phone应用源码分析(3)——phone 拨号UI分析
- Android6.0的phone应用源码分析(4)——phone拨号流程分析
- Android6.0的phone应用源码分析(3)——phone 拨号UI分析
- Android6.0的phone应用源码分析(4)——phone拨号流程分析
- Android6.0锁屏源码分析之界面布局分析
- Android4.4 Telephony流程分析——拨号应用(Dialer)的通话记录加载过程
- 关于Android6.0 电话拨号器
- Android4.0(Phone)拨号启动过程分析(二)
- Android6.0源码分析之Settings(二)
- android6.0 power显示(亮度等)深入分析(二)DisplayManagerService
- android6.0 power显示(亮度等)深入分析(二)DisplayManagerService
- Android6.0源码分析之View(二)--measure
- Android6.0 SurfaceControl分析(二)SurfaceControl和SurfaceFlinger通信
- DFS-The partial sum problem
- Activity life times——Android
- UITableView 的完美平滑滚动
- new 和delete
- if-else
- 【Dialer】android6.0拨号界面分析<二>
- Xcode7基本操作 详解
- 关于IIS部署.net项目问题解决方法
- iOS app 更多操作 代码(邮件、facebook、twitter等)
- 邮箱几乎
- angularjs介绍
- Gcc常用命令详解
- (Boost)mutex scoped_lock
- spring mvc restful工程demo