自定义ViewPager指示器

本文介绍了一种自定义的ViewPager指示器控件ViewPagerIndicator,该控件可以用于实现页面切换时的指示效果。文章详细解释了控件的实现原理,包括如何绘制指示器、如何响应页面变化以及如何设置监听器等。

效果

这里写图片描述

代码

public class ViewPagerIndicator extends LinearLayout {
    private Paint paint;
    private Context mContext;
    private Path path;
    private int mTriangleWidth;
    private int mTriangleHeight;
    private int mInitTranslationX;
    private int mTranslationX;
    private float INDICATOR_WIDTH_RATIO = 1/6f;
    public  int DEFAULT_VISIABLE_COUNT = 3;
    private  int visiableCount;
    private int mTotalCount;
    private List<TextView> mViews = new ArrayList<>();
    private int preIndex;
    public interface OnPageChangedListener{
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);

        public void onPageSelected(int position);

        public void onPageScrollStateChanged(int state);
    }

    public OnPageChangedListener mListener;

    /**
     * 提供给外界设置监听
     */
    public void setOnPageChangedListener(OnPageChangedListener listener){
        this.mListener = listener;
    }

    public ViewPagerIndicator(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.WHITE);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ViewPagerIndicator);
        visiableCount = typedArray.getInt(R.styleable.ViewPagerIndicator_visiableCount, DEFAULT_VISIABLE_COUNT);
        if(visiableCount <= 0 ){
            visiableCount = DEFAULT_VISIABLE_COUNT;
        }
        typedArray.recycle();
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        if(mTotalCount == 1){
            return;
        }
        canvas.save();
        canvas.translate(mInitTranslationX+mTranslationX,getHeight());
        canvas.drawPath(path,paint);
        canvas.restore();
    }

    public void scroll(int position,float positionOffset){
        int tabWidth = getWidth()/mTotalCount;
        mTranslationX = (int) (tabWidth*positionOffset+ tabWidth*position);
        if(mTotalCount == 2&&visiableCount==1){
//            mTranslationX = (int) (tabWidth*positionOffset+ 2*tabWidth*position);
        }
        if(position > (visiableCount - 2)&&visiableCount<mTotalCount&&positionOffset>0){
//            if(visiableCount!=1){
                scrollTo((position - (visiableCount -1))*tabWidth+(int)(tabWidth*positionOffset),0);
//            }else{
//                scrollTo((position*tabWidth+(int)(tabWidth*positionOffset)),0);
//            }
        }
        invalidate();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mTriangleWidth = (int) (getScreentWidth()/visiableCount*INDICATOR_WIDTH_RATIO);
            mInitTranslationX = getScreentWidth()/visiableCount/2-mTriangleWidth/2;
//        System.out.println("==========w: "+w+"mTriangleWidth: "+mTriangleWidth+"mInitTranslationX: "+mInitTranslationX);
//        System.out.println("=========width"+getLayoutParams().width);
        initTriangle();
    }
    public void initTriangle(){
        mTriangleHeight = (int) (mTriangleWidth/2*0.67);
        if(visiableCount == 1){
            mTriangleHeight = (int) (mTriangleWidth/2*0.4);
        }
        path = new Path();
        path.moveTo(0,0);
        path.lineTo(mTriangleWidth,0);
        path.lineTo(mTriangleWidth/2,-mTriangleHeight);
        path.close();
    }
    public void setTextView(List<String> title){
        mTotalCount = title.size();
        if(visiableCount > mTotalCount){
            visiableCount = mTotalCount;
        }
        int textViewWidth = getScreentWidth()/visiableCount;//每个textview宽度
        LinearLayout.LayoutParams layoutParams = (LayoutParams) getLayoutParams();
//        if(mTotalCount<DEFAULT_VISIABLE_COUNT){
//            layoutParams.width = getScreentWidth();
//        }else{
            layoutParams.width = textViewWidth*title.size();//父容器宽度
//        }
//        System.out.println("=======textViewWidth: "+textViewWidth+"size: "+title.size());
        for (int i = 0; i < title.size(); i++) {
            TextView textView = new TextView(mContext);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT);
            if(mTotalCount ==2&visiableCount==1){
                params.width = getScreentWidth();
            }else{
                params.weight = 1;
            }
            textView.setLayoutParams(params);
            textView.setText(title.get(i));
            textView.setGravity(Gravity.CENTER);
            textView.setTextSize(14);
            addView(textView);
            mViews.add(textView);
            textView.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    int position = mViews.indexOf(v);
                    mViewPager.setCurrentItem(position,true);
                }
            });
        }
    }
    private ViewPager mViewPager;
    public void setViewPager(ViewPager viewPager,int position){
        mViews.get(0).setTextColor(Color.RED);
        mViewPager = viewPager;
        mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                scroll(position,positionOffset );
                if(mListener!=null){
                    mListener.onPageScrolled(position,positionOffset,positionOffsetPixels);
                }
            }

            @Override
            public void onPageSelected(int position) {
                TextView textView = mViews.get(position);
                textView.setTextColor(Color.RED);
                if(mViews.get(preIndex)!=null){
                    mViews.get(preIndex).setTextColor(Color.WHITE);
                    preIndex = position;
                }
                if(mListener!=null){
                    mListener.onPageSelected(position);
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {
                if(mListener!=null){
                    mListener.onPageScrollStateChanged(state);
                }
            }
        });
        mViewPager.setCurrentItem(position);
    }

    /**
     * 返回以像素为单位的屏幕宽度,此处为720
     * @return
     */
    public int getScreentWidth(){
        WindowManager manager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics metrics = new DisplayMetrics();
        manager.getDefaultDisplay().getMetrics(metrics);
        return metrics.widthPixels;
    }

}
public class MainActivity extends FragmentActivity{
    private ViewPagerIndicator pagerIndicator;
    private ViewPager viewPager;
    private  List<String> mTitles = Arrays.asList("短信","电话","消息","语音","聊天","学习");
    private FragmentPagerAdapter pagerAdapter;
    private List<VPFragment> mContents = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initData();
    }
    public void initView(){
        pagerIndicator = (ViewPagerIndicator) findViewById(R.id.vp_indicator);
        viewPager = (ViewPager) findViewById(R.id.vp_pager);
    }
    public void initData(){
        for (String title:mTitles){
            VPFragment vpFragment = VPFragment.newInstance(title);
            mContents.add(vpFragment);
        }
        pagerIndicator.setTextView(mTitles);
        pagerAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {
            @Override
            public Fragment getItem(int position) {
                return mContents.get(position);
            }

            @Override
            public int getCount() {
                return mContents.size();
            }
        };
        viewPager.setAdapter(pagerAdapter);
        pagerIndicator.setViewPager(viewPager,0);
    }
}
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <com.example.hecun.myapplication.ViewPagerIndicator
        android:id="@+id/vp_indicator"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:background="#9e9e9e"
        app:visiableCount="1"
        >
    </com.example.hecun.myapplication.ViewPagerIndicator>
    <android.support.v4.view.ViewPager
        android:id="@+id/vp_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </android.support.v4.view.ViewPager>
</LinearLayout>
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值