安卓进度条样式开发

发布时间:2023-12-08

安卓进度条样式开发

更新: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();
    }
}