android實現miui指示器的效果

先來看看效果圖:

    

看看Xml佈局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical">

    <!--自定義WiewPager-->
    <com.example.admin.viewpagerindicator.ViewPagerIndicator
        android:id="@+id/view_indicator"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:orientation="horizontal"
        android:background="#666666"
        app:visible_count="5">

    </com.example.admin.viewpagerindicator.ViewPagerIndicator>

    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">
    </android.support.v4.view.ViewPager>

</LinearLayout>

看看java代碼:

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.CornerPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.util.List;

/**
 * Created by admin on 2016/4/5.
 */
public class ViewPagerIndicator extends LinearLayout {

    //畫筆
    private Paint myPaint;
    private Path myPath;

    private int triangleWidth;
    private int triangleHeight;
    //三角形寬度和每個tab寬度的比例
    private float RADIO_TRIANGLE_WIDTH = 1/6f;
    //三角形的初始位置
    private int initTranslationX;
    //三角形移動的位置
    private int translationX;
    //一屏顯示幾個tab
    private int visibleTab;

    List<String> tabs;
    private ViewPager myViewPager;

    public String TAB_DEFAULT_COLOR = "#77FFFFFF";
    public String TAB_SELECTED_COLOR = "#FFFFFF";

    public interface PageOnChangedListener {
        void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);

        void onPageSelected(int position);

        void onPageScrollStateChanged(int state);
    }

    private PageOnChangedListener myListener;


    private static final int DEFAULT_VISIBLE_TAB = 5;

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


    public ViewPagerIndicator(Context context, AttributeSet attrs) {
        super(context, attrs);

        //初始化畫筆
        myPaint = new Paint();
        //消除鋸齒
        myPaint.setAntiAlias(true);
        myPaint.setColor(Color.parseColor("#ffffffff"));
        myPaint.setStyle(Paint.Style.FILL);
        //設置三角形爲圓角三角形
        myPaint.setPathEffect(new CornerPathEffect(5));


        //獲取可見tab數量
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ViewPagerIndicator);
        visibleTab = ta.getInt(R.styleable.ViewPagerIndicator_visible_count, DEFAULT_VISIBLE_TAB);
        if (visibleTab <= 0) {
            visibleTab = DEFAULT_VISIBLE_TAB;
        }
        ta.recycle();
        RADIO_TRIANGLE_WIDTH = 1 / 6f;
    }

    /**
     * 持方法會在加載xml佈局完成後調用
     */
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        int childCount = getChildCount();
        if (childCount == 0) return;
        for (int i = 0; i < childCount; i++) {
            View view = getChildAt(i);
            LinearLayout.LayoutParams lp = (LayoutParams) view.getLayoutParams();
            lp.weight = 0;
            lp.width = getScreenWidth() / visibleTab;
            view.setLayoutParams(lp);
        }
        setIndicatorEvent();
    }

    //當View發生變化時調用
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        //三角形底邊寬度=控件寬度/有幾個TAB*三角形寬度和每個tab寬度的比例
        triangleWidth = (int) (w / visibleTab * RADIO_TRIANGLE_WIDTH);

        //三角形初始位置=每個TAB的寬度-三角形的寬度/2
        initTranslationX = w / visibleTab / 2 - triangleWidth / 2;

        //初始化三角形
        initTriangle();
    }

    //在調用invalidate或者postInvalidate方法後調用
    @Override
    protected void dispatchDraw(Canvas canvas) {

        //繪製三角形
        canvas.save();
        //移動到初始位置
        canvas.translate(initTranslationX + translationX, getHeight() + 2);
        canvas.drawPath(myPath, myPaint);
        canvas.restore();
        super.dispatchDraw(canvas);
    }

    private void initTriangle() {

        //初始化三角形的高度 = 三角形的寬度/2(等腰三角形)
        triangleHeight = triangleWidth / 2;
        myPath = new Path();
        myPath.moveTo(0, 0);
        myPath.lineTo(triangleWidth, 0);
        myPath.lineTo(triangleWidth / 2, -triangleHeight);
        myPath.close();
    }

    public void scroll(int position, float positionOffset) {
        //每個Tab的寬度
        int tabWidth = getWidth() / visibleTab;
        translationX = (int) (tabWidth * (position + positionOffset));

        //當容器移動到最後一個tab時
        if (position >= (visibleTab - 2) && positionOffset > 0 && getChildCount() > visibleTab) {
            if (visibleTab != 1) {
                this.scrollTo((position - (visibleTab - 2)) * tabWidth + (int) (tabWidth * positionOffset), 0);
            } else {
                this.scrollTo(position * tabWidth + (int) (tabWidth * positionOffset), 0);
            }
        }

        //重繪三角形
        invalidate();
    }

    //動態添加TAB
    public void addTab(List<String> tabs) {
        if (tabs != null && tabs.size() != 0) {
            this.tabs = tabs;
            //移除所有view
            removeAllViews();
            for (String title : this.tabs) {
                //動態添加tab
                addView(generateView(title));
            }
        }
        setIndicatorEvent();
    }

    private View generateView(String title) {
        TextView tv = new TextView(getContext());
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        lp.width = getScreenWidth() / visibleTab;
        tv.setText(title);
        tv.setGravity(Gravity.CENTER);
        tv.setTextColor(Color.parseColor(TAB_DEFAULT_COLOR));
        tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
        tv.setLayoutParams(lp);
        return tv;
    }

    //動態設置顯示的tab數量
    public void setVisibleTabCount(int count) {
        this.visibleTab = count;
    }

    //提供給使用者的回調接口
    public void setOnPageChangeListener(PageOnChangedListener listener) {
        myListener = listener;
    }

    public void setViewPager(ViewPager viewPager,int position) {
        this.myViewPager = viewPager;


        myViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                scroll(position, positionOffset);
                if (myListener != null) {
                    myListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
                }
            }

            @Override
            public void onPageSelected(int position) {
                if (myListener != null) {
                    myListener.onPageSelected(position);
                }
                setTabSelectedColor(position);

            }

            @Override
            public void onPageScrollStateChanged(int state) {
                if (myListener != null) {
                    myListener.onPageScrollStateChanged(state);
                }
            }
        });
        myViewPager.setCurrentItem(position);
        //設置選中tab高粱
        setTabSelectedColor(position);

    }

    /**
     * 設置tab的點擊事件
     */
    public void setIndicatorEvent() {
        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            final int j = i;
            View view = getChildAt(i);
            if (view instanceof TextView) {
                view.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        myViewPager.setCurrentItem(j);
                    }
                });
            }
        }

    }

    //重置所有tab爲初始狀態
    public void resetTabColor() {
        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            final int j = i;
            View view = getChildAt(i);
            if(view instanceof TextView){
                ((TextView) view).setTextColor(Color.parseColor(TAB_DEFAULT_COLOR));
            }
        }
    }

    /**
     * 設置tab選中的顏色
     */
    public void setTabSelectedColor(int position) {
        resetTabColor();
        TextView tv = (TextView) getChildAt(position);
        tv.setTextColor(Color.parseColor(TAB_SELECTED_COLOR));
    }

    //獲取屏幕的實際寬度
    public int getScreenWidth() {

        WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics metrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(metrics);
        return metrics.widthPixels;
    }
}
導入這些代碼就可以使用了
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章