根据产品的需求,新项目中使用到一个进度条,然后顶部显示相应的数字进度,数字进度随着进度条而移动,所以就自定义了一个进度条,满足产品需求。直接上代码。
import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.support.v7.widget.AppCompatSeekBar; import android.util.AttributeSet; import android.view.MotionEvent; import com.xwsd.app.R; /** * Created by qiang.lin on 2017/11/28. */ public class MySeekBar extends AppCompatSeekBar { /** * SeekBar数值文字颜色 */ private int mTextColor; /** * SeekBar数值文字大小 */ private float mTextSize; /** * SeekBar数值文字内容 */ private String mText; /** * SeekBar数值文字背景宽高 */ private float mBgWidth=0, mBgHeight=50; /** * 画笔 */ private Paint mPaint; /** * SeekBar数值文字宽度 */ private float mTextWidth; /** * SeekBar数值文字基线Y坐标 */ private float mTextBaseLineY; /** * SeekBar的进度 */ private int progress; public MySeekBar(Context context) { this(context, null); } public MySeekBar(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MySeekBar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray ta = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MySeekBar, defStyleAttr, 0); int count = ta.getIndexCount(); for(int i = 0; i < count; i++) { int index = ta.getIndex(i); switch (index) { case R.styleable.MySeekBar_textColor: mTextColor = ta.getColor(index, Color.WHITE); break; case R.styleable.MySeekBar_textSize: mTextSize = ta.getDimension(index, 15f); break; } } ta.recycle(); //设置画笔 mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setColor(mTextColor); mPaint.setTextSize(mTextSize); //设置SeekBar顶部数值文字预留空间,左右为数值背景图片的一半,顶部为数值背景图片高度加五的间隔 setPadding((int) Math.ceil(mBgWidth) / 2, (int) Math.ceil(mBgHeight) + 5, (int) Math.ceil(mBgWidth) / 2, 0); setEnabled(false); } @Override protected synchronized void onDraw(Canvas canvas) { super.onDraw(canvas); getTextLocation(); Rect bgRect = getProgressDrawable().getBounds(); //计算数值背景X坐标 float bgX = bgRect.width() * getProgress() / getMax(); //计算数值背景Y坐标 float bgY = 0; //计算数值文字X坐标 float textY = (float) (mTextBaseLineY + bgY + (0.16 * mBgHeight / 2)); float textX; if(progress<=5){ textX=0; }else if(progress>=95){ textX=bgX-mTextWidth; }else{ textX = bgX + (mBgWidth - mTextWidth) / 2; } //绘制文字 canvas.drawText(mText, textX, textY, mPaint); } @Override public boolean onTouchEvent(MotionEvent event) { invalidate(); return super.onTouchEvent(event); } /** * 计算SeekBar数值文字的显示位置 */ private void getTextLocation() { Paint.FontMetrics fm = mPaint.getFontMetrics(); progress=getProgress(); mText = getResources().getString(R.string.sale) + getProgress()+getResources().getString(R.string.percentage); //测量文字宽度 mTextWidth = mPaint.measureText(mText); //计算文字基线Y坐标 mTextBaseLineY = mBgHeight / 2 - fm.descent + (fm.descent - fm.ascent) / 2; } }
资源文件attrs添加如下
<declare-styleable name="MySeekBar"> <attr name="textSize" format="dimension" /> <attr name="textColor" format="color" /> </declare-styleable>drawable资源如下
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@android:id/background" android:height="@dimen/DIMEN_2"> <shape> <size android:height="@dimen/DIMEN_2" /> <solid android:color="@color/colorPrimary"/> </shape> </item> <item android:id="@android:id/progress" android:height="@dimen/DIMEN_2"> <clip> <shape> <size android:height="@dimen/DIMEN_2" /> <solid android:color="@color/color_white"/> </shape> </clip> </item> </layer-list>xml使用
<com.xwsd.app.view.MySeekBar android:id="@+id/progress_bar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:max="100" android:maxHeight="1dp" android:minHeight="1dp" android:paddingEnd="0dp" android:paddingStart="0dp" android:progress="0" android:progressDrawable="@drawable/seek_bar_style" android:thumb="@mipmap/project_progress" android:thumbOffset="0dp" app:textColor="@color/color_white" app:textSize="12sp"/>到此自定义进度条完成。效果图如下