您的位置:首页 > 运维架构

深度自定义的propressBar和seekBar,可竖直显示,继承自View

2015-01-30 15:02 423 查看
android本身提供的progressBar和seekBar也可以自定义很多属性和样式,可是有时候在面对产品的诸多UI和功能要求时,我们会发现系统控件有时候并不是那么好用,功能不能做到随心所欲。楼主最近在做电视上的设置项目,需要用到各种各样的propressBar和seekBar,横着的,竖着的,样式千奇百怪,实在是很蛋疼,最后自己继承自View写了一个比较统一且样式设置灵活的progressBar。

首先自定义了几个xml属性

<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>

自定义了6个xml属性,分别代表:

background: 进度条的背景图片

progress:  进度条中已经走过的进度用什么图片显示

thumb:针对seekBar的属性,即滑块用什么什么图片显示

thumbWidth:针对seekBar的属性,滑块的宽度

progressWidth:进度条的宽度(已走过的进度宽度)

orientation:进度条的方向(水平或者竖直)

xml中的调用示例

<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里面的涂鸦,根据当前进度分别画背景,画进度条,画滑块。代码应该还是很好理解的就不做详细说明了。



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐