android计时器视图(就像进度条一样)在画布中使用颜色更新
在我的应用程序中,当我输入一个活动时,我会显示一个计时器视图(看起来像一个进度条),它根据服务器的计时器值运行。开始时(如40秒),计时器将为绿色,中间(如25秒)变为黄色,最后变为红色(如10秒),下面是我正在使用的代码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
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中,我正在更改进度条的颜色,在那里我们不能插入这一行…这两行将从左到右减少,如果我按您所说的那样更改,它将从右到左减少。。。。