This custom view shows a progress bar in the foreground of a TextView. Check the Pixplicity Authenticator app for an example.
Simply call setProgress(value)
on the view to set the position of the background bar.
ProgressTextView.java
package com.pixplicity.example.ui;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Shader;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.view.View;
import com.pixplicity.example.R;
public class ProgressTextView extends android.support.v7.widget.AppCompatTextView {
private Paint mPaintBg, mPaintText;
private int mColorBg, mColorFg, mColorWarning;
private float mProgress;
private Shader mShader;
final private Rect mTextBounds = new Rect();
public ProgressTextView(Context context) {
super(context);
init();
}
public ProgressTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ProgressTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mPaintBg = new Paint();
mPaintBg.setColor(mColorBg);
mPaintBg.setStyle(Paint.Style.FILL);
mPaintText = getPaint();
mColorBg = ContextCompat.getColor(getContext(), R.color.progress_background);
mColorFg = ContextCompat.getColor(getContext(), R.color.progress_foreground);
mColorWarning = ContextCompat.getColor(getContext(), R.color.progress_warning);
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
setProgress(isInEditMode() ? 50 : 0);
}
@SuppressLint("WrongCall")
public void setProgress(float percentage) {
mProgress = percentage;
mShader = null;
invalidate();
}
@Override
public void onDraw(Canvas canvas) {
if (mShader == null) {
Bitmap original = Bitmap.createBitmap(
getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas originalCanvas = new Canvas(original);
// Drawing progress bar onto temp canvas
mPaintBg.setColor(mColorBg);
originalCanvas.drawRect(0, 0, originalCanvas.getWidth(), originalCanvas.getHeight(), mPaintBg);
mPaintBg.setColor(mProgress < 25 ? mColorWarning : mColorFg);
mPaintText.getTextBounds(getText().toString(), 0, getText().length(), mTextBounds);
final int textWidth = Math.min(mTextBounds.width(), originalCanvas.getWidth());
originalCanvas.drawRect(getPaddingLeft(), 0, getPaddingLeft() + (mProgress * textWidth) / 100f, originalCanvas.getHeight(), mPaintBg);
// Turn temp canvas into a shader
mShader = new BitmapShader(original,
Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaintText.setShader(mShader);
}
// Draw text using the shader
float bottom = .5f * (canvas.getHeight() + mTextBounds.height());
canvas.drawText(
getText().toString(),
getPaddingLeft(),
bottom,
mPaintText);
}
}