- PVSM.RU - https://www.pvsm.ru -
Все началось с того, что необходимо было стилизовать ProgressBar в одном из приложений. Как известно в андройде для этого используются Drawable [1] объекты, описанные либо в виде XML, либо унаследованные от абстрактного класса Drawable [1], который входит в состав AndroidSDK. Про первый способ информации довольно много, а вот о втором — пойдет речь в данном посте.
Для начала создадим два класса CustomProgressDrawable и CustomProgressIndeterminateDrawable, для determinate и indeterminate состояний нашего прогресс бара соотвественно.
Начнем с CustomProgressDrawable:
В конструкторе созданим объект класса Paint [2], для того, чтобы в дальнейшем мы могли с помощью него рисовать на Canvas [3].
public CustomProgressDrawable(int color) {
super();
mPaint = new Paint();
mPaint.setColor(color);
}
Далее переопределяем метод onLevelChange [4], именно этот метод вызывется, когда мы вызываем метод setProgress [5] у нашего объекта ProgressBar [6]. В конце метода вызываем метод invalidateSelf [7], который заставит наш Drawable [1] отрисоваться.
@Override
protected boolean onLevelChange(int level) {
final float drawTo = START_ANGLE + HALF_CIRCLE_DEGREES * level / (float)MainActivity.PROGRESS_MAX_VALUE;
boolean update = drawTo != mDrawTo;
mDrawTo = drawTo;
invalidateSelf();
return update;
}
Так как класс Drawable [1] является абстрактным, нам также будет необходимо реализовать все абстрактные методы данного класса, но их реализация довольно простая и ее в статье я опустил. Ниже есть ссылка на полный код примера.
Логику отрисовки реализуем в методе draw [8]:
@Override
public void draw(Canvas canvas) {
canvas.rotate(CANVAS_1ST_ARC_ROTATE_DEGREES, getBounds().centerX(), getBounds().centerY());
mPaint.setStyle(Paint.Style.STROKE);
canvas.drawOval(mBoundsF, mPaint);
mPaint.setStyle(Paint.Style.FILL);
canvas.drawArc(mInnerBoundsF, START_ANGLE, mDrawTo, true, mPaint);
canvas.rotate(CANVAS_2ND_ARC_ROTATE_DEGREES, getBounds().centerX(), getBounds().centerY());
canvas.drawArc(mInnerBoundsF, START_ANGLE, mDrawTo, true, mPaint);
}
Переходим к CustomProgressIndeterminateDrawable:
В целом логика реализации аналогична предыдущему классу, за исключением того, что вместо переопределения метода onLevelChange [4], нам необходимо имплементировать два интерфейса Animatable [9] и Runnable [10].
@Override
public void run() {
invalidateSelf();
scheduleSelf(this, AnimationUtils.currentAnimationTimeMillis());
}
@Override
public boolean isRunning() {
return mIsRunning;
}
@Override
public void start() {
if (!isRunning()) {
mIsRunning = true;
mStartTicks = AnimationUtils.currentAnimationTimeMillis();
run();
}
}
@Override
public void stop() {
if (isRunning()) {
unscheduleSelf(this);
mIsRunning = false;
}
}
Сама анимация происходит в методе run [11], сначала мы перерисовываем наш Drawable [1], вызывая метод invalidateSelf [7]. Затем, используя метод scheduleSelf [12] класса Drawable [1], вновь вызываем метод run [11].
Теперь, там где нам необходимо, инициализируем наши Drawable [1] и устанавливаем их обычному элементу ProgressBar [6], и далее работаем с ним через методы setProgress [5] и setIndeterminate [13].
final int color = getResources().getColor(R.color.green);
// initialize drawables
CustomProgressDrawable progressDrawable = new
CustomProgressDrawable(color);
CustomProgressIndeterminateDrawable barIndeterminateDrawable = new
CustomProgressIndeterminateDrawable(color);
// set drawables and max value
mCustomProgressBar = (ProgressBar)
findViewById(R.id.custom_progress_bar);
mCustomProgressBar.setIndeterminateDrawable(barIndeterminateDrawable);
mCustomProgressBar.setProgressDrawable(progressDrawable);
mCustomProgressBar.setMax(PROGRESS_MAX_VALUE);
И вот, что в итоге у нас получилось:
Весь код на github тыц [14].
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/pesochnitsa/77279
Ссылки в тексте:
[1] Drawable: http://developer.android.com/reference/android/graphics/drawable/Drawable.html
[2] Paint: http://developer.android.com/reference/android/graphics/Paint.html
[3] Canvas: http://developer.android.com/reference/android/graphics/Canvas.html
[4] onLevelChange: http://developer.android.com/reference/android/graphics/drawable/Drawable.html#onLevelChange%28int%29
[5] setProgress: http://developer.android.com/reference/android/widget/ProgressBar.html#setProgress%28int%29
[6] ProgressBar: http://developer.android.com/reference/android/widget/ProgressBar.html
[7] invalidateSelf: http://developer.android.com/reference/android/graphics/drawable/Drawable.html#invalidateSelf%28%29
[8] draw: http://developer.android.com/reference/android/graphics/drawable/Drawable.html#draw%28android.graphics.Canvas%29
[9] Animatable: http://developer.android.com/reference/android/graphics/drawable/Animatable.html
[10] Runnable: http://developer.android.com/reference/java/lang/Runnable.html
[11] run: http://developer.android.com/reference/java/lang/Runnable.html#run%28%29
[12] scheduleSelf: http://developer.android.com/reference/android/graphics/drawable/Drawable.html#scheduleSelf%28java.lang.Runnable,%20long%29
[13] setIndeterminate: http://developer.android.com/reference/android/widget/ProgressBar.html#setIndeterminate%28boolean%29
[14] тыц: https://github.com/Artemych/custom-progress-drawables
Нажмите здесь для печати.