drawable动画以及ConterView

照例:效果图

具体实现

  • 布局

                <?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"
        android:background="@color/aat_blue"
        android:orientation="vertical">
    
    
        <RelativeLayout
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:layout_gravity="center_horizontal">
    
            <ImageView
                android:id="@+id/imageview"
                android:layout_width="200dp"
                android:layout_height="200dp"
                android:background="@drawable/score" />
    
            <com.github.premnirmal.textcounter.CounterView
                android:id="@+id/value_tv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:layout_marginBottom="20dp"
                android:layout_marginTop="90dp"
                android:text="0"
                android:textColor="#ffffff"
                android:textSize="80sp" />
        </RelativeLayout>
    
        <Button
            android:id="@+id/tv_change_value"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="20dp"
            android:text="改变数值" />
    
    </LinearLayout>
    

ImageView 的background 是个蓝色背景图片

com.github.premnirmal.textcounter.CounterView 这个类 从github找的,可以自行search

  • 我这里是在fragment中的。大家自己随意

        /**
     * 描述:
     * 作者:Marc on 2016/7/22 10:03
     * 邮箱:aliali_ha@yeah.net
     */
    public class FragmentThree extends BaseFragment {
        ImageView imageView;
        CounterView valueTv;
        Button btn;
        CircularProgressDrawable drawable;
        Animator currentAnimation;
    
        @Override
        public void fetchData() {
            getmLoadingPager().loadData();
        }
    
        @Override
        protected View initSuccess() {
            View view = View.inflate(UIUtils.getContext(), R.layout.test_drawable, null);
            imageView = (ImageView) view.findViewById(R.id.imageview);
            valueTv = (CounterView) view.findViewById(R.id.value_tv);
            view.findViewById(R.id.tv_change_value).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Random random = new Random();
                    int score = random.nextInt(150);
                    valueTv.setStartValue(0);
                    valueTv.setEndValue(score);
                    valueTv.setIncrement(1);
                    valueTv.start();
                    startRingAnim(score);
                }
            });
    
            initViews();
    
            return view;
        }
    
    
        private void initViews() {
            drawable = new CircularProgressDrawable.Builder()
                    .setRingWidth(ScreenUtils.dip2px(UIUtils.getContext(),10))
                    .setRingWidth(ScreenUtils.dip2px(UIUtils.getContext(),9))
                    .setOutlineColor(
                            getResources().getColor(android.R.color.transparent))
                    .setRingColor(getResources().getColor(android.R.color.white))//外圈白色
                    .setCenterColor(
                            getResources().getColor(android.R.color.transparent))
                    .create();
    
            imageView.setImageDrawable(drawable);
    
            Typeface tf = Typeface.createFromAsset(getActivity().getAssets(),
                    "Uni_Sans_Light.otf");
            valueTv.setTypeface(tf);
            valueTv.setAutoFormat(false);
            valueTv.setFormatter(new Formatter() {
                @Override
                public String format(String prefix, String suffix, float value) {
                    return prefix
                            + NumberFormat.getNumberInstance(Locale.US).format(
                            value) + suffix;
                }
            });
            valueTv.setAutoStart(false);
        }
    
        @Override
        protected LoadingPager.LoadResult initData() {
            SystemClock.sleep(2000);
            return LoadingPager.LoadResult.SUCCESS;
        }
    
        /**
         * 开始圆圈动画
         *
         * @param score
         */
        private void startRingAnim(int score) {
            currentAnimation = prepareStyle2Animation(score);
            currentAnimation.start();
        }
    
        /**
         * 圆框动画
         *
         * @param duration
         * @return
         */
        private Animator prepareStyle2Animation(long duration) {
            AnimatorSet animation = new AnimatorSet();
            float progress = (duration / 150f) * 0.727f;
    
            ObjectAnimator progressAnimation = ObjectAnimator.ofFloat(drawable,
                    CircularProgressDrawable.PROGRESS_PROPERTY, 0.f, -progress);
            progressAnimation.setDuration(duration * 20);
            progressAnimation
                    .setInterpolator(new AccelerateDecelerateInterpolator());
    
            animation.play(progressAnimation);
    
            return animation;
        }
    }
    

这个类是我自己写的子类。取消fragment预加载。然后增加getLoading加载状态

CircularProgressDrawable 的代码如下

                    public class CircularProgressDrawable extends Drawable {
        /**
         * Factor to convert the factor to paint the arc.
         * <p/>
         * In this way the developer can use a more user-friendly [0..1f] progress
         */
        public static final int PROGRESS_FACTOR = -360;
        /**
         * Property Inner Circle Scale.
         * <p/>
         * The inner ring is supposed to defaults stay 3/4 radius off the outer ring at (75% scale), but this
         * property can make it grow or shrink via this equation: OuterRadius * Scale.
         * <p/>
         * A 100% scale will make the inner circle to be the same radius as the outer ring.
         */
        public static final String CIRCLE_SCALE_PROPERTY = "circleScale";
        /**
         * Property Progress of the outer circle.
         * <p/>
         * The progress of the circle. If {@link #setIndeterminate(boolean) indeterminate flag} is set
         * to FALSE, this property will be used to indicate the completion of the outer circle [0..1f].
         * <p/>
         * If set to TRUE, the drawable will activate the loading mode, where the drawable will
         * show a 90º arc which will be spinning around the outer circle as much as progress goes.
         */
        public static final String PROGRESS_PROPERTY = "progress";
        /**
         * Property Ring color.
         * <p/>
         * Changes the ring filling color
         */
        public static final String RING_COLOR_PROPERTY = "ringColor";
        /**
         * Property circle color.
         * <p/>
         * Changes the inner circle color
         */
        public static final String CIRCLE_COLOR_PROPERTY = "centerColor";
        /**
         * Property outline color.
         * <p/>
         * Changes the outline of the ring color.
         */
        public static final String OUTLINE_COLOR_PROPERTY = "outlineColor";
        /**
         * Logger Tag for Logging purposes.
         */
        public static final String TAG = "CircularProgressDrawable";
        /**
         * Paint object to draw the element.
         */
        private final Paint paint;
        /**
         * Ring progress.
         */
        protected float progress;
        /**
         * Color for the empty outer ring.
         */
        protected int outlineColor;
        /**
         * Color for the completed ring.
         */
        protected int ringColor;
        /**
         * Color for the inner circle.
         */
        protected int centerColor;
        /**
         * Rectangle where the filling ring will be drawn into.
         */
        protected final RectF arcElements;
        /**
         * Width of the filling ring.
         */
        protected final int ringWidth;
        /**
         * Scale of the inner circle. It will affect the inner circle size on this equation:
         * ([Biggest length of the Drawable] / 2) - (ringWidth / 2) * scale.
         */
        protected float circleScale;
        /**
         * Set if it is an indeterminate
         */
        protected boolean indeterminate;

        /**
         * Creates a new CouponDrawable.
         *
         * @param ringWidth    Width of the filled ring
         * @param circleScale  Scale difference between the outer ring and the inner circle
         * @param outlineColor Color for the outline color
         * @param ringColor    Color for the filled ring
         * @param centerColor  Color for the center element
         */
        CircularProgressDrawable(int ringWidth, float circleScale, int outlineColor, int ringColor, int centerColor) {
            this.progress = 0;
            this.outlineColor = outlineColor;
            this.ringColor = ringColor;
            this.centerColor = centerColor;
            this.paint = new Paint();
            this.paint.setAntiAlias(true);
            this.ringWidth = ringWidth;
            this.arcElements = new RectF();
            this.circleScale = circleScale;
            this.indeterminate = false;
        }

        @Override
        public void draw(Canvas canvas) {
            final Rect bounds = getBounds();

            // Calculations on the different components sizes
            int size = Math.min(bounds.height(), bounds.width());
            float outerRadius = (size / 2) - (ringWidth / 2);
            float innerRadius = outerRadius * circleScale;
            float offsetX = (bounds.width() - outerRadius * 2) / 2;
            float offsetY = (bounds.height() - outerRadius * 2) / 2;

            // Outline Circle
            paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeWidth(1);
            paint.setColor(outlineColor);
            canvas.drawCircle(bounds.centerX(), bounds.centerY(), outerRadius, paint);

            // Inner circle
            paint.setStyle(Paint.Style.FILL);
            paint.setColor(centerColor);
            canvas.drawCircle(bounds.centerX(), bounds.centerY(), innerRadius, paint);

            int halfRingWidth = ringWidth / 2;
            float arcX0 = offsetX + halfRingWidth;
            float arcY0 = offsetY + halfRingWidth;
            float arcX = offsetX + outerRadius * 2 - halfRingWidth;
            float arcY = offsetY + outerRadius * 2 - halfRingWidth;

            // Outer Circle
            paint.setColor(ringColor);
            paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeWidth(ringWidth);
            paint.setStrokeCap(Paint.Cap.ROUND);
            arcElements.set(arcX0 - 7, arcY0 - 7, arcX + 7, arcY + 7);
            if (indeterminate) {
                canvas.drawArc(arcElements, progress, 50, false, paint);
            } else {
                canvas.drawArc(arcElements, 139, progress, false, paint);
            }
        }

        @Override
        public void setAlpha(int alpha) {
            paint.setAlpha(alpha);
        }

        @Override
        public void setColorFilter(ColorFilter cf) {
            paint.setColorFilter(cf);
        }

        @Override
        public int getOpacity() {
            return 1 - paint.getAlpha();
        }


        /**
         * Returns the progress of the outer ring.
         * <p/>
         * Will output a correct value only when the indeterminate mode is set to FALSE.
         *
         * @return Progress of the outer ring.
         */
        public float getProgress() {
            return progress / PROGRESS_FACTOR;
        }

        /**
         * Sets the progress [0..1f]
         *
         * @param progress Sets the progress
         */
        public void setProgress(float progress) {
            if (indeterminate) {
                this.progress = progress;
            } else {
                this.progress = PROGRESS_FACTOR * progress;
            }
            invalidateSelf();
        }

        /**
         * Returns the inner circle scale.
         *
         * @return Inner circle scale in float multiplier.
         */
        public float getCircleScale() {
            return circleScale;
        }

        /**
         * Sets the inner circle scale.
         *
         * @param circleScale Inner circle scale.
         */
        public void setCircleScale(float circleScale) {
            this.circleScale = circleScale;
            invalidateSelf();
        }

        /**
         * Get the indeterminate status of the Drawable
         *
         * @return TRUE if the Drawable is in indeterminate mode or FALSE if it is in progress mode.
         */
        public boolean isIndeterminate() {
            return indeterminate;
        }

        /**
         * Sets the indeterminate parameter.
         * <p/>
         * The indeterminate parameter will change the behavior of the Drawable. If the indeterminate
         * mode is set to FALSE, the outer ring will be able to be filled by using {@link #setProgress(float) setProgress}.
         * <p/>
         * Otherwise the drawable will enter "loading mode" and a 90º arc will be able to be spinned around
         * the inner circle.
         * <p/>
         * <b>By default, indeterminate mode is set to FALSE.</b>
         *
         * @param indeterminate TRUE to activate loading mode. FALSE to activate progress mode.
         */
        public void setIndeterminate(boolean indeterminate) {
            this.indeterminate = indeterminate;
        }

        /**
         * Gets the outline color.
         *
         * @return Outline color of the empty ring.
         */
        public int getOutlineColor() {
            return outlineColor;
        }

        /**
         * Gets the filled ring color.
         *
         * @return Returns the filled ring color.
         */
        public int getRingColor() {
            return ringColor;
        }

        /**
         * Gets the color of the inner circle.
         *
         * @return Inner circle color.
         */
        public int getCenterColor() {
            return centerColor;
        }

        /**
         * Sets the empty progress outline color.
         *
         * @param outlineColor Outline color in #AARRGGBB format.
         */
        public void setOutlineColor(int outlineColor) {
            this.outlineColor = outlineColor;
            invalidateSelf();
        }

        /**
         * Sets the progress ring  color.
         *
         * @param ringColor Ring color in #AARRGGBB format.
         */
        public void setRingColor(int ringColor) {
            this.ringColor = ringColor;
            invalidateSelf();
        }

        /**
         * Sets the inner circle color.
         *
         * @param centerColor Inner circle color in #AARRGGBB format.
         */
        public void setCenterColor(int centerColor) {
            this.centerColor = centerColor;
            invalidateSelf();
        }

        /**
         * Helper class to manage the creation of a CircularProgressDrawable
         *
         * @author Saul Diaz <sefford@gmail.com>
         */
        public static class Builder {

            /**
             * Witdh of the stroke of the filled ring
             */
            int ringWidth;
            /**
             * Color of the outline of the empty ring in #AARRGGBB mode.
             */
            int outlineColor;
            /**
             * Color of the filled ring in #AARRGGBB mode.
             */
            int ringColor;
            /**
             * Color of the inner circle in #AARRGGBB mode.
             */
            int centerColor;
            /**
             * Scale between the outer ring and the inner circle
             */
            float circleScale = 0.75f;

            /**
             * Sets the ring width.
             *
             * @param ringWidth Default ring width
             * @return This builder
             */
            public Builder setRingWidth(int ringWidth) {
                this.ringWidth = ringWidth;
                return this;
            }

            /**
             * Sets the default empty outer ring outline color.
             *
             * @param outlineColor Outline color in #AARRGGBB format.
             * @return
             */
            public Builder setOutlineColor(int outlineColor) {
                this.outlineColor = outlineColor;
                return this;
            }

            /**
             * Sets the progress ring color.
             *
             * @param ringColor Ring color in #AARRGGBB format.
             * @returns This Builder
             */
            public Builder setRingColor(int ringColor) {
                this.ringColor = ringColor;
                return this;
            }


            /**
             * Sets the inner circle color.
             *
             * @param centerColor Inner circle color in #AARRGGBB format.
             * @return This builder
             */
            public Builder setCenterColor(int centerColor) {
                this.centerColor = centerColor;
                return this;
            }

            /**
             * Sets the inner circle scale. Defaults to 0.75.
             *
             * @param circleScale Inner circle scale.
             * @return This builder
             */
            public Builder setInnerCircleScale(float circleScale) {
                this.circleScale = circleScale;
                return this;
            }

            /**
             * Creates a new CircularProgressDrawable with the requested parameters
             *
             * @return New CircularProgressDrawableInstance
             */
            public CircularProgressDrawable create() {
                return new CircularProgressDrawable(ringWidth, circleScale, outlineColor, ringColor, centerColor);
            }

        }
    }

没错 ,看到这么多英文注释。确实是github找的。能实现效果就好

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值