Easy Tutorial
❮ Git Five Minutes Tutorial Cpp Static Usage ❯

2.3.7 ProgressBar (Progress Bar)

Category Android Basic Tutorial

Introduction to This Section:

This section introduces the ProgressBar, a fundamental UI control in Android. The ProgressBar has many application scenarios, such as when a user is logging in and the background is sending a request, as well as waiting for the server to return information, which is when a progress bar is used. Or when performing some time-consuming operations that require a longer waiting time, without a prompt, users might think the program has crashed or the phone has frozen, which greatly reduces the user experience. Therefore, adding a progress bar where time-consuming operations are needed, to let users know that the program is running and to intuitively inform users of the current task's progress! Using a progress bar can bring such convenience! Alright, let's start explaining the content of this section~ By the way, the official API documentation for ProgressBar is: ProgressBar


1. Common Attribute Explanation and Basic Example

From the official documentation, we see such a class hierarchy diagram:

The ProgressBar inherits from the View class, with direct subclasses including AbsSeekBar and ContentLoadingProgressBar. Among them, the subclasses of AbsSeekBar include SeekBar and RatingBar, which shows that these two are also implemented based on the ProgressBar.

Explanation of Common Attributes:

>

Correspondingly, in Java, we can call the following methods:

>

Next, let's take a look at the example of the default progress bar provided by the system!

Example of System Default ProgressBar:

Running Effect Picture:

Implementation Layout Code:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <!-- System-provided circular progress bars, in order of large, medium, and small -->

    <ProgressBar
        style="@android:style/Widget.ProgressBar.Small"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <ProgressBar
        style="@android:style/Widget.ProgressBar.Large"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <!-- System-provided horizontal progress bar -->
    <ProgressBar
        style="@android:style/Widget.ProgressBar.Horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="100"
        android:progress="18" />

    <ProgressBar
        style="@android:style/Widget.ProgressBar.Horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:indeterminate="true" />

</LinearLayout>

Well, apart from the second one, the rest are not very appealing... The system-provided ones definitely cannot meet our needs! Next, let's explain how we handle the progress bar in actual development!


2. Using Animation to Replace the Circular ProgressBar

The first solution is to use a set of continuous images to form a frame animation. When a progress diagram is needed, make the animation visible, and when it is not needed, make the animation invisible! And this animation is usually implemented using AnimationDrawable! Okay, let's define an AnimationDrawable file:

PS: The images used: [ProgressBar Image Material Package.zip Set this parameter to the aforementioned animation resource, but the size of the progress bar pattern cannot be directly modified; it requires modification in the Java code. If you set the width and height and these dimensions are too large, you will see multiple progress bars... weigh the pros and cons yourself.


3. Custom Circular Progress Bar

>

You may feel frustrated after reading section 2, thinking "Wow, this is so misleading, using an animation to deceive people, haha," but in actual development, it's like this. Of course, the above situation only applies to occasions where progress does not need to be displayed. If you need to display progress, it's useless. Alright, let's look at a simple custom circular progress bar from the internet next! The code is quite simple, easy to understand, and if you're interested, you can take a look or make relevant extensions.

Running effect picture:

Implementation code:

Custom View class:

/**
 * Created by Jay on 2015/8/5 0005.
 */
public class CirclePgBar extends View {

    private Paint mBackPaint;
    private Paint mFrontPaint;
    private Paint mTextPaint;
    private float mStrokeWidth = 50;
    private float mHalfStrokeWidth = mStrokeWidth / 2;
    private float mRadius = 200;
    private RectF mRect;
    private int mProgress = 0;
    //Target value, change as you wish
    private int mTargetProgress = 90;
    private int mMax = 100;
    private int mWidth;
    private int mHeight;

    public CirclePgBar(Context context) {
        super(context);
        init();
    }

    public CirclePgBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public CirclePgBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    //Initialize related parameters
    private void init() {
        mBackPaint = new Paint();
        mBackPaint.setColor(Color.WHITE);
        mBackPaint.setAntiAlias(true);
        mBackPaint.setStyle(Paint.Style.STROKE);
        mBackPaint.setStrokeWidth(mStrokeWidth);

        mFrontPaint = new Paint();
        mFrontPaint.setColor(Color.GREEN);
        mFrontPaint.setAntiAlias(true);
        mFrontPaint.setStyle(Paint.Style.STROKE);
        mFrontPaint.setStrokeWidth(mStrokeWidth);

        mTextPaint = new Paint();
        mTextPaint.setColor(Color.GREEN);
        mTextPaint.setAntiAlias(true);
        mTextPaint.setTextSize(80);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
    }

    //Override the onMeasure method for measuring size and the core method onDraw() for drawing the View
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mWidth = getRealSize(widthMeasureSpec);
        mHeight = getRealSize(heightMeasureSpec);
        setMeasuredDimension(mWidth, mHeight);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        initRect();
        float angle = mProgress / (float) mMax * 360;
        canvas.drawCircle(mWidth / 2, mHeight / 2, mRadius, mBackPaint);
        canvas.drawArc(mRect, -90, angle, false, mFrontPaint);
        canvas.drawText(mProgress + "%", mWidth / 2 + mHalfStrokeWidth, mHeight / 2 + mHalfStrokeWidth, mTextPaint);
        if (mProgress < mTargetProgress) {
            mProgress += 1;
            invalidate();
        }
    }

    public int getRealSize(int measureSpec) {
        int result = 1;
        int mode = MeasureSpec.getMode(measureSpec);
        int size = MeasureSpec.getSize(measureSpec);

        if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.UNSPECIFIED) {
            //Calculate by yourself
            result = (int) (mRadius * 2 + mStrokeWidth);
        } else {
            result = size;
        }

        return result;
    }

    private void initRect() {
        if (mRect == null) {
            mRect = new RectF();
            int viewSize = (int) (mRadius * 2);
            int left = (mWidth - viewSize) / 2;
            int top = (mHeight - viewSize) / 2;
            int right = left + viewSize;
            int bottom = top + viewSize;
            mRect.set(left, top, right, bottom);
        }
    }
}

Then add the following to the layout file:

```xml <com.jay.progressbardemo.CirclePgBar android:layout_width="match_parent" android:layout_height="

❮ Git Five Minutes Tutorial Cpp Static Usage ❯