天天看點

Android底部Tab頁基于ViewPager的實作源碼下載下傳

在衆多主流App中,包括QQ,微信等,為了和ios的UI保持統一,很多App使用的都是底部導航,當然在Android中也并不反對這種設計。這篇文章使用ViewPager實作這種效果。首先看實作效果圖吧。效果圖中包含了ViewPager的嵌套。

Android底部Tab頁基于ViewPager的實作源碼下載下傳
Android底部Tab頁基于ViewPager的實作源碼下載下傳

在讨論實作之前,我們先來回憶一下,之前我們是如何實作的。

之前的實作方法,我們無法是先進行布局,再編寫邏輯。而布局,底部有一定高度的Tab,一般由4個或者5個,也有3個的,具體視應用而定,而Tab上方則是一個FrameLayout,用于作為fragment的容器。在Activity中處理對應的點選事件的邏輯,需要自己控制Fragment的顯示與隐藏,有時候控制不好甚至會帶來莫名其妙的問題。

那麼有沒有一種簡單的方法,避免我們自己編寫Fragment切換的邏輯呢,其實是有的,ViewPager正是這個控件,這時候有人問了,一般放在底部的導航内容區域是點選切換的,不會滑動切換(微信除外),ViewPager是會滑動切換的,那麼怎麼解決這個問題呢。答案是重寫ViewPager,提供一個布爾變量,用于控制是否支援滑動切換,通過這個變量,對對應事件的函數onTouchEvent和onInterceptTouchEvent進行重寫,如果該變量設定為true,即支援滑動切換,也就是ViewPager的預設行為,我們使用父類的方法進行處理。如果是false,我們不進行處理或者不進行攔截,傳回false即可。這樣,我們的ViewPager子類的代碼就成了這樣。

public class CustomViewPager extends ViewPager {
    private boolean isCanScroll = false;

    public CustomViewPager(Context context) {
        super(context);
    }

    public CustomViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public boolean isCanScroll() {
        return isCanScroll;
    }

    public void setCanScroll(boolean isCanScroll) {
        this.isCanScroll = isCanScroll;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (isCanScroll) {
            return super.onTouchEvent(ev);
        } else {
            return false;
        }
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (isCanScroll) {
            return super.onInterceptTouchEvent(ev);
        } else {
            return false;
        }
    }
}
           

使用我們自己的ViewPager代替預設的ViewPager進行布局就可以了,如下

<com.kltz.tabdemo.view.CustomViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        >
    </com.kltz.tabdemo.view.CustomViewPager>
           

然後我們簡單進行底部Tab的布局

<RadioGroup
        android:id="@+id/radio"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#e8e8e8"
        android:orientation="horizontal">

        <RadioButton
            android:id="@+id/tab1"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/btn"
            android:button="@drawable/btn"
            android:gravity="center"
            android:text="Tab1"
            />

        <RadioButton
            android:id="@+id/tab2"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/btn"
            android:button="@null"
            android:gravity="center"
            android:text="Tab2"
            />

        <RadioButton
            android:id="@+id/tab3"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/btn"
            android:button="@null"
            android:gravity="center"
            android:text="Tab3"
            />

        <RadioButton
            android:id="@+id/tab4"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/btn"
            android:button="@null"
            android:gravity="center"
            android:text="Tab4"
            />
    </RadioGroup>
           

上面兩段布局外圍是一個線性布局,使用了layout_weight屬性控制了内容區域的高度。

然後Tab按鈕的點選是有效果的,編寫我們的Selector作為按鈕的背景,這裡随便選了兩個顔色,實際開發中用對應圖檔代替。

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

最後來看看我們簡單的邏輯處理,對RadioGroup設定監聽,當點選了之後判斷是哪一個Button,将ViewPager顯示為對應的頁,使用setCurrentItem函數,第二個參數傳false,代表無切換動畫。

public class MainActivity extends AppCompatActivity{
    private CustomViewPager mViewPager;
    private RadioGroup mRadioGroup;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        mViewPager= (CustomViewPager) findViewById(R.id.viewpager);
        mRadioGroup= (RadioGroup) findViewById(R.id.radio);
        mViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
            @Override
            public Fragment getItem(int i) {
                return BaseFragment.newInstance(i);
            }

            @Override
            public int getCount() {
                return ;
            }
        });
        mRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                switch (checkedId) {
                    case R.id.tab1:
                        mViewPager.setCurrentItem(, false);
                        break;
                    case R.id.tab2:
                        mViewPager.setCurrentItem(, false);
                        break;
                    case R.id.tab3:
                        mViewPager.setCurrentItem(, false);
                        break;
                    case R.id.tab4:
                        mViewPager.setCurrentItem(, false);
                        break;
                }
            }
        });
    }

}
           

很簡單的Tab實作有木有,有時候系統有的元件,我們需要的功能如果與其相似,可以改造一下直接拿來用,沒必要重複造輪子。

源碼下載下傳

http://download.csdn.net/detail/sbsujjbcy/8881617

如果你覺得對你有幫助,點個贊吧!