标签:
android本身提供的progressBar和seekBar也可以自定义很多属性和样式,可是有时候在面对产品的诸多UI和功能要求时,我们会发现系统控件有时候并不是那么好用,功能不能做到随心所欲。
楼主最近在做电视上的设置项目,需要用到各种各样的propressBar和seekBar,横着的,竖着的,样式千奇百怪,实在是很蛋疼,最后自己继承自View写了一个比较统一且样式设置灵活的progressBar。
<declare-styleable name="TvProgressBar"> <!-- 背景图片 --> <attr name="background" format="reference" /> <!-- 已走过的进度图片 --> <attr name="progress" format="reference" /> <!-- 滑块图片 --> <attr name="thumb" format="reference" /> <!-- 滑块宽度 --> <attr name="thumbWidth" format="reference|dimension" /> <!-- 进度条宽度 --> <attr name="progressWidth" format="reference|dimension" /> <!-- 进度条方向 0:水平 1:竖直 --> <attr name="orientation" format="reference|integer" /> </declare-styleable>
background: 进度条的背景图片
progress: 进度条中已经走过的进度用什么图片显示
thumb:针对seekBar的属性,即滑块用什么什么图片显示
thumbWidth:针对seekBar的属性,滑块的宽度
progressWidth:进度条的宽度(已走过的进度宽度)
orientation:进度条的方向(水平或者竖直)
<com.pptv.tv.view.base.CustomSeekBar android:id="@+id/progressbar" android:layout_width="100dp" android:layout_height="350dp" tv:background="@drawable/sound_progress_bg" tv:orientation="@integer/pptv_orientation_vertical" tv:progressWidth="2dp" tv:thumb="@drawable/sound_progress_point" tv:thumbWidth="12dp" />
出来的效果如下图所示:
图片资源就不列了,
sound_progress_point就是那个圆形蓝色的滑块,
sound_progress_bg就是那条白色的细线
pptv_orientation_vertical = 1,表示方向竖直。
import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.KeyEvent; import android.view.View; import com.pptv.tv.R; public class CustomSeekBar extends View { public static final int HORIZONTAL = 0; public static final int VERTICAL = 1; private Drawable mBackGroundDrawable; private Drawable mProgressDrawable; private Drawable mThumbDrawable; private int mOrientation = 0; private int mProgressWidth = 0; private int mThumbWidth = 0; private int maxProgress = 100; private int mProgress = 50; private OnSeekBarChangeListener mSeekBarChangeListener; public CustomSeekBar(Context context) { this(context, null); } public CustomSeekBar(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CustomSeekBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TvProgressBar, defStyle, 0); mBackGroundDrawable = a .getDrawable(R.styleable.TvProgressBar_background); mProgressDrawable = a.getDrawable(R.styleable.TvProgressBar_progress); mThumbDrawable = a.getDrawable(R.styleable.TvProgressBar_thumb); mProgressWidth = a.getDimensionPixelSize( R.styleable.TvProgressBar_progressWidth, 0); mThumbWidth = a.getDimensionPixelSize( R.styleable.TvProgressBar_thumbWidth, 0); mOrientation = a.getInteger(R.styleable.TvProgressBar_orientation, 0); a.recycle(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int width = getWidth(); int height = getHeight(); if (width <= 0 || height <= 0) { return; } float rate = ((float) mProgress) / maxProgress; // 画背景 if (mBackGroundDrawable != null) { int bgleft = 0,bgright=0,bgtop=0,bgbottom=0; if (mOrientation == HORIZONTAL){ bgleft = mThumbWidth / 2; bgright = width - mThumbWidth / 2; bgtop = (height - mProgressWidth) / 2; bgbottom = bgtop + mProgressWidth; }else if (mOrientation == VERTICAL){ bgleft = (width - mProgressWidth) / 2; bgright = bgleft + mProgressWidth; bgtop = mThumbWidth / 2; bgbottom = height - mThumbWidth / 2; } mBackGroundDrawable.setBounds(bgleft, bgtop, bgright, bgbottom); mBackGroundDrawable.draw(canvas); } // 画进度条 if (mProgressDrawable != null) { int progressleft=0,progressright=0,progresstop=0,progressbottom=0; if (mOrientation == HORIZONTAL){ progressleft = mThumbWidth / 2; progressright = (int) (progressleft + rate * (width - mThumbWidth)); progresstop = (height - mProgressWidth) / 2; progressbottom = progresstop + mProgressWidth; }else if (mOrientation == VERTICAL){ progressleft = (width - mProgressWidth) / 2; progressright = progressleft + mProgressWidth; progressbottom = height - mThumbWidth / 2; progresstop = (int) (progressbottom - rate * (height - mThumbWidth)); } mProgressDrawable.setBounds(progressleft, progresstop, progressright, progressbottom); mProgressDrawable.draw(canvas); } // 画滑块 if (mThumbDrawable != null) { int thumbleft=0,thumbright=0,thumbtop=0,thumbbottom=0; if (mOrientation == HORIZONTAL){ thumbleft = (int) ((width - mThumbWidth) * rate); thumbright = thumbleft + mThumbWidth; thumbtop = (height - mThumbWidth) / 2; thumbbottom = thumbtop + mThumbWidth; }else if (mOrientation == VERTICAL){ thumbleft = (width - mThumbWidth) / 2; thumbright = thumbleft + mThumbWidth; thumbbottom = (int) (height - rate * (height - mThumbWidth)); thumbtop = thumbbottom - mThumbWidth; } mThumbDrawable.setBounds(thumbleft, thumbtop, thumbright, thumbbottom); mThumbDrawable.draw(canvas); } } public void setOnSeekBarChangeListener(OnSeekBarChangeListener listener) { mSeekBarChangeListener = listener; } public interface OnSeekBarChangeListener { public abstract void onProgressChanged(); } public void setOrientation(int orientation){ mOrientation = orientation; invalidate(); } public void setProgress(int progress) { if (progress < 0 || progress > maxProgress) { return; } mProgress = progress; invalidate(); if (mSeekBarChangeListener != null) { mSeekBarChangeListener.onProgressChanged(); } } public int getProgress() { return mProgress; } public int getMaxProgress() { return maxProgress; } public boolean increase() { if (mProgress < maxProgress) { mProgress++; setProgress(mProgress); return true; } return false; } public boolean reduce() { if (mProgress > 0) { mProgress--; setProgress(mProgress); return true; } return false; } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (mOrientation == HORIZONTAL) { if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) { if (mProgress > 0) { mProgress--; setProgress(mProgress); return true; } } if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) { if (mProgress < maxProgress) { mProgress++; setProgress(mProgress); return true; } } } if (mOrientation == VERTICAL) { if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) { if (mProgress > 0) { mProgress--; setProgress(mProgress); return true; } } if (keyCode == KeyEvent.KEYCODE_DPAD_UP) { if (mProgress < maxProgress) { mProgress++; setProgress(mProgress); return true; } } } return super.onKeyDown(keyCode, event); } }
重点是在onDraw里面的涂鸦,根据当前进度分别画背景,画进度条,画滑块。代码应该还是很好理解的就不做详细说明了。
深度自定义的propressBar和seekBar,可竖直显示,继承自View
标签:
原文地址:http://www.cnblogs.com/xiaomo8086/p/4262382.html