安卓进度条样式开发
更新:2023-05-14 16:58
一、优化默认进度条外观
Android中提供了默认的进度条,但其外观简单、单调,不能满足用户的个性化需求。因此,我们需要对默认的进度条样式进行优化。
首先,我们可以使用<style>
标签重新定义进度条的颜色和形状,为其加上背景颜色或边框线条,以增强其可视性和美观度。
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">#0066CC</item>
<item name="colorPrimaryDark">#005299</item>
<item name="colorAccent">#FF4081</item>
<item name="android:progressBarStyle">@style/MyProgressBar</item>
</style>
<style name="MyProgressBar" parent="@android:style/Widget.ProgressBar">
<item name="android:indeterminateOnly">false</item>
<item name="android:minHeight">48dp</item>
<item name="android:maxHeight">48dp</item>
<item name="android:indeterminateDrawable">@drawable/custom_progress</item>
</style>
<!-- custom_progress.xml -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#FF9D9E9D"
android:centerColor="#FF5A5D5A"
android:centerY="0.75"
android:endColor="#FF5A5D5A"
android:angle="270" />
</shape>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#FF00FF"
android:endColor="#FFF0F0"
android:angle="270" />
</shape>
</clip>
</item>
</layer-list>
通过以上代码的设置,我们可以自定义进度条的颜色与形状,使其具备更好的可见性与美观度。
二、使用动态图形交互进度条
除了改变进度条样式的外观,我们也可以使用动态图形交互,来增强用户的体验感。例如,可以运用Bezier曲线和属性动画技术,来实现一个弧形的进度条。
// 示例代码(见下方完整类定义)
以上代码中,我们使用了一个自定义的View和自定义属性,实现了一个弧形的进度条。通过属性动画,可以实现进度条的平滑过渡,同时可在进度条两端加上标签文字,提供更好的交互体验。
三、使用气泡状进度条
除了弧形进度条,在用户体验过程中,我们也可以设计出一些独特的进度条样式,以增强用户的感官体验。 例如下面的气泡状进度条,就可以使用户更直观地了解到进度条状态的变化,增强其使用体验。
// 示例代码(见下方完整类定义)
四、总结
通过本文的介绍,我们可以看到,通过默认进度条优化、动态图形交互和独特进度条样式等方面的探索,可以为用户提供更好的体验,使应用更加吸引人。
示例代码:弧形进度条(ArcProgress)
public class ArcProgress extends View {
private Paint paint;
private RectF rectF;
private float strokeWidth;
private float progress = 0;
private int max;
private int finishedStrokeColor;
private int unfinishedStrokeColor;
private int textColor;
private float textSize;
private String text;
private int arc_angle = 270;
private int start_angle = 135;
public ArcProgress(Context context) {
this(context, null);
}
public ArcProgress(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ArcProgress(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
paint = new Paint();
rectF = new RectF();
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ArcProgress, defStyleAttr, 0);
strokeWidth = typedArray.getDimension(R.styleable.ArcProgress_arcWidth, 10f);
progress = typedArray.getFloat(R.styleable.ArcProgress_progress, 0);
max = typedArray.getInt(R.styleable.ArcProgress_max, 100);
finishedStrokeColor = typedArray.getColor(R.styleable.ArcProgress_finishedStrokeColor, Color.WHITE);
unfinishedStrokeColor = typedArray.getColor(R.styleable.ArcProgress_unfinishedStrokeColor, Color.WHITE);
textColor = typedArray.getColor(R.styleable.ArcProgress_android_textColor, Color.WHITE);
textSize = typedArray.getDimension(R.styleable.ArcProgress_android_textSize, 20f);
typedArray.recycle();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int width = getWidth();
int height = getHeight();
int cx = width / 2;
int cy = height / 2;
int radius = (int) Math.min(cx, cy) - (int) strokeWidth / 2;
paint.setStrokeWidth(strokeWidth);
paint.setAntiAlias(true);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(finishedStrokeColor);
rectF.set(cx - radius, cy - radius, cx + radius, cy + radius);
canvas.drawArc(rectF, start_angle, progress / (float) max * arc_angle, false, paint);
paint.setColor(unfinishedStrokeColor);
canvas.drawArc(rectF, start_angle + progress / (float) max * arc_angle, arc_angle - progress / (float) max * arc_angle, false, paint);
paint.setStrokeWidth(0);
paint.setColor(textColor);
paint.setTextSize(textSize);
paint.setTextAlign(Paint.Align.CENTER);
canvas.drawText(text, cx, cy + textSize / 4, paint);
}
public void setProgress(float progress) {
this.progress = progress;
this.text = String.format("%.0f%%", progress / max * 100f);
invalidate();
}
public void setMax(int max) {
this.max = max;
invalidate();
}
}
示例代码:气泡状进度条(BubbleProgressBar)
public class BubbleProgressBar extends View {
private Paint paint;
private RectF rectF;
private float strokeWidth;
private float progress = 0;
private float max = 100;
private float bubbleWidth;
private float bubbleHeight;
private int bubbleColor;
private int barColor;
private float barWidth;
private int textColor;
private float textSize;
public BubbleProgressBar(Context context) {
this(context, null);
}
public BubbleProgressBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public BubbleProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
paint = new Paint();
paint.setAntiAlias(true);
rectF = new RectF();
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.BubbleProgressBar, defStyleAttr, 0);
bubbleWidth = typedArray.getDimension(R.styleable.BubbleProgressBar_bubbleWidth, 24);
bubbleHeight = typedArray.getDimension(R.styleable.BubbleProgressBar_bubbleHeight, 36);
bubbleColor = typedArray.getColor(R.styleable.BubbleProgressBar_bubbleColor, Color.parseColor("#1abc9c"));
barColor = typedArray.getColor(R.styleable.BubbleProgressBar_barColor, Color.parseColor("#bdc3c7"));
barWidth = typedArray.getDimension(R.styleable.BubbleProgressBar_barWidth, 10);
textSize = typedArray.getDimension(R.styleable.BubbleProgressBar_android_textSize, 18);
textColor = typedArray.getColor(R.styleable.BubbleProgressBar_android_textColor, Color.WHITE);
typedArray.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height;
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
} else {
width = (int) bubbleWidth * 3;
}
if (heightMode == MeasureSpec.EXACTLY) {
height = heightSize;
} else {
height = (int) bubbleHeight;
}
setMeasuredDimension(width, height);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int width = getWidth();
int height = getHeight();
paint.setStrokeWidth(0);
paint.setStyle(Paint.Style.FILL);
// 画气泡
paint.setColor(bubbleColor);
canvas.drawRoundRect(rectF, bubbleWidth / 2, bubbleWidth / 2, paint);
// 画进度条背景
paint.setColor(barColor);
rectF.set(bubbleWidth / 2, height / 2 - barWidth / 2, width - bubbleWidth / 2, height / 2 + barWidth / 2);
canvas.drawRoundRect(rectF, barWidth / 2, barWidth / 2, paint);
// 画进度条
paint.setColor(bubbleColor);
rectF.set(bubbleWidth / 2, height / 2 - barWidth / 2, progress / max * (width - bubbleWidth) + bubbleWidth / 2, height / 2 + barWidth / 2);
canvas.drawRoundRect(rectF, barWidth / 2, barWidth / 2, paint);
// 画进度百分比
paint.setColor(textColor);
paint.setTextSize(textSize);
paint.setTextAlign(Paint.Align.CENTER);
String text = (int)(progress / max * 100) + "%";
float textWidth = paint.measureText(text);
float x = progress / max * (width - bubbleWidth) + bubbleWidth / 2;
float y = height / 2 + textSize / 2;
canvas.drawText(text, x, y, paint);
}
public float getProgress() {
return progress;
}
public void setProgress(float progress) {
this.progress = progress;
if (this.progress > max) {
this.progress = max;
}
invalidate();
}
public float getMax() {
return max;
}
public void setMax(float max) {
this.max = max;
invalidate();
}
}