com.alex.view.loop.IndicatorView.java Source code

Java tutorial

Introduction

Here is the source code for com.alex.view.loop.IndicatorView.java

Source

/*
 * Copyright 2016 Alex_ZHOU
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
  * @author Alex_ZHOU
 *
 * @author junweiliu 2016/6/14
 */

package com.alex.view.loop;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;

import com.alex.view.R;

/**
 * 
 * Created by junweiliu on 16/6/15.
 */
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class IndicatorView extends LinearLayout implements ViewPager.OnPageChangeListener {
    /**
     * ?
     */
    private int childViewCount = 0;
    /**
     * margin
     */
    private int mInterval;
    /**
     * ??
     */
    private int mCurrentPostion = 0;
    /**
     * 
     */
    private Bitmap normalBp;
    /**
     * 
     */
    private Bitmap selectBp;
    /**
     * Vp
     */
    private ViewPager mViewPager;
    /**
     * ?
     */
    private int mWidth;
    /**
     * ?
     */
    private int mHeight;
    /**
     * ?
     */
    private int mRadius;
    /**
     * ?
     */
    private int normalColor;
    /**
     * ?
     */
    private int selectColor;
    /**
     * ?
     */
    private boolean isCirculate;

    /**
     * ??ViewPager?
     */
    public interface OnPageChangeListener {

        void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);

        void onPageSelected(int position);

        void onPageScrollStateChanged(int state);

    }

    /**
     * ?
     */
    private OnPageChangeListener mListener;

    /**
     * 
     *
     * @param listener
     */
    public void setOnPageChangeListener(OnPageChangeListener listener) {
        this.mListener = listener;
    }

    public IndicatorView(Context context) {
        this(context, null);
    }

    public IndicatorView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public IndicatorView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // ?
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.IndicatorView);
        normalBp = drawableToBitamp(ta.getDrawable(R.styleable.IndicatorView_normalDrawable));
        selectBp = drawableToBitamp(ta.getDrawable(R.styleable.IndicatorView_selectDrawable));
        mInterval = ta.getDimensionPixelOffset(R.styleable.IndicatorView_indicatorInterval, 6);
        normalColor = ta.getColor(R.styleable.IndicatorView_normalColor, Color.GRAY);
        selectColor = ta.getColor(R.styleable.IndicatorView_selectColor, Color.RED);
        mRadius = ta.getInteger(R.styleable.IndicatorView_indicatorRadius, 6);
        isCirculate = ta.getBoolean(R.styleable.IndicatorView_isCirculate, true);
        ta.recycle();
        // ?
        init();

    }

    /**
     * ??
     */
    private void init() {
        // ?
        if (null == normalBp) {
            normalBp = makeIndicatorBp(normalColor);
        }
        if (null == selectBp) {
            selectBp = makeIndicatorBp(selectColor);
        }
        mWidth = normalBp.getWidth();
        mHeight = normalBp.getWidth();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
        int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
        // wrap_content,?
        setMeasuredDimension((widthMode == MeasureSpec.EXACTLY) ? sizeWidth : (mWidth + mInterval) * childViewCount,
                (heightMode == MeasureSpec.EXACTLY) ? sizeHeight : mHeight);
    }

    /**
     * ?
     *
     * @param canvas
     */
    @Override
    protected void dispatchDraw(Canvas canvas) {
        // 
        if (getChildCount() < childViewCount && getChildCount() == 0) {
            for (int i = 0; i < childViewCount; i++) {
                addView(makeIndicatorItem());
            }
            // 
            setIndicatorState(mCurrentPostion);
        }
        super.dispatchDraw(canvas);
    }

    /**
     * Vp
     *
     * @param viewpager
     */
    public void setViewPager(ViewPager viewpager) {
        if (null == viewpager) {
            return;
        }
        if (null == viewpager.getAdapter()) {
            throw new IllegalStateException("ViewPager does not have adapter.");
        }

        this.mViewPager = viewpager;
        this.mViewPager.addOnPageChangeListener(this);
        this.childViewCount = viewpager.getAdapter().getCount();
        invalidate();
    }

    /**
     * Vp
     *
     * @param viewpager
     * @param currposition ??
     */
    public void setViewPager(ViewPager viewpager, int currposition) {
        if (null == viewpager) {
            return;
        }
        if (null == viewpager.getAdapter()) {
            throw new IllegalStateException("ViewPager does not have adapter.");
        }
        this.mViewPager = viewpager;
        this.mViewPager.addOnPageChangeListener(this);
        this.childViewCount = viewpager.getAdapter().getCount();
        this.mCurrentPostion = currposition;
        invalidate();
    }

    /**
     * vp
     *
     * @param childViewCount ?
     * @param viewpager      vp
     */
    public void setViewPager(int childViewCount, ViewPager viewpager) {
        if (null == viewpager) {
            return;
        }
        if (null == viewpager.getAdapter()) {
            throw new IllegalStateException("ViewPager does not have adapter.");
        }
        this.mViewPager = viewpager;
        this.mViewPager.addOnPageChangeListener(this);
        this.childViewCount = childViewCount;
        removeAllViews();
        invalidate();
    }

    /**
     * 
     *
     * @return
     */
    private View makeIndicatorItem() {
        ImageView iv = new ImageView(getContext());
        LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        lp.width = normalBp.getWidth();
        lp.height = normalBp.getHeight();
        lp.rightMargin = mInterval;
        iv.setImageBitmap(normalBp);
        iv.setLayoutParams(lp);
        return iv;
    }

    /**
     * 
     *
     * @param color ??
     * @return
     */
    private Bitmap makeIndicatorBp(int color) {
        Bitmap normalBp = Bitmap.createBitmap(mRadius * 2, mRadius * 2, Bitmap.Config.ARGB_8888);
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setColor(color);
        Canvas canvas = new Canvas(normalBp);
        canvas.drawCircle(mRadius, mRadius, mRadius, paint);
        return normalBp;
    }

    /**
     * drawablebitmap
     *
     * @param drawable
     * @return
     */
    private Bitmap drawableToBitamp(Drawable drawable) {
        if (null == drawable) {
            return null;
        }
        if (drawable instanceof BitmapDrawable) {
            BitmapDrawable bd = (BitmapDrawable) drawable;
            return bd.getBitmap();
        }
        int w = drawable.getIntrinsicWidth();
        int h = drawable.getIntrinsicHeight();
        Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, w, h);
        drawable.draw(canvas);
        return bitmap;
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        if (null != mListener) {
            mListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
        }
    }

    @Override
    public void onPageSelected(int position) {
        if (isCirculate && 0 != childViewCount) {
            position %= childViewCount;
        }
        setIndicatorState(position);
        if (null != mListener) {
            mListener.onPageSelected(position);
        }
    }

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

    /**
     * ?
     *
     * @param position
     */
    public void setIndicatorState(int position) {
        for (int i = 0; i < getChildCount(); i++) {
            if (i == position)
                ((ImageView) getChildAt(i)).setImageBitmap(selectBp);
            else
                ((ImageView) getChildAt(i)).setImageBitmap(normalBp);
        }
    }

}