天天看點

多種多樣的App主界面Tab實作方法——利用ViewPagerIndicator+ViewPager實作Tab

視訊位址:http://www.imooc.com/video/5905

這次的實作方法要借用一個第三方項目開源庫:ViewPagerIndicator

是以要涉及到如何導入library項目開源庫,因為我是用的Android Studio,不知道操作的童鞋可以看看在Android Studio中導入library項目開源庫

下面就是示範的效果:

多種多樣的App主界面Tab實作方法——利用ViewPagerIndicator+ViewPager實作Tab

可以看到在切換到相應的Tab的時候,會有一個下劃線訓示着,這就是ViewPagerIndicator提供的,通過ViewPagerIndicator,我們不必再像前三篇文章中那樣需要類似于

bottom.xml

的布局了,是以也不必去實作Tab對應的點選事件了,以及用于差別”點選“的效果。

首先,還是展示一下目錄清單(其中包含了導入的library項目開源庫–ViewPagerIndicator,跟tabtest4是同級的):

多種多樣的App主界面Tab實作方法——利用ViewPagerIndicator+ViewPager實作Tab

activity_main比較的簡單:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#C5DAED"
    android:orientation="vertical" >

    <include layout="@layout/top" />

    <com.viewpagerindicator.TabPageIndicator
        android:id="@+id/id_indicator"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent" >
    </com.viewpagerindicator.TabPageIndicator>

    <android.support.v4.view.ViewPager
        android:id="@+id/id_viewpager"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </android.support.v4.view.ViewPager>
</LinearLayout>
           

主布局檔案比較的簡單,top即為:

多種多樣的App主界面Tab實作方法——利用ViewPagerIndicator+ViewPager實作Tab

對應的布局,接着是需要借助的TabPageIndicator,最後是ViewPager。

在目錄中還有一個frag.xml的布局檔案,是在執行個體化Fragment需要用到的。

還是先把MainActivity先貼出來,友善後面的講解,在這之前,還需要說明一點,在導入的library中已經附帶了一個v4的包,是以不需要我們自己另外再為Module添加Library Dependency了:

public class MainActivity extends AppCompatActivity {
    private ViewPager mViewPager;
    private TabPageIndicator mTabPageIndicator;
    private TabAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getSupportActionBar().hide();
        initView();
    }

    private void initView() {
        mViewPager= (ViewPager) findViewById(R.id.id_viewpager);
        mTabPageIndicator= (TabPageIndicator) findViewById(R.id.id_indicator);
        mAdapter=new TabAdapter(getSupportFragmentManager());
        mViewPager.setAdapter(mAdapter);
        mTabPageIndicator.setViewPager(mViewPager,);//将TabPageIndicator與ViewPager關聯,第二個參數為訓示器(即前面說的那個下劃線)的初始位置
    }
}
           

可以看到,相比于前三篇的MainActivity,這次的十分的簡潔,大緻是三步:

1、初始化ViewPager、TabPageIndicator、Adapter

2、給ViewPager設定擴充卡

3、将TabPageIndicator與ViewPager關聯

當然,這裡所用的TabAdapter是自己定義的:

public class TabAdapter extends FragmentPagerAdapter {
    public static String[] TITLES=new String[]{"課程","問答","求課","學習","計劃"};

    public TabAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        TabFragment fragment=new TabFragment(position);
        return fragment;
    }

    @Override
    public int getCount() {
        return TITLES.length;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return TITLES[position];
    }
}
           

TabAdapter 繼承自FragmentPagerAdapter ,代碼的内容就跟前一篇中的差不多,隻不過這裡多重寫了一個getPageTitle方法,用于傳回page的title,而這裡傳回的title就對應着Tab的title(TabPageIndicator會根據這裡傳回的title自動設定Tab的title)。

既然有FragmentPagerAdapter ,那就少不了Fragment,可以看到在getItem中就使用了自定義的TabFragment:

public class TabFragment extends Fragment {
    private int position;

    public TabFragment(int position) {
        this.position=position;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view=inflater.inflate(R.layout.frag,container,false);
        TextView tv= (TextView) view.findViewById(R.id.id_tv);
        tv.setText(TabAdapter.TITLES[position]);
        return view;
    }
}
           

自定義的TabFragment會根據構造參數傳來的position來設定frag布局中TextView的内容。

看到了這兒,是不是覺得大功告成了?那你可以運作一下程式試試效果,怎麼樣?是不是覺得少了點什麼?說好的訓示下劃線去哪兒了?怎麼Tab的字型看着有點不對頭?

沒錯,确實少了一點東西,就是TabPageIndicator的style,因為訓示位置的下劃線及顔色,Tab的字型風格、大小等都是由TabPageIndicator的style所決定的。

是以需要把下面自定義的内容添加到src\main\res\values中的styles.xml中,然後在AndroidManifest.xml中将

<application ... android:theme="@style/AppTheme">

改為

android:theme="@style/MyTheme"

即可。

<style name="MyTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="vpiTabPageIndicatorStyle">@style/MyWidget.TabPageIndicator</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:animationDuration"></item>
        <item name="android:windowContentOverlay">@null</item>
    </style>

    <style name="MyWidget.TabPageIndicator" parent="Widget">
        <item name="android:gravity">center</item>
        <item name="android:background">@drawable/vpi__tab_indicator</item>
        <item name="android:paddingLeft">dip</item>
        <item name="android:paddingRight">dip</item>
        <item name="android:paddingTop">dp</item>
        <item name="android:paddingBottom">dp</item>
        <item name="android:textAppearance">@style/MyTextAppearance.TabPageIndicator</item>
        <item name="android:textSize">sp</item>
        <item name="android:maxLines"></item>
    </style>

    <style name="MyTextAppearance.TabPageIndicator" parent="Widget">
        <item name="android:textStyle">bold</item>
        <item name="android:textColor">@android:color/black</item>
    </style>
           

可以看到自定義的style有三個,MyTheme、MyWidget.TabPageIndicator和MyTextAppearance.TabPageIndicator。

其中MyTheme跟原來就有的AppTheme類似,是作為App的Theme,在其中就通過

vpiTabPageIndicatorStyle

定義了TabPageIndicator的style(需要注意,在視訊中MyTheme的parent為

AppBaseTheme

,但是在實際開發中,需要視情況而定,因為可能

AppBaseTheme

不存在,而且前面提到過MyTheme跟原來就有的AppTheme類似,是以可以使用與AppTheme相同的parent)。

然後是MyWidget.TabPageIndicator,被MyTheme中的

vpiTabPageIndicatorStyle

所引用,用作TabPageIndicator的style,并且在其中引用了MyTextAppearance.TabPageIndicator,還有某些屬性是引用的導入的library自帶的。

而MyTextAppearance.TabPageIndicator包含了Tab的字型風格以及顔色。

源碼:http://download.csdn.net/download/qq_22804827/9459234

繼續閱讀