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;
    }
}
导入这些代码就可以使用了
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章