Android 原生實現Tap切換字型變色下劃線移動

艾陽丶發表於2017-04-26

前言

我們知道,現在實現Tab切換之類的效果都是android TabLayout+ViewPager配合使用。剛開始開發那段時期,第一次看見某app滑動tap標題變色下劃線移動效果,當時非常喜歡,於是從網上找資料,發現它是一個用自定義view繪製畫圖實現的。本人不是對這種實現有偏見,只是覺得它太繁瑣複雜,但是我的個性是有些功能搞懂Viewpager的原理後,自己動手就能實現了。

好了,廢話不說了,上原始碼和效果圖Tap切換字型變色下劃線移動

實現邏輯

首先,效果看起來還是蠻棒的,程式碼怎麼寫呢?原始碼已經發了, 下面貼上出來,關鍵點都在程式碼中講解了。首先,從整體控制元件佈局上看,它包含三個部分,分別是一個FragmentActivity(v4.app.fragment 需要宿主繼承)、2個fragment、一個viewpager。

其次,是下劃線的測量和計算。

最後,主要看viewpager的頁面切換監聽。

 

實現程式碼

public class MainActivity extends FragmentActivity implements View.OnClickListener, ViewPager.OnPageChangeListener{

    private TextView mTextViews1;
    private TextView mTextViews2;
    private ViewPager mViewpager;
    /*
     * tab下劃線
     */
    private LinearLayout.LayoutParams params;
    private int width;
    private LinearLayout tabView;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initUi();
    }
    //初始化
    private void initUi() {
        mTextViews1= (TextView) findViewById(R.id.news_tab);
        mTextViews2=(TextView) findViewById(R.id.daily_tab);
        tabView= (LinearLayout)findViewById(R.id.tab_view);
        mViewpager =(ViewPager) findViewById(R.id.viewpager);
        mViewpager.addOnPageChangeListener(this);
        mTextViews1.setOnClickListener(this);
        mTextViews2.setOnClickListener(this);
        initTabLine();

        List<Fragment> mList=new ArrayList<Fragment>();
        mList.add(new OneFragment());
        mList.add(new OneFragment());
        mViewpager.setAdapter(new MissonPagerAdapter(getSupportFragmentManager(),mList));
        mViewpager.setOffscreenPageLimit(0);//設定頁面快取數量  預設為2表示當前頁左右的快取個數  加當前頁其實3個頁面
    }
    /**
     * 初始化tab下劃線
     * 實現步驟:
     * 1、獲取螢幕大小 比例設定寬度
     * 2、然後有幾個tab就分幾份  移動時改變外邊距引數
     */
    private void initTabLine() {
        params = (LinearLayout.LayoutParams) tabView.getLayoutParams();
        DisplayMetrics metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);
        width = metrics.widthPixels / 2;
        params.width = width;
        tabView.setLayoutParams(params);
    }

    /**
     * 滑動監聽
     * @param position 第一個頁面索引為0
     * @param positionOffset  從左向右 0-0.99  反之 0.99-0 (主要跟右邊頁面有關係) 當0.5以上下一頁 反之回到滑動前
     * @param positionOffsetPixels 整數值
     */
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        if(positionOffset!=0){
            mTextViews2.setTextColor(Color.argb(255, (int) (255*positionOffset), (int) (115*positionOffset),0));
            mTextViews1.setTextColor(Color.argb(255, (int) (255*(1-positionOffset)), (int) (115*(1-positionOffset)),0));
            params.leftMargin =  (int)(width*positionOffset);
            tabView.setLayoutParams(params);
        }
    }
    //滑動結束
    @Override
    public void onPageSelected(int position) {
        if (position==0){
            mTextViews1.setTextColor(Color.argb( 255, 255, 115, 0));
            mTextViews2.setTextColor(Color.argb( 255, 0, 0, 0));
            params.leftMargin=0;
            tabView.setLayoutParams(params);
        }else if (position==1){
            params.leftMargin = width;
            tabView.setLayoutParams(params);
            mTextViews1.setTextColor(Color.argb(255,0,0,0));
            mTextViews2.setTextColor(Color.argb( 255, 255, 155, 0));
        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }

    /**
     * 點選切換
     */
    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.news_tab:
                mViewpager.setCurrentItem(0,true);
                params.leftMargin=width/2;
                tabView.setLayoutParams(params);
                break;

            case R.id.daily_tab:
                mViewpager.setCurrentItem(1,true);
                params.leftMargin = width*2+width/2;
                tabView.setLayoutParams(params);
                break;
        }
    }

佈局檔案就補貼出來了,很簡單。歡迎大家下載demo。

 

原始碼下載:Tap切換字型變色下劃線移動

 

相關文章