Хочу сделать кастомный круглый прогресс бар.
введите сюда описание изображения
Нашел пример такого кастомного прогресс бара,
введите сюда описание изображения
Можно ли переписать этот код что бы получить нужный мне результат, мне нужно что бы количество синих кружочков могло быть разным взависимости от установленного значения.Я пытаюсь изменить код но не до конца понимаю что именно нужно сделать, пробую в методе onDraw заменить рисование с прямоугольника на круг, но как получить нужный мне результат все равно не понимаю. Вот код кастомного бара который я показал выше:
public class CircleSegmentBar extends ProgressView {
public static final int rad_360 = 360;
private float SEGMENT_WIDTH = 3f;
private int PADDING = 10;
private Path progressPath;
private Path backgroundPath;
final RectF oval = new RectF();
private float radius;
private float angle;
private int angleStartPoint = ProgressStartPoint.DEFAULT.getValue();
private float left;
private float top;
private float right;
private float bottom;
private boolean isGradientColor;
public CircleSegmentBar(Context context) {
super(context);
}
public CircleSegmentBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
void init() {
initBackgroundColor();
initForegroundColor();
progressPath = new Path();
backgroundPath = new Path();
}
@Override
protected void onSizeChanged(int width, int height, int oldw, int oldh) {
if (width > height) {
radius = height / 3;
} else {
radius = width / 3;
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
left = 0 + strokeWidth / 2;
top = 0 + strokeWidth / 2;
right = min - strokeWidth / 2;
bottom = min - strokeWidth / 2;
oval.set(left + PADDING, top + PADDING, right - PADDING, bottom
- PADDING);
}
@Override
public void onDraw(Canvas canvas) {
drawGradientColor();
drawCircle(canvas);
}
private void drawCircle(Canvas canvas) {
backgroundPath.reset();
for (int i = 0; i < rad_360; i += 5) {
backgroundPath.addArc(oval, i, SEGMENT_WIDTH);
}
canvas.drawPath(backgroundPath, backgroundPaint);
progressPath.reset();
angle = rad_360 * (int) progress / maximum_progress + angleStartPoint;
for (int i = angleStartPoint; i < angle; i += 5) {
// progressPath.addArc(oval, i, SEGMENT_WIDTH);
Log.wtf("Width: " + getWidth(), "Height: " + getHeight());
progressPath.addCircle(getWidth() / 2 , getHeight() /2 , 20 , Path.Direction.CW);
}
canvas.drawPath(progressPath, foregroundPaint);
drawText(canvas);
}
public void setCircleViewPadding(int padding) {
PADDING = padding;
invalidate();
}
public float getSegmentWidth() {
return SEGMENT_WIDTH;
}
/***
* @
***/
public void setSegmentWidth(float segment_width) {
SEGMENT_WIDTH = segment_width;
}
public int getPadding() {
return PADDING;
}
// *******************START POSITION FOR CIRCLE AND CIRCLE SEGMENT
// VIEW******************
public int getProgressStartPosition() {
return startPosInDegrees;
}
public void setStartPositionInDegrees(int degrees) {
this.startPosInDegrees = degrees;
}
public void setStartPositionInDegrees(ProgressStartPoint position) {
this.startPosInDegrees = position.getValue();
}
private void drawGradientColor() {
if (isGradientColor)
setLinearGradientProgress(gradColors);
}
public void setLinearGradientProgress(boolean isGradientColor) {
this.isGradientColor = isGradientColor;
}
public void setLinearGradientProgress(boolean isGradientColor, int[] colors) {
this.isGradientColor = isGradientColor;
gradColors = colors;
}
private void setLinearGradientProgress(int[] gradColors) {
if (gradColors != null)
colorHelper.setGradientPaint(foregroundPaint, left, top, right, bottom, gradColors);
else
colorHelper.setGradientPaint(foregroundPaint, left, top, right, bottom);
}
@Override
public ShapeType setType(ShapeType type) {
// TODO Auto-generated method stub
return ShapeType.SEGMENT_CIRCLE;
}
}
Отрисовка одного диления происходит я так понимаю в этом месте:
progressPath.addArc(oval, i, SEGMENT_WIDTH);
А мне нужно рисовать круг
progressPath.addCircle(x, x, radius , Path.Direction.CW);
Как можно сделать замену ?
-
я не очень сведущ в Андроид ОС но судя по указанному вами участку кода и просмотренной по диагонали документации в самом методе происходит рисование дуги со смещением(в смещении участвует собственно цикл а шаг равен 5) логично что количество интересующих вас диаметров должно быть пропорционально данному шагу(или любом) ну а далее вычислить длину пройденного пути и найти координаты высвечиваемого (по идее заранее прорисованного круга и заливка его цветом относительно прогресса) должна быть простой задачей если потребуется я могу предоставить наглядный код под Fx`ом к примеруPeter Slusar– Peter Slusar2016年06月15日 16:49:22 +00:00Commented 15 июн. 2016 в 16:49
-
@PeterSlusar я буду рад любой помощиKirill Stoianov– Kirill Stoianov2016年06月15日 17:00:48 +00:00Commented 15 июн. 2016 в 17:00
1 ответ 1
Вот грубый пример описанного в комментарии метода(JavaFx):
private void setProgress(double progress) {
//Вычисляем количество видимых частей
int visiblePiece = (int) (360 * progress / (360 / pieces));
for (double i = 0; i < visiblePiece; i++) {
// Порождаем обект круга в конструктор передаем кординаты нового обекта.
// Угол поворота можно учесть здесь же
Circle c = new Circle(center, center - radius, 10, Color.AQUA);
// или позже
c.getTransforms().add(Translate.rotate(i * stepAngle, center, center));
// Добавляем объект на сцену
pane.getChildren().add(c);
}
}
т.е мы вычисляем количество уже видимых полных кругов и в цикле добавляем их на сцену.На всякий случай напомню что вычислить X/Y координаты точки на окружности можно через синус и косинус угла * на радиус.Для того чтобы не перерисовывать все объекты при мизерном изменении прогресса можно сохранять состояние уже от рисованных окружностей(или реализовать изменение яркости заливки к примеру)Ну и на по следок рекомендую при обрисовке графики по возможности использовать работу со стрим апи(хотя в анероиде похоже это не возможно)
результат (0.9) :
Начните задавать вопросы и получать на них ответы
Найдите ответ на свой вопрос, задав его.
Задать вопрос