Android自定义SeekBar

来源:互联网 发布:中国人口 知乎 编辑:程序博客网 时间:2024/06/05 15:20
  1. 效果图:
    运行效果图
    好了,废话不过说,直接上代码:

自定义一个MySeekbar类:

public class MySeekBar extends android.support.v7.widget.AppCompatSeekBar {    /**     * SeekBar数值文字颜色     */    private int mTextColor;    /**     * SeekBar数值文字大小     */    private float mTextSize;    /**     * SeekBar数值文字内容     */    private String mText;    /**     * SeekBar数值文字背景     */    private Bitmap mBackgroundBitmap;    /**     * SeekBar数值文字背景宽高     */    private float mBgWidth, mBgHeight;    /**     * 画笔     */    private Paint mPaint;    /**     * SeekBar数值文字方向     */    private int mTextOrientation;    /**     * SeekBar数值文字宽度     */    private float mTextWidth;    /**     * SeekBar数值文字基线Y坐标     */    private float mTextBaseLineY;    //文字方向    private static final int ORIENTATION_TOP = 1;    private static final int ORIENTATION_BOTTOM = 2;    private String mSeekBarText;    public MSeekBar(Context context) {        this(context, null);    }    public MSeekBar(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;                case R.styleable.MySeekBar_textBackground:                    //获取文字背景图片的宽高                    int bgResId = ta.getResourceId(index, R.mipmap.bg_seekbar_display2);                    mBackgroundBitmap = BitmapFactory.decodeResource(getResources(), bgResId);                    mBgWidth = mBackgroundBitmap.getWidth();                    mBgHeight = mBackgroundBitmap.getHeight();                    break;                case R.styleable.MySeekBar_textOrientation:                    mTextOrientation = ta.getInt(index, ORIENTATION_TOP);                    break;            }        }        ta.recycle();       /* TypedArray typedArray=context.obtainStyledAttributes(R.styleable.MySeekBar);        mSeekBarText = typedArray.getString(R.styleable.MySeekBar_imageText);        typedArray.recycle();*/        //设置画笔        mPaint = new Paint();        mPaint.setAntiAlias(true);        mPaint.setColor(mTextColor);        mPaint.setTextSize(mTextSize);        //设置文字显示方向        if(mTextOrientation == ORIENTATION_TOP) {            //设置SeekBar顶部数值文字预留空间,左右为数值背景图片的一半,顶部为数值背景图片高度加五的间隔            setPadding((int) Math.ceil(mBgWidth) / 2, (int) Math.ceil(mBgHeight) + 5, (int) Math.ceil(mBgWidth), 0);        } else {            //设置SeekBar顶部数值文字预留空间,左右为数值背景图片的一半,底部为数值背景图片高度加五的间隔            setPadding((int) Math.ceil(mBgWidth) / 2, 0, (int) Math.ceil(mBgWidth) / 2, (int) Math.ceil(mBgHeight) + 5);        }    }    @Override    public boolean onFilterTouchEventForSecurity(MotionEvent event) {        return false;    }    @Override    protected synchronized void onDraw(Canvas canvas) {        super.onDraw(canvas);        int progress = getProgress();        int max = getMax();        if (progress>max/2){            mText="较多";        }else if(progress>max/3&&progress<max/2){            mText="适中";        }else {            mText="一般";        }        getTextLocation();        Rect bgRect = getProgressDrawable().getBounds();        //计算数值背景X坐标        float bgX = bgRect.width() * getProgress() / getMax();        //计算数值背景Y坐标        float bgY = 0;        if(mTextOrientation == ORIENTATION_BOTTOM) {            bgY = mBgHeight + 10;        }        //计算数值文字X坐标        float textX = bgX + (mBgWidth - mTextWidth)/4+5;        float textY = (float) (mTextBaseLineY + bgY + (0.16 * mBgHeight / 2) - 10);        //绘制文字和背景        canvas.drawBitmap(mBackgroundBitmap, bgX, bgY, mPaint);        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();        //mText = "一般";        //测量文字宽度        mTextWidth = mPaint.measureText(mText);        //计算文字基线Y坐标        mTextBaseLineY = mBgHeight / 2 - fm.descent + (fm.descent - fm.ascent);    }}

在values文件下新建attrs.xml

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="MySeekBar">        <attr name="textSize" format="dimension" />        <attr name="textColor" format="color" />        <attr name="textBackground" format="reference" />        <attr name="textOrientation" format="enum">            <enum name="top" value="1" />            <enum name="bottom" value="2" />        </attr>    </declare-styleable>

这样一个自定义的seekBar就完成了,具体的使用方式跟常见的Android控件的使用方式一样。

<com.kang.MSeekBar    android:id="@+id/sb_main1"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:max="100"    android:progress="50"                      android:thumb="@null"                         app:textColor="@color/white"    app:textOrientation="top"    app:textSize="12sp"/>

现在运行你的项目就可以看到上面的效果了。
完整代码请QQ联系博主:QQ 2812456302

原创粉丝点击