一个不是那么优美的圆形进度条续(基本还原原应用里面的效果)

之前帮别人写了一个不是那么优美的圆形进度条,效果图大家也看过了。但是后某人不满意,说原应用是倒计时时间最后5s,才开始显示数字的,同时转完一圈需要的时间只能是30s左右。然后我掐时间看了一下虽然总时间设置的是30s,但是总共转完一圈却耗费了50多秒的样子。

问题出来了:

1. 转圈总时间30s不正确

2. 数字显示时间不正确

3. 数字1的动画没原应用的好(2144手机令牌)

花了一个小时搞了一下,忍不住终于射出来了什么东西,解决了上面的3个问题(请看1从有到无);国际惯例效果图先行,先看下改善之后的效果图(不好请不要吐我口水)

当对于一个问题无从下手的话,有时候反编译看下别人家的源代码也是不错的选择。反编译工具用的是Android逆向助手。

看了下它的代码,发现他原来是用定时器区去完成这个工作的

 public class MyProgressCount extends CountDownTimer
  {
    public MyProgressCount()
    {
      super(30000L, 25L);
    }

    public void onFinish()
    {
      start();
    }

    public void onTick(long paramLong)
    {
      MainFragment.this.count = (MainFragment.this.max - (float)paramLong);
      MainFragment.this.progress_bar.setProgress(MainFragment.this.count);
      MainFragment.this.circleRadius = (MainFragment.this.progressBar_width / 2);
      MainFragment.this.circleX = (MainFragment.this.window_width / 2 - MainFragment.this.circleRadius);
      MainFragment.this.circleY = (MainFragment.this.circleY_init + MainFragment.this.circleRadius);
      if (MainFragment.this.count >= MainFragment.this.max - 200.0F)
      {
        MainFragment.this.round_text.setVisibility(8);
        MainFragment.this.password_time = (DateUtils.getStringToDate(DateUtils.getCurrentDate()) + MainFragment.this.d_value);
        MainFragment.this.count = 0.0F;
        MainFragment.this.password = Util.DynamicPassword(MainFragment.this.uid, MainFragment.this.password_time - (MainFragment.this.password_time % 30L), MainFragment.this.token);
        DbManage.getInstance(MainFragment.this.activity).saveActionStr(MainFragment.this.password, MainFragment.this.password_time - (MainFragment.this.password_time % 30L));
        MainFragment.this.stringArr = MainFragment.this.password.toCharArray();
        MainFragment.this.dynamic_password.setText(MainFragment.this.stringArr[0] + " " + MainFragment.this.stringArr[1] + " " + MainFragment.this.stringArr[2] + "   " + MainFragment.this.stringArr[3] + " " + MainFragment.this.stringArr[4] + " " + MainFragment.this.stringArr[5]);
      }
      if (MainFragment.this.count > MainFragment.this.max * 5.0F / 6.0F)
      {
        float f = MainFragment.this.max * 5.0F / 6.0F;
        f = (float)(MainFragment.this.count / 1000.0D);
        double d = 3.141592653589793D * 12.0F * f / 180.0D;
        int i = (int)(Math.sin(d) * MainFragment.this.progress_bar.getWidth() / 2.0D);
        int j = (int)(Math.cos(d) * MainFragment.this.progress_bar.getWidth() / 2.0D);
        Util.setLayout(MainFragment.this.round_text, MainFragment.this.circleX + MainFragment.this.circleRadius - Math.abs(i), MainFragment.this.circleY - Math.abs(j));
        i = ((Integer)ColorUtils.evaluate((float)((MainFragment.this.count / MainFragment.this.max - 0.75D) * 4.0D), Integer.valueOf(-1853686), Integer.valueOf(-3407872))).intValue();
        MainFragment.this.round_text.setBackgroundDrawable(Util.getRoundBg(i, 100));
        MainFragment.this.round_text.setTextColor(-1);
        if ((f >= 25.0F) && (f <= 30.0F))
        {
          MainFragment.this.round_text.setVisibility(0);
          MainFragment.this.round_text.setText((int)(31.0F - f));
          if ((f >= 29.0F) && (f < 30.0F) && (!(MainFragment.this.scaleAnimation.hasStarted())))
          {
            MainFragment.this.round_text.setAnimation(MainFragment.this.scaleAnimation);
            MainFragment.this.scaleAnimation.setAnimationListener(new Animation.AnimationListener()
            {
              public void onAnimationEnd(Animation paramAnimation)
              {
                MainFragment.this.scaleAnimation = new ScaleAnimation(1.0F, 0.0F, 1.0F, 0.0F, 1, 0.5F, 1, 0.5F);
                MainFragment.this.scaleAnimation.setDuration(MainFragment.this.duration);
              }

              public void onAnimationRepeat(Animation paramAnimation)
              {
              }

              public void onAnimationStart(Animation paramAnimation)
              {
              }
            });
            MainFragment.this.scaleAnimation.start();
          }
        }
        while (true)
        {
          MainFragment.this.round_text.invalidate();
          return;
          MainFragment.this.round_text.setVisibility(8);
        }
      }
      MainFragment.this.round_text.setVisibility(8);
    }
  }

至于里面数字的显示用的是一个TextView动态改变他的位置以及内容和背景颜色,然后配合上CircleProgressBar就行了(当然里面涉及到有颜色值改变的计算),详情看下文给出的源代码。

当然看了反编译代码思路说起来很轻松,估计是个稍微会一点安卓的人都知道,那下面我们改进入正题了(talk is cheap,show me the fucking code).

里面牵涉到4个类,工具类:UtilColorUtils;界面类:TestActivity01CircleProgressBar

先看下CircleProgressBar里面有些什么狗屎东西:

package com.example.tangxb.myapplication;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;

public class CircleProgressBar extends View {
    private static final int DEFAULT_BACKGROUND_COLOR = Color.parseColor("#ffffff");
    private static final int DEFAULT_MAX = 100;
    private static final int DEFAULT_PROGRESS_COLOR = Color.parseColor("#54bfad");
    private static final int DEFAULT_PROGRESS_END_COLOR = 0;
    private static final int DEFAULT_SIZE = 80;
    private static final boolean DEFAULT_TRANSITION_ENABLE = false;
    private static final int END_ANGLE = 360;
    private static final float MAX_SWEEP_ANGLE = 360.0F;
    private static final String TAG = "ArcProgressBar";
    private float DEFAULT_STROKE_WIDTH;
    int c;
    Context context;
    SizeChangeListener l;
    private float mMax;
    private Path mPath;
    private float mProgress;
    private int mProgressBackgroundColor;
    private Paint mProgressBgPaint;
    private RectF mProgressBgRectF;
    private int mProgressColor;
    private int mProgressEndColor;
    private int mProgressEndColor2;
    private Paint mProgressPaint;
    private Paint mProgressPaintEnd;
    private RectF mProgressRectF;
    private float mStrokeWith;
    private float unitAngle;

    public CircleProgressBar(Context paramContext) {
        this(paramContext, null);
    }

    public CircleProgressBar(Context paramContext, AttributeSet paramAttributeSet) {
        this(paramContext, paramAttributeSet, 0);
    }

    public CircleProgressBar(Context paramContext, AttributeSet paramAttributeSet, int paramInt) {
        super(paramContext, paramAttributeSet, paramInt);
        this.DEFAULT_STROKE_WIDTH = 6.0F;
        this.mProgressRectF = new RectF(0.0F, 0.0F, 0.0F, 0.0F);
        this.mProgressBgRectF = new RectF(0.0F, 0.0F, 0.0F, 0.0F);
        this.mStrokeWith = 0.0F;
        this.unitAngle = 0.0F;
        this.context = paramContext;
        loadStyledAttr(paramContext, paramAttributeSet, paramInt);
        initPaint();
    }

    private void drawProgress(Canvas paramCanvas) {
        int i = getWidth() / 2;
        int j = i - Util.dip2px(this.context, 13.0F);
        paramCanvas.drawArc(new RectF(i - j, i - j, i + j, i + j), getStartAngle(), getSweepAngel(), getUseCenter(), this.mProgressPaint);
    }

    private void drawProgressBg(Canvas paramCanvas) {
        int i = getWidth() / 2;
        int j = i - Util.dip2px(this.context, 20.0F);
        paramCanvas.drawArc(new RectF(i - j, i - j, i + j, i + j), getStartAngle(), 360.0F, true, this.mProgressBgPaint);
    }

    private void drawProgressNum(Canvas paramCanvas) {
        this.mProgressBgRectF.left = 30.0F;
        this.mProgressBgRectF.top = 30.0F;
        this.mProgressBgRectF.right = 105.0F;
        this.mProgressBgRectF.bottom = 105.0F;
        Paint localPaint = new Paint(1);
        localPaint.setColor(Color.rgb(216, 76, 75));
        localPaint.setStyle(Paint.Style.STROKE);
        paramCanvas.drawArc(this.mProgressBgRectF, getStartAngle(), 360.0F, getUseCenter(), localPaint);
    }

    private int getStartAngle() {
        return -90;
    }

    private float getSweepAngel() {
        return (this.unitAngle * this.mProgress);
    }

    private boolean getUseCenter() {
        return false;
    }

    private void initPaint() {
        this.mPath = new Path();
        this.mProgressPaint = new Paint(1);
        this.mProgressPaint.setColor(this.mProgressColor);
        this.mProgressBgPaint = new Paint(1);
        this.mProgressBgPaint.setColor(this.mProgressBackgroundColor);
        this.mProgressBgPaint.setAntiAlias(true);
        this.mProgressPaint.setStyle(Paint.Style.STROKE);
        this.mProgressPaint.setStrokeJoin(Paint.Join.ROUND);
        this.mProgressPaint.setStrokeWidth(Util.dip2px(this.context, 10.0F));
        this.mProgressBgPaint.setStyle(Paint.Style.FILL);
        this.mProgressBgPaint.setStrokeWidth(this.mStrokeWith);
    }

    private void loadStyledAttr(Context paramContext, AttributeSet paramAttributeSet, int paramInt) {
        // 颜色设置
        this.mProgressBackgroundColor = DEFAULT_BACKGROUND_COLOR;
        this.mProgressColor = Color.parseColor("#ff48d502");
        this.mProgressEndColor = Color.parseColor("#ffe3b70a");
        this.mProgressEndColor2 = Color.parseColor("#ffcc0000");
        this.mMax = 100;
        this.mProgress = 0;
        this.DEFAULT_STROKE_WIDTH = Util.dip2px(getContext(), this.DEFAULT_STROKE_WIDTH);
        this.mStrokeWith = Util.dip2px(getContext(), this.DEFAULT_STROKE_WIDTH);
    }

    private int measure(int paramInt) {
        int i = View.MeasureSpec.getMode(paramInt);
        paramInt = View.MeasureSpec.getSize(paramInt);
        if (i == 1073741824)
            return paramInt;
        return Util.dip2px(getContext(), 80.0F);
    }

    private void onProgressChanged() {
        this.c = ((Integer) ColorUtils.evaluate((float) (this.mProgress / this.mMax * 1.5D), Integer.valueOf(this.mProgressColor), Integer.valueOf(this.mProgressEndColor))).intValue();
        this.mProgressPaint.setColor(this.c);
    }

    private void onProgressChangedEnd() {
        this.c = ((Integer) ColorUtils.evaluate((float) ((float) (this.mProgress / this.mMax - 0.75D) * 4.0D), Integer.valueOf(this.mProgressEndColor), Integer.valueOf(this.mProgressEndColor2))).intValue();
        this.mProgressPaint.setColor(this.c);
    }

    private void setUnitProgress() {
        this.unitAngle = (360.0F / this.mMax);
    }

    public float getMax() {
        return this.mMax;
    }

    public double getPrgoress() {
        return this.mProgress;
    }

    protected void onDraw(Canvas paramCanvas) {
        drawProgressBg(paramCanvas);
        drawProgress(paramCanvas);
    }

    protected void onMeasure(int paramInt1, int paramInt2) {
        setMeasuredDimension(measure(paramInt1), measure(paramInt2));
        setUnitProgress();
    }

    protected void onSizeChanged(int paramInt1, int paramInt2, int paramInt3, int paramInt4) {
        this.l.sizeChanged(paramInt1, paramInt2, paramInt3, paramInt4);
        super.onSizeChanged(paramInt1, paramInt2, paramInt3, paramInt4);
    }

    public void setMax(float paramFloat) {
        this.mMax = paramFloat;
        setUnitProgress();
        invalidate();
    }

    public void setProgress(float paramFloat) {
        this.mProgress = paramFloat;
        if (paramFloat <= this.mMax * 0.75D)
            onProgressChanged();
        if (paramFloat > this.mMax * 0.75D)
            onProgressChangedEnd();
        invalidate();
    }

    public void setProgressWithAnim(int paramInt1, int paramInt2, long paramLong) {
        ValueAnimator localValueAnimator = ValueAnimator.ofInt(new int[]{paramInt1, paramInt2});
        localValueAnimator.setDuration(paramLong);
        localValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            public void onAnimationUpdate(ValueAnimator paramValueAnimator) {
            }
        });
        localValueAnimator.setInterpolator(new LinearInterpolator());
        localValueAnimator.start();
    }

    public void setProgressWithAnim(int paramInt, long paramLong) {
        setProgressWithAnim(0, paramInt, paramLong);
    }

    /**
     * 这里可用getViewTreeObserver()去做监听,消除耦合
     *
     * @param paramSizeChangeListener
     */
    public void setSizeChangeListener(SizeChangeListener paramSizeChangeListener) {
        this.l = paramSizeChangeListener;
    }

    public interface SizeChangeListener {
        void sizeChanged(int paramInt1, int paramInt2, int paramInt3, int paramInt4);
    }
}

源码有点长,但是里面画的东西却很少

 protected void onDraw(Canvas paramCanvas) {
        drawProgressBg(paramCanvas);
        drawProgress(paramCanvas);
    }

然后看下TestActivity01:

package com.example.tangxb.myapplication;

import android.graphics.Color;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
import android.widget.TextView;

/**
 * Created by Tangxb on 2016/4/19.
 */
public class TestActivity01 extends AppCompatActivity {
    private int circleRadius;
    private int circleX;
    private int circleY;
    private int circleY_init;
    private int duration = 1200;
    private float count = 0.0F;
    private float max;
    private MyProgressCount progressCount;
    private CircleProgressBar progress_bar;
    /**
     * 宽高为20dp的TextView
     */
    private TextView round_text;
    // 第一个效果表现没有第二个好
    Animation scaleAnimation1 = new ScaleAnimation(1.0F, 0.4F, 1.0F, 0.4F, Animation.RELATIVE_TO_SELF, 0.3F, Animation.RELATIVE_TO_SELF, 0.2F);
    // 使用第二个替代了第一个
    Animation scaleAnimation = new ScaleAnimation(1.0F, 0.0F, 1.0F, 0.0F, Animation.RELATIVE_TO_SELF, 0.5F, Animation.RELATIVE_TO_SELF, 0.5F);
    private int window_width;
    private int progressBar_width;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.acttivity_test);
        init();
    }

    private void init() {
        scaleAnimation.setDuration(this.duration);
        max = 30000.0F;
        circleY_init = Util.dip2px(this, 85.0F);
        window_width = getWindowManager().getDefaultDisplay().getWidth();
        progress_bar = ((CircleProgressBar) findViewById(R.id.cpb));
        round_text = ((TextView) findViewById(R.id.tv));
        progress_bar.setMax(max);
        progress_bar.setSizeChangeListener(new CircleProgressBar.SizeChangeListener() {
            public void sizeChanged(int paramInt1, int paramInt2, int paramInt3, int paramInt4) {
                progressBar_width = progress_bar.getWidth();
                if (progressCount == null) {
                    progressCount = new MyProgressCount();
                }
                progressCount.start();
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        if (progressBar_width != 0) {
            if (progressCount == null) {
                progressCount = new MyProgressCount();
            }
            progressCount.start();
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (progressCount != null) {
            progressCount.cancel();
            progressCount = null;
        }
    }

    class MyProgressCount extends CountDownTimer {
        public MyProgressCount() {
            super(30000L, 25L);
        }

        public void onFinish() {
            start();
        }

        public void onTick(long paramLong) {
            count = (max - (float) paramLong);
            // 设置进度
            progress_bar.setProgress(count);
            circleRadius = (progressBar_width / 2);
            circleX = (window_width / 2 - circleRadius);
            circleY = (circleY_init + circleRadius);
            if (count >= max - 200.0F) {
            }
            if (count > max * 5.0F / 6.0F) {
                float f = (float) (count / 1000.0D);
                // 计算弧度值(sin需要的是弧度值不是角度值),至于是怎么得到的,数学渣渣表示懵逼
                double d = Math.PI * 12.0F * f / 180.0D;
                int i = (int) (Math.sin(d) * progress_bar.getWidth() / 2.0D);
                int j = (int) (Math.cos(d) * progress_bar.getWidth() / 2.0D);
                // 这里请注意里面使用的FrameLayout.LayoutParams,所以容器请用FrameLayout
                Util.setLayout(round_text, circleX + circleRadius - Math.abs(i), circleY - Math.abs(j));
                i = ((Integer) ColorUtils.evaluate((float) ((count / max - 0.75D) * 4.0D), Integer.valueOf(-1853686), Integer.valueOf(-3407872))).intValue();
                round_text.setBackgroundDrawable(Util.getRoundBg(i, 100));
                round_text.setTextColor(Color.WHITE);
                if ((f >= 25.0F) && (f <= 30.0F)) {
                    round_text.setVisibility(View.VISIBLE);
                    round_text.setText((int) (31.0F - f) + "");
                    if ((f >= 29.0F) && (f < 30.0F) && (!(scaleAnimation.hasStarted()))) {
                        round_text.setAnimation(scaleAnimation);
                        scaleAnimation.setAnimationListener(new Animation.AnimationListener() {
                            public void onAnimationEnd(Animation paramAnimation) {
                                scaleAnimation = new ScaleAnimation(1.0F, 0.0F, 1.0F, 0.0F, Animation.RELATIVE_TO_SELF, 0.5F, Animation.RELATIVE_TO_SELF, 0.5F);
                                scaleAnimation.setDuration(duration);
                                // 设置数字的text为GONE状态
                                round_text.setVisibility(View.GONE);
                            }

                            public void onAnimationRepeat(Animation paramAnimation) {
                            }

                            public void onAnimationStart(Animation paramAnimation) {
                                // 设置数字的text为VISIBLE状态
                                round_text.setVisibility(View.VISIBLE);
                            }
                        });
                        scaleAnimation.start();
                    }
                }
            }
        }
    }
}

附上ColorUtilsUtil以及xml文件

package com.example.tangxb.myapplication;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RoundRectShape;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

/**
 * Created by Tangxb on 2016/7/25.
 */
public class Util {
    public static int dip2px(Context paramContext, float paramFloat) {
        return (int) (paramFloat * paramContext.getResources().getDisplayMetrics().density + 0.5F);
    }

    public static void setLayout(View paramView, int paramInt1, int paramInt2) {
        ViewGroup.MarginLayoutParams localMarginLayoutParams = new ViewGroup.MarginLayoutParams(paramView.getLayoutParams());
        localMarginLayoutParams.setMargins(paramInt1 - 14, paramInt2 + 10, localMarginLayoutParams.width + paramInt1, localMarginLayoutParams.height + paramInt2);
        paramView.setLayoutParams(new FrameLayout.LayoutParams(localMarginLayoutParams));
    }

    public static Drawable getRoundBg(int paramInt1, int paramInt2) {
        ShapeDrawable localShapeDrawable = new ShapeDrawable(new RoundRectShape(new float[]{paramInt2, paramInt2, paramInt2, paramInt2, paramInt2, paramInt2, paramInt2, paramInt2}, null, null));
        paramInt2 = paramInt1;
        if (paramInt1 == -1)
            paramInt2 = -1;
        localShapeDrawable.getPaint().setColor(paramInt2);
        return localShapeDrawable;
    }

}
package com.example.tangxb.myapplication;

/**
 * Created by Tangxb on 2016/7/25.
 */
public class ColorUtils {
    public static Object evaluate(float paramFloat, Object paramObject1, Object paramObject2)
    {
        int l = ((Integer)paramObject1).intValue();
        int i = l >> 24 & 0xFF;
        int j = l >> 16 & 0xFF;
        int k = l >> 8 & 0xFF;
        l &= 255;
        int i1 = ((Integer)paramObject2).intValue();
        return Integer.valueOf((int)(((i1 >> 24 & 0xFF) - i) * paramFloat) + i << 24 | (int)(((i1 >> 16 & 0xFF) - j) * paramFloat) + j << 16 | (int)(((i1 >> 8 & 0xFF) - k) * paramFloat) + k << 8 | (int)(((i1 & 0xFF) - l) * paramFloat) + l);
    }

    public static Object evaluate2(float paramFloat, Object paramObject1, Object paramObject2, Object paramObject3)
    {
        int l = ((Integer)paramObject1).intValue();
        int i = l >> 24 & 0xFF;
        int j = l >> 16 & 0xFF;
        int k = l >> 8 & 0xFF;
        l &= 255;
        int i1 = ((Integer)paramObject2).intValue();
        int i2 = ((Integer)paramObject3).intValue();
        return Integer.valueOf((int)(((i1 >> 24 & 0xFF) - i - (i2 >> 24 & 0xFF)) * paramFloat) + i << 24 | (int)(((i1 >> 16 & 0xFF) - j - (i2 >> 16 & 0xFF)) * paramFloat) + j << 16 | (int)(((i1 >> 8 & 0xFF) - k - (i2 >> 8 & 0xFF)) * paramFloat) + k << 8 | (int)(((i1 & 0xFF) - l - (i2 & 0xFF)) * paramFloat) + l);
    }
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="385.0dp">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="300.0dp"
            android:layout_marginTop="85.0dp">

            <com.example.tangxb.myapplication.CircleProgressBar
                android:id="@+id/cpb"
                android:layout_width="300.0dp"
                android:layout_height="300.0dp"
                android:layout_centerHorizontal="true" />
        </RelativeLayout>

        <TextView
            android:id="@+id/tv"
            android:layout_width="20.0dp"
            android:layout_height="20.0dp"
            android:gravity="center"
            android:textColor="#ff494949" />
    </FrameLayout>

</RelativeLayout>

我把里面能够自己还原的部分还原了,然而这里为了偷懒,就没有再用自定义属性去设置颜色值了。

时间: 2024-07-30 10:17:32

一个不是那么优美的圆形进度条续(基本还原原应用里面的效果)的相关文章

Android自定义控件实现一个带文本与数字的圆形进度条

实现的效果图如下所示: 第一步:绘制下方有缺口的空心圆,称为外围大弧吧 anvas.clipRect(0, 0, mWidth, mHeight / 2 + radius - textHeight * 3 / 4); 第二步:计算绘制圆弧进度条时的起始角度,设置为外围大弧的左端点为进度值得起点,扫过的角度所占外围大弧的百分比就是进度值 第三步:绘制数字.文字.百分号 第四步:使用Handler Runnable 和DecelerateInterpolator是进度条和数字动起来 测试代码: fi

利用css3动画和border来实现圆形进度条

最近在学习前端的一些知识,发现border的功能十分强大啊! 首先来看看demo 就是这么一个圆形的进度条,在文本框中输入0-100的数值下面的进度条相应的转到多少 这个主要是利用border,旋转和css动画来实现的,主要思想是利用两个div来互相遮挡border形成的一个只有半圈有颜色的圆形,再利用旋转div的角度来调整显示 上代码: html+css+js(这里引入了jquery) <!DOCTYPE html> <html lang="en"> <

自定义圆形进度条

关于控件呢,我想大家应该都很熟悉了吧,android应用开发MVC架构中,控件担任着至关重要的作用,感觉可以说是基于控件的事件模型人机交互的基础吧.这种特性感觉在wpf开发中体现得更为直接,感兴趣的同学可以去了解一下.而android框架自身就已经给我们提供了很多控件.那么问题来了?为什么有那么多控件可以用,你还要去屑自定义控件呢?是因为大家闲的蛋疼吗?显然不是.个人认为只要有两方面吧,要么是觉得有些原生控件是在是丑得难以忍受(即使是在你已经自定义了他的shape,圆角,selector等一系列

Android自定义View——圆形进度条式按钮

介绍 今天上班的时候有个哥们问我怎么去实现一个按钮式的进度条,先来看看他需要实现的效果图. 和普通的圆形进度条类似,只是中间的地方有两个状态表示,未开始,暂停状态.而且他说圆形进度的功能已经实现了.那么我们只需要对中间的两个状态做处理就行了. 先来看看实现的效果图: 上面说了我们只需要处理中间状态的变化就可以了,对于进度的处理直接使用了弘洋文章中实现: http://blog.csdn.net/lmj623565791/article/details/43371299 下面开始具体实现. 具体实

Html5基于SVG的扁平风格圆形进度条javascript插件教程

一.使用方法 使用该圆形进度条需要引入circleDonutChart.js文件. <script type="text/javascript" src="circleDonutChart.js"></script> 二.Html结构 你可以使用一个空的<div>元素来制作圆形进度条. <div id="example1"></div> 三.初始化插件 要制作圆形进度条,可以使用下面的方

Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)

转载请注明地址:http://blog.csdn.net/xiaanming/article/details/10298163 很多的时候,系统自带的View满足不了我们功能的需求,那么我们就需要自己来自定义一个能满足我们需求的View,自定义View我们需要先继承View,添加类的构造方法,重写父类View的一些方法,例如onDraw,为了我们自定义的View在一个项目中能够重用,有时候我们需要自定义其属性,举个很简单的例子,我在项目中的多个界面使用我自定义的View,每个界面该自定义View

CAShapeLayer实现圆形进度条效果

一.CAShapeLayer简介: 1.CAShapeLayer继承至CALayer,可以使用CALayer的所有属性值 2.CAShapeLayer需要与贝塞尔曲线配合使用才有意义 3.使用CAShapeLayer与贝塞尔曲线可以实现不在view的drawRect方法中画出一些想要的图形 4.CAShapeLayer属于CoreAnimation框架,其动画渲染直接提交到手机的GPU当中,相较于view的drawRect方法使用CPU渲染而言,其效率极高,能大大优化内存使用情况 五角星动画 #

WPF 实现圆形进度条

项目中用到圆形进度条,首先就想到使用 ProgressBar 扩展一个,在园子里找到 迷途的小榔头 给出的思路和部分代码,自己加以实现.在此感谢 迷途的小榔头! 进度小于60显示红色,大于60则显示绿色.效果如下: 基本思路: 本质上是一个进度条,只是外观有别于矩形进度条,所以需要修改ProgressBar的ControlTemplate. 进度条部分实际是一个扇形,用WPF动态绘出(原理参考迷途的小榔头讲解). 要将进度条的值(Value依赖属性)转换为进度条,需要一个Converter. 根

Android绘制圆形进度条

一.背景介绍 我们在项目中,经常会见到圆形进度条,看起来很美观.直观.刚好最近项目中有这样的需求,记录一下,顺便回顾下自定义View的知识. 二.实现思路 自定义View,就是在画布中绘制View,需要重写onDraw方法.该View可以拆分成以下几部分: 1)需要画一个浅绿色的圆 2)需要画一个白色的圆 3)圆圈中有进度数字的显示 4)圆圈中可以自定义顶部和底部不同文案的提示 三.主要方法介绍 1.drawArc:由上图可以看出,该圆需要画出圆弧表示进度,所以选择drawArc(RectF o