Percentage + background icon progress bar

Keywords: Android xml encoding

Recently, there is a demand for project development, in fact, it is the commonly used percentage progress bar. There are a lot of materials on this function, not to mention much. The function I mentioned below is to add a background icon to the percentage text on the basis of the original. The effect chart is as follows:

Only a percentage of texts or background icons found on the Internet are user-defined view s, which do not meet the needs of the project, so I researched and wrote one myself. (for the convenience of testing and using, I try not to screenshot the content of this article, completely pure code)

Custom ImageTextProgressBar

/**
 * @date 2018/8/22
 * @describe Percentage + background icon progress bar
 * Please strictly use the background picture without blank cutout, otherwise the experience will be affected. If you have to use it (the artist may not cut it for you), you can also modify the code adjustment
 * @e-mail:897971804@qq.com
 */
public class ImageTextProgressBar extends RelativeLayout {
    private static final String TAG = "ImageTextProgressBar";
    //Text background
    private Drawable textBackground;
    //Percentage text color
    private int textColor;
    //% text size
    private int textSize = 15;
    //Percentage text content
    private String textContent;
    //Customize the background of progress bar. Please strictly use the cutout without blank space
    private Drawable progressDrawable;
    //Progress bar current progress
    private int progress;
    private int MAX = 100;

    private View mView;
    private ProgressBar mProgressBar;
    private TextView mTextView;

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    public ImageTextProgressBar(Context context) {
        this(context, null, 0);
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    public ImageTextProgressBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    public ImageTextProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ImageTextProgressBar);
        textBackground = a.getDrawable(R.styleable.ImageTextProgressBar_itpbTextBackground);
        textColor = a.getColor(R.styleable.ImageTextProgressBar_itpbTextColor, Color.WHITE);
        textSize = a.getDimensionPixelSize(R.styleable.ImageTextProgressBar_itpbTextSize, textSize);
        textContent = a.getString(R.styleable.ImageTextProgressBar_itpbTextContent);

        progressDrawable = a.getDrawable(R.styleable.ImageTextProgressBar_itpbProgressDrawable);

        progress = a.getInteger(R.styleable.ImageTextProgressBar_itpbProgress, 0);
        a.recycle();
        initView();
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    private void initView() {
        if (mView == null) {
            mView = LayoutInflater.from(getContext()).inflate(R.layout.image_text_pb, null);
            mProgressBar = (ProgressBar) mView.findViewById(R.id.pb_progressbar);
            mTextView = (TextView) mView.findViewById(R.id.pb_precent);
            if (textBackground != null) {
                mTextView.setBackground(textBackground);
            }
            //Set text
            mTextView.setTextColor(textColor);
            mTextView.setTextSize(textSize);
            mTextView.setText(textContent);
            //Progress bar
            mProgressBar.setProgress(progress);
            if (progressDrawable != null) {
                mProgressBar.setProgressDrawable(progressDrawable);
            }
            addView(mView);
        }
    }

    public void setProgress(final int precent) {
        if (precent < 0 || precent > MAX) {
            return;
        }
        ViewTreeObserver vto2 = mProgressBar.getViewTreeObserver();
        vto2.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
            @Override
            public void onGlobalLayout() {
                mProgressBar.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                int width = mProgressBar.getWidth();
                int tvWidth = mTextView.getMeasuredWidth();
                mProgressBar.setProgress(precent);
                mTextView.setText(precent + "%");
                float offsetX = (float) (mProgressBar.getProgress() * 1.0 / mProgressBar.getMax() * width);
                int maxOffset = width - tvWidth;
                int minOffset = tvWidth / 2;
                //Prevent the background image from moving out of the screen, so add this judgment
                if (offsetX < minOffset) {
                    offsetX = 0;
                } else if (offsetX >= minOffset && offsetX <= maxOffset) {
                    offsetX -= tvWidth / 2;
                } else if (offsetX > maxOffset) {
                    offsetX = maxOffset;
                }
                mTextView.setTranslationX(offsetX);
            }
        });
    }

    public int getProgress() {
        return mProgressBar.getProgress();
    }

    public static int dpToPx(int dp, Context context) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics());
    }
}



Layout file
image_text_pb.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">


    <ProgressBar
        android:id="@+id/pb_progressbar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="5dp"
        android:layout_centerVertical="true"
        android:max="100"
        android:progress="0"
        android:progressDrawable="@drawable/progress_drawable"/>

    <TextView
        android:id="@+id/pb_precent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:background="@mipmap/love"
        android:gravity="center"
        android:text="0%"
        android:textColor="@android:color/white"
        android:textSize="12sp"/>

</RelativeLayout>

Customizing the background color of the progress bar

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- background  gradient Gradual change,corners Fillet is defined -->
    <item android:id="@android:id/background">
        <shape>
            <corners android:radius="5dp" />
            <solid android:color="#9a9a9a" />
        </shape>
    </item>
    <!-- Progress bar -->
    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <corners android:radius="5dp" />
                <solid android:color="#E34f4f" />
            </shape>
        </clip>
    </item>

</layer-list>

Custom properties

<declare-styleable name="ImageTextProgressBar">
    <attr name="itpbTextBackground" format="reference"/>
    <attr name="itpbTextColor" format="color"/>
    <attr name="itpbTextSize" format="dimension"/>
    <attr name="itpbTextContent" format="string"/>
    <attr name="itpbProgressDrawable" format="reference"/>
    <attr name="itpbProgress" format="integer"/>
</declare-styleable>

textview background textbackground.xml or use the image directly

Please strictly use the background picture without blank cutout, otherwise the experience will be affected. If you have to use it (the artist may not cut it for you), you can also modify the code adjustment

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <solid android:color="#E34F4F"/>
    <corners android:radius="5dp"/>
    <size
        android:width="40dp"
        android:height="6dp"/>
</shape>

Final rendering:

All code has been pasted.

I feel that there are still some flaws, but they do not affect the use. You can test the use, and you can ask questions at any time to learn together.

Thank you!!! have fun!!!

Posted by Scummy12 on Wed, 01 Jan 2020 16:08:04 -0800