使用tablayout 打造高度不同的tab

要實現下圖這樣的效果,請忽略紅線。java


本人的實現綜指是以最少的代碼來實現。android

每個tab使用自定義view.每一個tab是由兩個控件疊加的。沒有選中的時候下面一層的背景爲透明,選中的時候下面一層的背景爲放大效果的圖片。tab的上面一層的背景爲白色。app

tabLayout.setupWithViewPager(mViewPager);
for (int i = 0; i < tabLayout.getTabCount(); i++) {
    TabLayout.Tab tab = tabLayout.getTabAt(i);
    if(tab==null){
        continue;
    }
    View view = mSectionsPagerAdapter.getTabView(this,i);
    tab.setCustomView(view);
}

adapter
ide

public class SectionsPagerAdapter extends FragmentPagerAdapter {
    private List<Fragment> mFragments = new ArrayList<>();
    private int[] imageResId = {
            R.drawable.bottom_button_index,
            R.drawable.bottom_button_study,
            R.drawable.bottom_button_activity,
            R.drawable.bottom_button_my
    };//圖片資源
    private int[] titleResId = {
            R.string.bottom_button_index,
            R.string.bottom_button_study,
            R.string.bottom_button_activity,
            R.string.bottom_button_my
    };//標題資源
    public SectionsPagerAdapter(FragmentManager fm,Fragment... fragments) {
        super(fm);
        mFragments.addAll(Arrays.asList(fragments));
    }

    @Override
    public Fragment getItem(int position) {
        return mFragments.get(position);
    }

    @Override
    public int getCount() {
        // Show 3 total pages.
        return 4;
    }

    //加載自定義佈局
    View getTabView(Context context, int position){
        View view = LayoutInflater.from(context).inflate(R.layout.bottom_button,null);
        ((ImageView) view.findViewById(R.id.bottom_button_img)).setImageDrawable(context.getResources().getDrawable(imageResId[position]));
        ((TextView) view.findViewById(R.id.bottom_button_title)).setText(context.getResources().getString(titleResId[position]));
        return view;
    }
}

每一個tab的佈局佈局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/bottom_button"
    android:orientation="vertical">
<!--外層的LinearLayout即爲下面一層的放大區域,選中時設置放大的背景圖。固然也能夠用FrameLayout。裏層的LinearLayout爲按鈕,背景爲白色,選中時背景爲綠色。
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="@dimen/tab_height_limit"//這裏須要給放大的區域留一個空間,否則看不到放大的效果
        android:orientation="vertical"
        android:background="@drawable/bottom_button2">

        <ImageView
            android:id="@+id/bottom_button_img"
            android:layout_width="@dimen/tab_img_width"
            android:layout_height="@dimen/tab_img_width"
            android:layout_gravity="center_horizontal"
            android:scaleType="fitCenter"
            tools:src="@drawable/bottom_button_index" />

        <TextView
            android:id="@+id/bottom_button_title"
            android:layout_width="match_parent"
            android:layout_height="@dimen/bottom_btn_text_height"
            android:layout_gravity="bottom"
            android:gravity="bottom|center_horizontal"
            tools:text="@string/bottom_button_index" />
    </LinearLayout>
</LinearLayout>

外層的圖片bottom_button.xml,選中時是放大的圖片,不選中時是透明的this

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/tab_selected_bg" android:state_selected="true" />
    <item android:drawable="@android:color/transparent" />
</selector>

裏層的背景圖片botton_button2.xml,選中時是透明的,不選中時白色的。spa

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@android:color/white" android:state_selected="false"  />
    <item android:drawable="@android:color/transparent" android:state_selected="true"  />
</selector>

這樣就基本上實現了上述功能。不過你會發現第一個tab最開始是沒有這種效果的。code

無論你是設置xml

android:state_...="true"

仍是實現tabselectlistener,去手動更改背景圖片也好。效果都不理想。事件

由此我在想 android:state_selected =true 是如何工做的?怎麼樣才叫selected? 

最終我發現view中有一個方法叫setSelected(true),經過如下代碼使第一個tab剛開始時實現咱們的效果。

if (tabLayout.getSelectedTabPosition() == 0){
    tabLayout.getTabAt(0).getCustomView().setSelected(true);
}

由此不得不吐槽一下,既然 tabLayout.getSelectedTabPosition()==0,爲啥還要我手動去設置selected效果。

還有viewpager剛開始時,也就是最初顯示viewpager時也不觸發onpageselected事件。就算你設置setcurrentitem(0)也沒有用,由於如今就是顯示的就是第0頁。

最後再提一點就是,若是設置了tablayout的ontabselectedlistener,你會發現點擊tab以後,viewpager不切換了,看一下源代碼就知道爲何了。

相關文章
相關標籤/搜索