【Dialer】android6.0拨号界面分析<二>

题记

大家清明假期快乐!!!!

下面简单介绍下拨号界面运用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!!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值