【问题标题】:Custom circular image progress bar with transparent background具有透明背景的自定义圆形图像进度条
【发布时间】:2019-01-18 13:51:39
【问题描述】:

我有计时器的圆形图片:

我想创建由这张图片组成的圆形进度条,它会像时钟一样慢慢变空,直到完全消失(像动画一样)。

例如,在一半的时间后,我将其定义为:

现在我正在这样做: 我将计时器图像作为图像放在屏幕上,然后在其上方放置带有颜色的常规圆形进度条作为隐藏图像的背景色(因此我得到了所需的效果)。

但是现在当应用程序的背景颜色很少时我遇到了问题,因为我不能使进度条与背景颜色相同,所以我正在寻找新的方法来制作它,比如自定义由具有透明背景的计时器图像组成的进度条。

请帮助我如何更改我的代码以获取它:

ProgressBar XML:
<ProgressBar
    android:id="@+id/progressBar"
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:progress="100"
    android:rotation="90"
    style="?android:progressBarStyleHorizontal"
    android:progressDrawable="@drawable/prog_blue"/>

Prog_blue(progressBar 的 drawable)——蓝色是应用的背景色:

<?xml version="1.0" encoding="utf-8"?>
<scale
    android:fromDegrees="270"
    android:pivotX="50%"
    android:pivotY="50%"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <shape
        android:shape="ring"
        android:innerRadiusRatio="2.7"
        android:thickness="23dp"
        xmlns:android="http://schemas.android.com/apk/res/android">
        <gradient
            android:startColor="@color/prog_blue"
            android:endColor="@color/prog_blue"
            android:type="sweep"
            android:useLevel="false"/>
    </shape>
</scale>

【问题讨论】:

  • 查看这个库link

标签: java android android-layout android-progressbar


【解决方案1】:

您可以创建自定义View 来实现这一目标

这里是我的代码:

ClockProgressBar.java

 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.support.annotation.Nullable;
 import android.util.AttributeSet;
 import android.view.View;


 public class ClockProgressBar extends View {
 Paint tickPaint;
 private int shortTickLen=10;
 private int longTickLen=20;
 private int finalWidth=0;
 private int finalHeight=0;
 private int r=0;
 private Path ticksPath;
 int tickNumbers=60;
 private ValueAnimator animator;

 public ClockProgressBar(Context context) {
    super(context);
    ini();
 }

 public ClockProgressBar(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    ini();
 }

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    drawIntervals(canvas);

 }

void drawIntervals(Canvas canvas){


    double cX = getX()+finalWidth/2;
    double cY = getY()+finalHeight/2;
    ticksPath=new Path();
    for ( int i=1; i<= tickNumbers; i++){
        int len = shortTickLen;
        if ( i % 15 == 0 ){
            len = longTickLen;
        }else if ( i % 5 == 0 ){
            len = longTickLen;
        }
        double di = (double)i;
        double angleFrom12 = di/60.0*2.0*Math.PI;
        double angleFrom3 = Math.PI/2.0-angleFrom12;
        ticksPath.moveTo(
                (float)(cX+Math.cos(angleFrom3)*r),
                (float)(cY-Math.sin(angleFrom3)*r)
        );

        ticksPath.lineTo(
                (float)(cX+Math.cos(angleFrom3)*(r-len)),
                (float)(cY-Math.sin(angleFrom3)*(r-len))
        );
    }
    canvas.drawPath(ticksPath,tickPaint);


}

void ini(){
    tickPaint=new Paint();
    tickPaint.setStrokeCap(Paint.Cap.BUTT);
    tickPaint.setStrokeJoin(Paint.Join.ROUND);
    tickPaint.setAntiAlias(true);
    tickPaint.setStyle(Paint.Style.STROKE);
    tickPaint.setStrokeWidth(8);
    tickPaint.setStrokeMiter(2f);
    tickPaint.setColor(Color.BLACK);


}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    finalWidth = getMeasuredWidth() / 2;
    finalHeight = getMeasuredWidth() / 2;
    r = (finalWidth / 2);
    setMeasuredDimension(finalWidth, finalHeight );
}

public void startAnimation(){
     animator = ValueAnimator.ofInt(60, 0);
    animator.setDuration(5000);
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        public void onAnimationUpdate(ValueAnimator animation) {
            tickNumbers= (int) animation.getAnimatedValue();
            invalidate();
        }
    });
    animator.setRepeatCount(Integer.MAX_VALUE);
    animator.start();
}
public void stopAnimation(){
    if (animator!=null){
        animator.cancel();
    }
    setVisibility(GONE);

}




  }

并在xml中使用它

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<<Your Package Name>.ClockProgressBar
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/progress"/>

</LinearLayout>

并在您的活动中调用它并使用startAnimation()stopAnimation() 显示和关闭View

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ClockProgressBar progressBar=findViewById(R.id.progress);
    progressBar.startAnimation();
}
}

最终结果

希望对你有帮助

【讨论】:

  • 有没有办法使用进度条组件来做到这一点? @Amrnoid
  • 尝试将你的计时器图像更改为AnimatedVectorDrawable并将其用作ProgressBar的drawable
  • 感谢您的回复!我试过你的代码,但我有问题,它画的时钟很好,但是在 startAnimation() 调用之后,时钟消失了(没有任何动画)......
猜你喜欢
  • 1970-01-01
  • 2019-04-21
  • 2015-05-15
  • 1970-01-01
  • 2015-01-20
  • 2015-12-20
  • 1970-01-01
  • 2012-05-26
  • 1970-01-01
相关资源
最近更新 更多