package com.gh.common.view; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import android.text.TextPaint; import android.text.TextUtils; import android.util.AttributeSet; import android.widget.ProgressBar; import androidx.annotation.StringRes; import androidx.core.content.ContextCompat; import com.gh.gamecenter.core.utils.DisplayUtils; import com.gh.gamecenter.R; public class DownloadProgressBar extends ProgressBar { public static final int MAX_LENGTH = 1000; public static final int DOWNLOAD_NORMAL_STYLE = 0; public static final int DOWNLOAD_IMAGE_STYLE = 2; public enum DownloadType { NORMAL, NONE, NONE_WITH_HINT, PLUGIN, LAUNCH_OR_OPEN, INSTALL_NORMAL, INSTALL_PLUGIN, DOWNLOADING_NORMAL, DOWNLOADING_PLUGIN, RESERVABLE, RESERVED, H5_GAME, UPDATING, TEENAGER_MODEL, SPECIAL_DOWNLOAD, XAPK_UNZIPPING, XAPK_SUCCESS, XAPK_FAILURE, } private PorterDuffXfermode mDuffXFerMode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN); private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); // 仅用于测量文字是否超出范围,不用于画文字 private TextPaint mFakeTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); private DownloadType mDownloadType; private String mText; private int mDownloadStyle; private int mDefaultColor; private int mTextSize; private boolean mShowDownloadPercent = false; private Rect mTextBound = new Rect(); public DownloadProgressBar(Context context) { super(context); } public DownloadProgressBar(Context context, AttributeSet attrs) { super(context, attrs); if (attrs != null) { TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.DownloadProgressBar); mDownloadStyle = ta.getInteger(R.styleable.DownloadProgressBar_downloadStyle, DOWNLOAD_NORMAL_STYLE); mTextSize = ta.getDimensionPixelSize(R.styleable.DownloadProgressBar_textSize, DisplayUtils.sp2px(getContext(), 14)); mShowDownloadPercent = ta.getBoolean(R.styleable.DownloadProgressBar_showDownloadPercent, false); ta.recycle(); } setMax(MAX_LENGTH); setProgressDrawable(getResources().getDrawable(R.drawable.game_item_btn_download_style)); } Bitmap srcBitmap; Canvas srcCanvas; RectF rectF; private void create() { srcBitmap = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888); srcCanvas = new Canvas(srcBitmap); rectF = new RectF(0, 0, getProgress() * getWidth() / MAX_LENGTH, getMeasuredHeight()); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (TextUtils.isEmpty(mText)) return; mPaint.setColor(mDefaultColor == 0 ? ContextCompat.getColor(getContext(), R.color.text_theme) : mDefaultColor); // 初始化颜色 mPaint.setTextSize(mTextSize); mFakeTextPaint.setTextSize(mTextSize); mFakeTextPaint.setStyle(Paint.Style.FILL_AND_STROKE); mFakeTextPaint.setTextAlign(Paint.Align.CENTER); mPaint.setStyle(Paint.Style.FILL_AND_STROKE); mPaint.setXfermode(null); create(); Paint.FontMetricsInt fontMetrics = mPaint.getFontMetricsInt(); int baseline = (getHeight() - fontMetrics.bottom - fontMetrics.top) / 2; mPaint.setTextAlign(Paint.Align.CENTER); canvas.getClipBounds(mTextBound); //The dimensions of your canvas int width = mTextBound.width() - 20; //10 to keep some space on the right for the "..." String txt = TextUtils.ellipsize(mText, mFakeTextPaint, width, TextUtils.TruncateAt.END).toString(); srcCanvas.drawText(txt, getWidth() / 2, baseline, mPaint); mPaint.setXfermode(mDuffXFerMode); if (getProgress() != 0) { int color = Color.WHITE; if (DOWNLOAD_IMAGE_STYLE == mDownloadStyle) { color = Color.BLACK; } mPaint.setColor(color); // 反向颜色 } srcCanvas.drawRect(rectF, mPaint); canvas.drawBitmap(srcBitmap, 0, 0, null); } public void setText(String text) { mText = text; invalidate(); } public String getText() { if (mText != null && mText.contains("%")) { return getResources().getString(R.string.downloading); } return mText; } public void setText(@StringRes int res) { if (mShowDownloadPercent && res == R.string.downloading) { setText(getProgressPercent()); } else { setText(getResources().getString(res)); } } public void setDownloadStyle(int downloadStyle) { this.mDownloadStyle = downloadStyle; } @Override public synchronized void setProgress(int progress) { super.setProgress(progress); if (getResources().getString(R.string.downloading).equals(mText)) { setText(getProgressPercent()); } } private String getProgressPercent() { return getProgress() / 10 + "%"; } public void setDownloadType(DownloadType downloadType) { switch (downloadType) { case NORMAL: case NONE_WITH_HINT: case INSTALL_NORMAL: case H5_GAME: if (mDownloadStyle == DOWNLOAD_IMAGE_STYLE) { setProgressDrawable(getResources().getDrawable(R.drawable.text_white_background)); mDefaultColor = Color.BLACK; } else { setProgressDrawable(getResources().getDrawable(R.drawable.download_button_normal_style)); mDefaultColor = Color.WHITE; } setProgress(0); break; case PLUGIN: case INSTALL_PLUGIN: setProgressDrawable(getResources().getDrawable(R.drawable.download_button_pluggable_style)); mDefaultColor = Color.WHITE; setProgress(0); break; case NONE: setProgressDrawable(getResources().getDrawable(R.drawable.button_round_gray_light)); mDefaultColor = ContextCompat.getColor(getContext(), R.color.text_tertiary); setProgress(0); break; case LAUNCH_OR_OPEN: if (mDownloadStyle == DOWNLOAD_IMAGE_STYLE) { setProgressDrawable(getResources().getDrawable(R.drawable.detail_download_open_image_style)); mDefaultColor = Color.WHITE; } else { setProgressDrawable(getResources().getDrawable(R.drawable.download_button_normal_style)); mDefaultColor = Color.WHITE; } setProgress(0); break; case DOWNLOADING_NORMAL: if (mDownloadStyle == DOWNLOAD_IMAGE_STYLE) { setProgressDrawable(getResources().getDrawable(R.drawable.detail_downloading_normal_image_style)); mDefaultColor = Color.WHITE; } else { setProgressDrawable(getResources().getDrawable(R.drawable.detail_downloading_normal_style)); mDefaultColor = ContextCompat.getColor(getContext(), R.color.text_theme); } break; case DOWNLOADING_PLUGIN: setProgressDrawable(getResources().getDrawable(R.drawable.detail_downloading_normal_style)); mDefaultColor = ContextCompat.getColor(getContext(), R.color.text_theme); break; case RESERVABLE: setProgressDrawable(getResources().getDrawable(R.drawable.button_reserve)); mDefaultColor = ContextCompat.getColor(getContext(), R.color.white); break; case UPDATING: setProgressDrawable(getResources().getDrawable(R.drawable.download_button_updating_style)); mDefaultColor = ContextCompat.getColor(getContext(), R.color.white); break; case RESERVED: setProgressDrawable(getResources().getDrawable(R.drawable.button_round_gray_light)); mDefaultColor = ContextCompat.getColor(getContext(), R.color.text_tertiary); break; case XAPK_FAILURE: case XAPK_SUCCESS: case XAPK_UNZIPPING: setProgressDrawable(getResources().getDrawable(R.drawable.progressbar_xapk_detail_style)); mDefaultColor = ContextCompat.getColor(getContext(), R.color.white); break; case TEENAGER_MODEL: case SPECIAL_DOWNLOAD: setProgressDrawable(getResources().getDrawable(R.drawable.download_button_normal_style)); mDefaultColor = ContextCompat.getColor(getContext(), R.color.white); break; } mDownloadType = downloadType; } public DownloadType getDownloadType() { return mDownloadType; } }