PageIndicator兩種動畫效果
阿新 • • 發佈:2019-01-10
最近看了一個關於PageIndicator的開源專案,發現效果挺好,遍著手寫了一兩個效果。上程式碼
自定義屬性:
<declare-styleable name="PageIndicatorView"> <attr name="dot_radius" format="dimension" /> <attr name="dot_margin" format="dimension" /> <attr name="dot_count" format="integer" /> <attr name="dot_bg" format="reference" /> </declare-styleable>
//第一種效果
public class CircleSmoothPageIndictor extends View implements ViewPager.OnPageChangeListener { private int mDotRadius; private int mDotMargin; private int mDotCount; private int mDotSytle; private ViewPager mViewPager; private RectF mRectF; private boolean mFirstLoad = true; private List<Integer> mDotLeftXs = new ArrayList<>(10); public CircleSmoothPageIndictor(Context context, @Nullable AttributeSet attrs) { super(context, attrs); TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.PageIndicatorView); mDotRadius = typedArray.getDimensionPixelSize(R.styleable.PageIndicatorView_dot_radius, 10); mDotMargin = typedArray.getDimensionPixelOffset(R.styleable.PageIndicatorView_dot_margin, 10); mDotCount = typedArray.getInteger(R.styleable.PageIndicatorView_dot_count, 0); mDotSytle = typedArray.getResourceId(R.styleable.PageIndicatorView_dot_bg,0); typedArray.recycle(); initRectF(); } private void initRectF(){ mRectF = new RectF(); mRectF.left = 0; mRectF.top = 0; mRectF.right = mRectF.left + mDotRadius; mRectF.bottom = mDotRadius; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width = mDotRadius * mDotCount + (mDotCount-1)* mDotMargin; int height = mDotRadius; setMeasuredDimension(width,height); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.parseColor("#B48A8A")); drawAtOnce(canvas); } private void drawAtOnce(Canvas canvas){ Log.d("getMeasuredHeight()",""+getMeasuredHeight()); Paint paint = new Paint(); if (mFirstLoad){ int dotX; for (int i =0;i< mDotCount;i++){ if (i ==0){ dotX = mDotRadius/2; }else{ dotX = mDotRadius/2 + (mDotRadius+ mDotMargin)*i; } mDotLeftXs.add(dotX-mDotRadius/2); paint.setColor(Color.parseColor("#3F48CC")); paint.setStyle(Paint.Style.FILL); paint.setAntiAlias(true); canvas.drawCircle(dotX,mDotRadius/2,mDotRadius/2,paint); } } paint.setColor(Color.parseColor("#000000")); canvas.drawRoundRect(mRectF,mDotRadius,mDotRadius,paint); } public void setViewPager(ViewPager viewPager){ mViewPager = viewPager; mViewPager.setOnPageChangeListener(this); } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { Log.d("xjbin",positionOffset+"");//0-1 if (mRectF == null){ mRectF = new RectF();//rect 的高度最大mRedius的一半,長度最大為mRedius的mMargin } if (mDotLeftXs != null && mDotLeftXs.size() > 0){ mRectF.left = mDotLeftXs.get(position) + (mDotRadius+mDotMargin)*positionOffset/1; mRectF.top = 0; mRectF.right = mRectF.left + mDotRadius; mRectF.bottom = mDotRadius; invalidate(); } } @Override public void onPageSelected(int position) { if (mRectF != null){ mRectF.setEmpty(); } } @Override public void onPageScrollStateChanged(int state) { } }
//第二種效果
引用開源https://github.com/XjbJoy/PageIndicatorView.gitpublic class RectAnimPageIndictor extends View implements ViewPager.OnPageChangeListener { private int mDotRadius; private int mDotMargin; private int mDotCount; private int mDotSytle; private ViewPager mViewPager; private RectF mRectF; private boolean mFirstLoad = true; private List<Integer> mDotLeftXs = new ArrayList<>(10); public RectAnimPageIndictor(Context context, @Nullable AttributeSet attrs) { super(context, attrs); TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.PageIndicatorView); mDotRadius = typedArray.getDimensionPixelSize(R.styleable.PageIndicatorView_dot_radius, 10); mDotMargin = typedArray.getDimensionPixelOffset(R.styleable.PageIndicatorView_dot_margin, 10); mDotCount = typedArray.getInteger(R.styleable.PageIndicatorView_dot_count, 0); mDotSytle = typedArray.getResourceId(R.styleable.PageIndicatorView_dot_bg,0); typedArray.recycle(); initRectF(); } private void initRectF(){ mRectF = new RectF(); mRectF.left = 0; mRectF.top = 0; mRectF.right = mRectF.left + mDotRadius; mRectF.bottom = mDotRadius; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width = mDotRadius * mDotCount + (mDotCount-1)* mDotMargin; int height = mDotRadius; setMeasuredDimension(width,height); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.parseColor("#B48A8A")); drawAtOnce(canvas); } private void drawAtOnce(Canvas canvas){ Log.d("getMeasuredHeight()",""+getMeasuredHeight()); Paint paint = new Paint(); if (mFirstLoad){ int dotX; for (int i =0;i< mDotCount;i++){ if (i ==0){ dotX = mDotRadius/2; }else{ dotX = mDotRadius/2 + (mDotRadius+ mDotMargin)*i; } mDotLeftXs.add(dotX-mDotRadius/2); paint.setColor(Color.parseColor("#3F48CC")); paint.setStyle(Paint.Style.FILL); paint.setAntiAlias(true); canvas.drawCircle(dotX,mDotRadius/2,mDotRadius/2,paint); } } paint.setColor(Color.parseColor("#000000")); canvas.drawRoundRect(mRectF,mDotRadius,mDotRadius,paint); } public void setViewPager(ViewPager viewPager){ mViewPager = viewPager; mViewPager.setOnPageChangeListener(this); } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { Log.d("xjbin",positionOffset+"");//0-1 if (mRectF == null){ mRectF = new RectF();//rect 的高度最大mRedius的一半,長度最大為圓點的mMargin } int maxDotWidth = mDotMargin; if (mDotLeftXs != null && mDotLeftXs.size() > 0){ mRectF.top = 0; mRectF.bottom = mDotRadius; //0-0.5之間變長 if (positionOffset < 0.5){ mRectF.left = mDotLeftXs.get(position) + mDotRadius/2f*positionOffset/0.5f; mRectF.right = mDotLeftXs.get(position) + mDotRadius/2f*positionOffset/0.5f + mDotRadius + mDotMargin * positionOffset/0.5f; }else{ //0.5-1之間變短到正常長度 float leftOffset = (mDotRadius/2f + mDotMargin) * (positionOffset-0.5f)/0.5f; mRectF.left = (mDotLeftXs.get(position) + mDotRadius/2f) + leftOffset; float offset = mDotRadius/2f * (positionOffset/1f); mRectF.right = mDotLeftXs.get(position+1)+ mDotRadius/2f + offset; } invalidate(); } } @Override public void onPageSelected(int position) { } @Override public void onPageScrollStateChanged(int state) { } }