com.android.contacts,[转载]在Android4.0中Contacts拨号界面分页方式剖析(源码)

最后希望朋友们按照我的思路自己跟一遍代码,这样您将会得到更大的收获,小弟才疏学浅,有肯定地方不到位,希望大家指正!

如果我的一点点总结,对您的有一丁点帮助,那么我将会感到莫大的欣慰!

在Android4.0中,Contacts 拨号界面的分页方式是怎么样的呢?是通过传统的TabHost+tab的方式吗?

不是的,而是通过ActionBar + tab

+ view Pager的方式实现的。

具体的实现详情,请见下面的详细剖析。

在DialtactsActivity类中,通过向ActionBar中添加Tab的方式实现分页,每页显示的内容,则通过ViewPager对象设置的Adapter对象来设置。

在onCreate()方法中

顺序调用

setupDialer();

setupCallLog();

setupFavorites();

方法加载将三哥tab加载到ActionBar中

下面以setupDialer

为例,逐行描述一下其加载过程

private void setupDialer()

{

final Tab tab = getActionBar().newTab();

tab.setContentDescription(R.string.dialerIconLabel);

tab.setTabListener(mTabListener);

tab.setIcon(R.drawable.ic_tab_dialer);

getActionBar().addTab(tab);

}

final Tab tab =

getActionBar().newTab();

新建一个Tab页

tab.setContentDescription(R.string.dialerIconLabel);

为该tab也设置描述,基本上没意义,也不显示,只是存储一些临时的数据

设置监听器,当点击该tab页时触发该事件

tab.setIcon(R.drawable.ic_tab_dialer);

给该tab也添加显示的图标

getActionBar().addTab(tab);

将该tab页添加到ActionBar中

其它几个方法的具体实现也类似。

那么,您想想, Activity

多次调用getActionBar().addTab(tab) 添加tab都是添加到一个ActionBar中了吗?

有此疑问的朋友请点击

那么创建三个tab就可以了吗?

不是的,

DialtactsActivity中又对ActionBar进行了下面的处理

getActionBar().setDisplayShowHomeEnabled(false);

第一句将ActionBar设置为“Tab导航”模式

第二句将ActionBar设置为标题不可见

第三句将ActionBar设置为显示主界面按钮不可用

是不是感觉缺了点什么?tab

页内显示的内容呢?

先别急,我们继续往下走

上文提到tab.setTabListener(mTabListener),现在我们来看看这个监听器到底做了什么

private final TabListener

mTabListener = new TabListener() {

@Override

public void onTabUnselected(Tab tab, FragmentTransaction ft)

{

}

@Override

public void onTabSelected(Tab tab, FragmentTransaction ft)

{

if (mViewPager.getCurrentItem() != tab.getPosition()) {

mViewPager.setCurrentItem(tab.getPosition(), true);

}

….

}

@Override

public void onTabReselected(Tab tab, FragmentTransaction ft)

{

}

};

看到了吗?

if (mViewPager.getCurrentItem() !=

tab.getPosition()) {

mViewPager.setCurrentItem(tab.getPosition(), true);

}

将tab和ViewPager联系到一起了。

tab.getPosition()获得当前tab的位置返回int值

mViewPager.getCurrentItem()返回滑动页当前的item编号,返回int值

mViewPager.setCurrentItem(tab.getPosition(), true);

设置viewPager的平滑滚动到tab设置的位置

当tab的位置和ViewPager的当前页不等时,重新设置viewpager的当前页

看样子就是这了,tab页的内容肯定就是通过mViewPager来设置的。

下面我们继续跟进mViewPager

private ViewPager mViewPager;

首先声明mViewPager

为类的私有成员

在onCreate()方法中被初始化

第一句

mViewPager = (ViewPager)

findViewById(R.id.pager);

我们来看类的布局文件dialtacts_activity.xml文件

在该文件中有一处

android:id="@+id/pager"

android:layout_width="match_parent"

android:layout_height="match_parent" />

原来mViewPager

就是布局中的pager啊

com.android.contacts.activities.DialtactsViewPager

好像不是传统的ViewPager,难道DialtactsViewPager继承了DialtactsViewPager?

答案是正确的

public class

DialtactsViewPager extends ViewPager

好,我们接下来继续看看viewPager对象往下都做了些什么

第二句mViewPager.setAdapter(new

ViewPagerAdapter(getFragmentManager()));

为ViewPager对象设置了一个Adapter

我们来看看Adapter的具体内容

public class

ViewPagerAdapter extends FragmentPagerAdapter {

private DialpadFragment mDialpadFragment;

private CallLogFragment mCallLogFragment;

private PhoneFavoriteFragment mPhoneFavoriteFragment;

public ViewPagerAdapter(FragmentManager fm) {

super(fm);

}

@Override

public Fragment getItem(int position) {

switch (position) {

case TAB_INDEX_DIALER:

if (mDialpadFragment == null) {

mDialpadFragment

= new DialpadFragment();

}

return mDialpadFragment;

}

throw new IllegalStateException("No fragment at position " +

position);

}

@Override

public int getCount() {

return TAB_INDEX_COUNT;

}

}

哦,我明白了,原来在Adapter里面建立了三种Fragment对象

然后通过当前的选中位置来返回当前页是哪个fragment对象,在fragment对象里面设置页面的具体内容。

既然Adapter设置好了,已经可以滑动了,也就是已经可以实现切换效果了,google接下来还要干什么了呢?

mViewPager.setOnPageChangeListener(mPageChangeListener);

private int mCurrentPosition = -1;

private int mNextPosition = -1;

@Override

public void onPageScrolled(

int position, float positionOffset, int positionOffsetPixels)

{

}

@Override

public void onPageSelected(int position) {

final ActionBar actionBar = getActionBar();

if (mCurrentPosition == position) {

Log.w(TAG,

"Previous position and next position became same (" + position +

")");

}

actionBar.selectTab(actionBar.getTabAt(position));

mNextPosition = position;

}

public void setCurrentPosition(int position) {

mCurrentPosition

= position;

}

@Override

public void onPageScrollStateChanged(int state) {

switch (state) {

case ViewPager.SCROLL_STATE_IDLE: {

if (mCurrentPosition >= 0) {

sendFragmentVisibilityChange(mCurrentPosition,

false);

}

if (mNextPosition >= 0) {

sendFragmentVisibilityChange(mNextPosition, true);

}

mCurrentPosition = mNextPosition;

break;

}

case ViewPager.SCROLL_STATE_DRAGGING:

case ViewPager.SCROLL_STATE_SETTLING:

default:

break;

}

}

}

private Fragment

getFragmentAt(int position) {

switch (position) {

case TAB_INDEX_DIALER:

return mDialpadFragment;

case TAB_INDEX_CALL_LOG:

return

mCallLogFragment;

case TAB_INDEX_FAVORITES:

return mPhoneFavoriteFragment;

default:

throw new IllegalStateException("Unknown fragment index: " +

position);

}

}

private void sendFragmentVisibilityChange(int position, boolean

visibility) {

final Fragment fragment = getFragmentAt(position);

if (fragment instanceof ViewPagerVisibilityListener) {

((ViewPagerVisibilityListener)

fragment).onVisibilityChanged(visibility);

}

}

通过上面的操作,了解到PageChangeListener 的主要作用是在页面滑动过程中,menu菜单键有可见到不可见的。

最后希望朋友们按照我的思路自己跟一遍代码,这样您将会得到更大的收获,小弟才疏学浅,有肯定地方不到位,希望大家指正!

如果我的一点点总结,对您的有一丁点帮助,那么我将会感到莫大的欣慰!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值