Пользовательский круговой индикатор выполнения изображения с прозрачным фоном

У меня есть круглое изображение таймера:

Пользовательский круговой индикатор выполнения изображения с прозрачным фоном

Я хочу создать круговой индикатор выполнения, который будет состоять из этой картинки, что сделает его медленно пустым, как часы, до полного исчезновения (как анимация).

например, через половину времени я определю, что это выглядит так:

Пользовательский круговой индикатор выполнения изображения с прозрачным фоном

Сейчас я делаю это следующим образом: Я помещаю изображение таймера как изображение на экран, а поверх него я помещаю обычный круговой индикатор выполнения с цветом в качестве цвета фона, который скрывает изображение (и так я получаю желаемый эффект).

но теперь у меня проблема, когда у меня мало цветов на фоне приложения, потому что я не могу сделать индикатор выполнения того же цвета, что и фон, поэтому я ищу новый способ сделать это, например, настраиваемый индикатор выполнения, который состоят из изображения таймера с прозрачным фоном.

пожалуйста, помогите мне, как изменить мой код, чтобы получить его:

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) — синий цвет фона приложения:

<?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>

Проверить эту библиотеку ссылка на сайт

Ali Ali 18.01.2019 18:47
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
1
982
1

Ответы 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();
}
}

конечный результат:

Надеюсь, поможет

Нет способа сделать это с помощью компонента Progress Bar? @амрноид

Idan Neeman 19.01.2019 23:17

попробуйте изменить изображение таймера на АнимированныйВектор и использовать его как рисуемый ProgressBar

Amrdroid 20.01.2019 08:46

Спасибо за ваши ответы! Я попробовал ваш код, но у меня есть проблема, он очень хорошо рисует часы, но после вызова startAnimation() часы исчезают (без анимации)...

Idan Neeman 21.01.2019 22:09

Другие вопросы по теме