带数字显示的自定义SeekBar
2016-10-14 11:12
344 查看
由于项目需要做个单向滑动SeekBar,而系统自带的SeekBar并没能提供滑块上面的数字,所以只能自定义了。
效果图如下:
![](https://img-blog.csdn.net/20161014103859731)
使用方法如下:
SeekBar底部背景和进度背景
bg_seekbar_progress_drawable.xml
滑块图片
文字在滑块的顶部(top)或底部(bottom)
滑块顶部(底部)文字背景图片
attrs.xml
MSeekBar源码
在MainActivity中调用和普通SeekBar一样
去Github查看源码
效果图如下:
使用方法如下:
<com.whoisaa.mseekbar.MSeekBar android:layout_width="match_parent" android:layout_height="wrap_content" android:max="100" android:progress="0" android:progressDrawable="@drawable/bg_seekbar_progress_drawable" android:thumb="@mipmap/icon_seekbar_thumb" app:textBackground="@mipmap/bg_seekbar_display2" app:textColor="@color/white" app:textOrientation="top" app:textSize="14sp"/>
SeekBar底部背景和进度背景
android:progressDrawable="@drawable/bg_seekbar_progress_drawable"
bg_seekbar_progress_drawable.xml
<?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="15dp"> <shape> <corners android:radius="10dp"/> <size android:height="15dp" /> <solid android:color="#CBCBCB"/> </shape> </item> <!-- 进度背景 --> <item android:id="@android:id/progress" android:height="15dp"> <clip> <shape> <corners android:radius="10dp"/> <size android:height="15dp" /> <solid android:color="#0069B6"/> </shape> </clip> </item> </layer-list>
滑块图片
android:thumb="@mipmap/icon_seekbar_thumb"
文字在滑块的顶部(top)或底部(bottom)
app:textOrientation="top"
滑块顶部(底部)文字背景图片
app:textBackground="@mipmap/bg_seekbar_display2"
attrs.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="MSeekBar"> <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> </resources>
MSeekBar源码
package com.whoisaa.mseekbar; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.SeekBar; public class MSeekBar extends SeekBar { /** * 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; public MSeekBar(Context context) { this(context, null); } public MSeekBar(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MSeekBar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray ta = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MSeekBar, defStyleAttr, 0); int count = ta.getIndexCount(); for(int i = 0; i < count; i++) { int index = ta.getIndex(i); switch (index) { case R.styleable.MSeekBar_textColor: mTextColor = ta.getColor(index, Color.WHITE); break; case R.styleable.MSeekBar_textSize: mTextSize = ta.getDimension(index, 15f); break; case R.styleable.MSeekBar_textBackground: //获取文字背景图片的宽高 int bgResId = ta.getResourceId(index, R.mipmap.bg_seekbar_display1); mBackgroundBitmap = BitmapFactory.decodeResource(getResources(), bgResId); mBgWidth = mBackgroundBitmap.getWidth(); mBgHeight = mBackgroundBitmap.getHeight(); break; case R.styleable.MSeekBar_textOrientation: mTextOrientation = ta.getInt(index, ORIENTATION_TOP); break; } } ta.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) / 2, 0); } else { //设置SeekBar顶部数值文字预留空间,左右为数值背景图片的一半,底部为数值背景图片高度加五的间隔 setPadding((int) Math.ceil(mBgWidth) / 2, 0, (int) Math.ceil(mBgWidth) / 2, (int) Math.ceil(mBgHeight) + 5); } } @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; if(mTextOrientation == ORIENTATION_BOTTOM) { bgY = mBgHeight + 10; } //计算数值文字X坐标 float textX = bgX + (mBgWidth - mTextWidth) / 2; 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 = "¥" + getProgress(); //测量文字宽度 mTextWidth = mPaint.measureText(mText); //计算文字基线Y坐标 mTextBaseLineY = mBgHeight / 2 - fm.descent + (fm.descent - fm.ascent) / 2; } }
在MainActivity中调用和普通SeekBar一样
package com.whoisaa.mseekbar; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.widget.SeekBar; import android.widget.TextView; public class MainActivity extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener { private TextView mTextView1, mTextView2; private MSeekBar mSeekBar1, mSeekBar2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView1 = (TextView) findViewById(R.id.tv_main1); mTextView2 = (TextView) findViewById(R.id.tv_main2); mSeekBar1 = (MSeekBar) findViewById(R.id.sb_main1); mSeekBar2 = (MSeekBar) findViewById(R.id.sb_main2); mSeekBar1.setOnSeekBarChangeListener(this); mSeekBar2.setOnSeekBarChangeListener(this); } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if(seekBar.equals(mSeekBar1)) { mTextView1.setText("滑块一当前值为" + progress); } else if(seekBar.equals(mSeekBar2)) { mTextView2.setText("滑块二当前值为" + progress); } } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }
去Github查看源码
相关文章推荐
- Android自定义SeekBar滑动显示数字
- [Asp.Net]如何在GridView将数字显示成金额格式或自定义格式呢?
- 织梦(dedecms)自定义表单,“时间类型”字段显示为数字的解决办法
- WPF自定义LED风格数字显示控件
- 自定义可拖拽显示数字BadgeView(仿QQ可拖拽控件)
- 笔记——Android自定义seekbar中,滑块显示不全解决办法
- 如何在GridView将数字显示成金额格式或自定义格式?
- Android自定义SeekBar,滑动时弹出气泡指示器显示进度
- AlertDialog弹窗引用自定义layout布局动态显示seekbar进度
- 织梦自定义表单添加地区联动显示数字解决办法(支持三级)
- 深度自定义的propressBar和seekBar,可竖直显示,继承自View
- LCD1602 显示数字,字符,自定义字符,字符串,光标
- android自定义Seekbar你还将你的拖动数值显示在旁边固定的TextView上么?
- 一个带数字显示的SeekBar
- 自定义seekbar中,圆球显示不全被覆盖掉一部分问题
- VS MONO Android开发控件悬浮显示提醒 自定义背景颜色、字体、数字颜色、摆放位置
- android自定义Seekbar你还将你的拖动数值显示在旁边固定的TextView上么?
- [Android开发]仿天天P图带气泡显示百分比进度的自定义SeekBar
- Android 自定义SeekBar显示进度百分比
- 织梦自定义表单联动地区显示为数字的解决方法