android计时器视图(就像进度条一样)在画布中使用颜色更新

android计时器视图(就像进度条一样)在画布中使用颜色更新,android,canvas,android-activity,progress,Android,Canvas,Android Activity,Progress,在我的应用程序中,当我输入一个活动时,我会显示一个计时器视图(看起来像一个进度条),它根据服务器的计时器值运行。开始时(如40秒),计时器将为绿色,中间(如25秒)变为黄色,最后变为红色(如10秒),下面是我正在使用的代码 public class TimerView extends View { private LinearInterpolator mInterpolator; private Transformation mTransformation; priva

在我的应用程序中,当我输入一个活动时,我会显示一个计时器视图(看起来像一个进度条),它根据服务器的计时器值运行。开始时(如40秒),计时器将为绿色,中间(如25秒)变为黄色,最后变为红色(如10秒),下面是我正在使用的代码

public class TimerView extends View 
{
    private LinearInterpolator mInterpolator;
    private Transformation mTransformation;
    private AlphaAnimation mAnimation;

    int orange = Color.rgb(255, 153, 0);
    private int green = Color.rgb(107, 155, 21);
    private int red = Color.rgb(194, 21, 30);
    private int yellow = Color.rgb(225, 170, 0);

    private RectF rect;
    private Integer mTimerVal = 0;
    private Paint tmrPaint;
    private Paint txtPaint;
    private float mDensity = 1.0f;

    public TimerView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        mDensity = getResources().getDisplayMetrics().density;

        txtPaint = new Paint();
        tmrPaint = new Paint();
        tmrPaint.setAntiAlias(true);

        txtPaint.setColor(Color.WHITE);
        txtPaint.setTextSize(15.0f * mDensity);
        txtPaint.setAntiAlias(true);

        if (!isInEditMode()) {
            txtPaint.setTypeface(Typefaces.get(getContext(), "OpenSans-CondBold.ttf"));
        }
        rect = new RectF(0, 8 * mDensity, 0, 22 * mDensity);
        mInterpolator = new LinearInterpolator();
        // Timer Animation
        mTransformation = new Transformation();
        mAnimation = new AlphaAnimation(1.0f, 0.0f);
        mAnimation.setRepeatMode(AlphaAnimation.RESTART);
        mAnimation.setRepeatCount(0);
        mAnimation.setDuration(0);
        mAnimation.setInterpolator(mInterpolator);
        mAnimation.setStartTime(Animation.START_ON_FIRST_FRAME);
        mAnimation.cancel();
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        // System.out.println("onLayout: " + left + " top: " + top + " r: " +
        // right + " b: " + bottom);
        super.onLayout(changed, left, top, right, bottom);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // System.out.println("onLayout onMeasure: " + widthMeasureSpec + " x "
        // + heightMeasureSpec);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onDraw(Canvas canvas) 
    {
        long time = getDrawingTime();
        mAnimation.getTransformation(time, mTransformation);
        float scale = mTransformation.getAlpha();

        int rem = (int) Math.floor(mTimerVal * scale);
        if (rem > 0) 
        {
            if (rem < 5) 
            {
                tmrPaint.setColor(red);
            }
            else if (rem <= 10) 
            {
                tmrPaint.setColor(yellow);
            }
            else 
            {
                tmrPaint.setColor(green);
            }

            rect.right = this.getWidth() - mDensity * 8;
            rect.left = (1 - scale) * (this.getWidth());

            canvas.drawRoundRect(rect, 4 * mDensity, 4 * mDensity, tmrPaint);
            canvas.drawText(String.format("%d", rem), 13 * mDensity, 20 * mDensity, txtPaint);
        }
        if (scale > 0.0f) {
            postInvalidateDelayed(40);
        }

        super.onDraw(canvas);
    }

    public void setTimer(TimerTag timer) {
        if (timer.getTimerValue() > 0) {
            mAnimation.reset();
            mTimerVal = timer.getTimerValue();
            mAnimation.setDuration(timer.getTimerValue() * 1000);
            mAnimation.start();
            postInvalidate();
        }

    }
}
公共类TimerView扩展视图
{
私人电话电报机;
私有化改造;
私人字母动画制作;
int橙色=Color.rgb(255,153,0);
private int green=Color.rgb(10715521);
私有内部红色=颜色.rgb(194,21,30);
私有整数黄色=颜色.rgb(225170,0);
私人rectfrect;
私有整数mTimerVal=0;
私人油漆;
私人涂料txtPaint;
私有浮动密度=1.0f;
公共TimerView(上下文、属性集属性){
超级(上下文,attrs);
init();
}
私有void init(){
mDensity=getResources().getDisplayMetrics().density;
txtPaint=新油漆();
tmrPaint=新油漆();
tmrPaint.setAntiAlias(真);
txtPaint.setColor(Color.WHITE);
txtPaint.setTextSize(15.0f*mDensity);
txtPaint.setAntiAlias(真);
如果(!isInEditMode()){
setTypeface(Typefaces.get(getContext(),“OpenSans CondBold.ttf”);
}
rect=新的RectF(0,8*mDensity,0,22*mDensity);
mInterpolator=新的LinearInterpolator();
//计时器动画
MTTransformation=新转换();
mAnimation=新字母动画(1.0f,0.0f);
mAnimation.setRepeatMode(AlphaAnimation.RESTART);
mAnimation.setRepeatCount(0);
mAnimation.setDuration(0);
设置插值器(最小插值器);
mAnimation.setStartTime(动画。在第一帧上启动);
mAnimation.cancel();
}
@凌驾
仅限受保护的空心布局(布尔值已更改、整数左侧、整数顶部、整数右侧、整数底部){
//System.out.println(“onLayout:+left+”top:+top+“r:”+
//右+b:+底部);
超级。仅限布局(已更改、左、上、右、下);
}
@凌驾
测量时的保护空隙(内部宽度测量等级、内部高度测量等级){
//System.out.println(“仅测量时的布局:+widthMeasureSpec+“x”
//+高度测量等级);
超级测量(宽度测量、高度测量);
}
@凌驾
受保护的void onDraw(画布)
{
长时间=getDrawingTime();
mAnimation.getTransformation(时间,mtTransformation);
float scale=mttransformation.getAlpha();
int rem=(int)数学楼层(mTimerVal*比例);
如果(rem>0)
{
如果(rem<5)
{
tmrPaint.setColor(红色);
}
否则如果(雷姆0.0f){
验证后延迟(40);
}
super.onDraw(帆布);
}
公共无效设置计时器(计时器标记计时器){
if(timer.getTimerValue()>0){
mAnimation.reset();
mTimerVal=timer.getTimerValue();
mAnimation.setDuration(timer.getTimerValue()*1000);
mAnimation.start();
后验证();
}
}
}

现在我的问题是,当我进入活动时,如果服务器响应低于25而高于10,我的计时器将显示黄色,但它是从末尾开始的,我希望它从视图中的中间或其他位置开始,我无法更改画布中的起始点,任何建议…

,因为矩形坐标(特别是左上角)是基于当前alpha值计算的,alpha动画的起始alpha值应基于已经经过的时间

e、 g.如果计时器设置为30秒,用户在第10秒进入活动,则动画需要播放20秒。因此,开始alpha值应为20/30,即0.67f。
AlphaAnimation
应实例化如下:

mAnimation = new AlphaAnimation(0.67f, 0.0f);

如我所见,您绘制了rect,它始终位于右侧:

rect.right = this.getWidth() - mDensity * 8;
矩形的左边缘取决于比例:

 rect.left = (1 - scale) * (this.getWidth());
我认为您只需将其更改为:

rect.right = this.getWidth() - mDensity * 8 - (1-scale) * this.getWidth();
rect.left = 0;

这个想法无法实现。在基于整数rem值的onDraw中,我正在更改进度条的颜色,在那里我们不能插入这一行…这两行将从左到右减少,如果我按您所说的那样更改,它将从右到左减少。。。。