今天想使用垂直的seebar邻吞,因?yàn)橄到y(tǒng)的是默認(rèn)水平方向的,所以要想使用垂直方向上的seebar就要自定義了葫男。原理很簡(jiǎn)單抱冷,只需要將水平的seebar,翻轉(zhuǎn)90°就可以了梢褐。定義一個(gè)類(lèi)繼承于SeekBar旺遮,并在OnDraw方法里面旋轉(zhuǎn)一下視圖赵讯。代碼如下:
public class VerticalSeekBar extends SeekBar {
public VerticalSeekBar(Context context) {
super(context);
}
public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public VerticalSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(h, w, oldh, oldw);
}
@Override
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(heightMeasureSpec, widthMeasureSpec);
setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
}
protected void onDraw(Canvas c) {
//將SeekBar轉(zhuǎn)轉(zhuǎn)90度
c.rotate(-90);
//將旋轉(zhuǎn)后的視圖移動(dòng)回來(lái)
c.translate(-getHeight(),0);
Log.i("getHeight()",getHeight()+"");
super.onDraw(c);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!isEnabled()) {
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
int i=0;
//獲取滑動(dòng)的距離
i=getMax() - (int) (getMax() * event.getY() / getHeight());
//設(shè)置進(jìn)度
setProgress(i);
Log.i("Progress",getProgress()+"");
//每次拖動(dòng)SeekBar都會(huì)調(diào)用
onSizeChanged(getWidth(), getHeight(), 0, 0);
Log.i("getWidth()",getWidth()+"");
Log.i("getHeight()",getHeight()+"");
break;
case MotionEvent.ACTION_CANCEL:
break;
}
return true;
}
}
另外說(shuō)說(shuō)
View在屏幕上顯示出來(lái)要先經(jīng)過(guò)measure(計(jì)算)和layout(布局).
1、什么時(shí)候調(diào)用onMeasure方法耿眉?
當(dāng)控件的父元素正要放置該控件時(shí)調(diào)用.父元素會(huì)問(wèn)子控件一個(gè)問(wèn)題边翼,“你想要用多大地方啊鸣剪?”组底,然后傳入兩個(gè)參數(shù)——widthMeasureSpec和heightMeasureSpec.
這兩個(gè)參數(shù)指明控件可獲得的空間以及關(guān)于這個(gè)空間描述的元數(shù)據(jù).
當(dāng)然,可以直接傳遞View的高度和寬度到setMeasuredDimension方法里,這樣可以直接告訴父控件筐骇,需要多大地方放置子控件.
更新內(nèi)容:
上面的自定義垂直SeekBar我在使用的過(guò)程中發(fā)現(xiàn)了問(wèn)題债鸡,綁定SeekBar監(jiān)聽(tīng)之后,想實(shí)現(xiàn)拖拽調(diào)節(jié)屏幕亮度功能铛纬,即觸摸控件時(shí)顯示TextView厌均,顯示當(dāng)前屏幕亮度,拖動(dòng)時(shí)實(shí)時(shí)更新告唆,手指離開(kāi)屏幕后TextView隱藏棺弊,可是不知道為什么,按下以后TextView不顯示擒悬,拖動(dòng)時(shí)模她,TextView顯示,數(shù)據(jù)會(huì)實(shí)時(shí)更新茄螃,手機(jī)離開(kāi)屏幕后缝驳,TextView不消失,即onProgressChanged方法有執(zhí)行归苍,但是onStartTrackingTouch用狱、onStopTrackingTouch這兩個(gè)方法莫名奇妙的沒(méi)有被執(zhí)行到,查閱很多資料之后拼弃,發(fā)現(xiàn)了問(wèn)題的所在夏伊,需要在 VerticalSeekBar 類(lèi)中重寫(xiě)這上面提到的三個(gè)方法。下面是重寫(xiě)過(guò)的代碼:
public class VerticalSeekBar extends SeekBar {
private Drawable mThumb;
private OnSeekBarChangeListener mOnSeekBarChangeListener;
public VerticalSeekBar(Context context) {
super(context,null);
}
public VerticalSeekBar(Context context, AttributeSet attrs) {
super(context, attrs,0);
}
public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(h, w, oldh, oldw);
}
public void setOnSeekBarChangeListener(OnSeekBarChangeListener l) {
mOnSeekBarChangeListener = l;
}
@Override
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(heightMeasureSpec, widthMeasureSpec);
setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
}
protected void onDraw(Canvas canvas) {
//將SeekBar轉(zhuǎn)轉(zhuǎn)90度
canvas.rotate(-90);
//將旋轉(zhuǎn)后的視圖移動(dòng)回來(lái)
canvas.translate(-getHeight(),0);
super.onDraw(canvas);
}
void onStartTrackingTouch() {
if (mOnSeekBarChangeListener != null) {
mOnSeekBarChangeListener.onStartTrackingTouch(this);
}
}
void onStopTrackingTouch() {
if (mOnSeekBarChangeListener != null) {
onSizeChanged(getWidth(), getHeight(), 0, 0);
mOnSeekBarChangeListener.onStopTrackingTouch(this);
}
}
void onProgressChanged() {
if (mOnSeekBarChangeListener != null) {
mOnSeekBarChangeListener.onProgressChanged(this,getProgress(),true);
}
}
void onProgressRefresh(float scale, boolean fromUser) {
Drawable thumb = mThumb;
if (thumb != null) {
setThumbPos(getHeight(), thumb, scale, Integer.MIN_VALUE);
invalidate();
}
if (mOnSeekBarChangeListener != null) {
mOnSeekBarChangeListener.onProgressChanged(this, getProgress(), fromUser);
}
}
void setThumbPos(int w, Drawable thumb, float scale, int gap) {
int available = w - getPaddingLeft() - getPaddingRight();
int thumbWidth = thumb.getIntrinsicWidth();
int thumbHeight = thumb.getIntrinsicHeight();
int thumbPos = (int) (scale * available + 0.5f);
int topBound, bottomBound;
if (gap == Integer.MIN_VALUE) {
Rect oldBounds = thumb.getBounds();
topBound = oldBounds.top;
bottomBound = oldBounds.bottom;
} else {
topBound = gap;
bottomBound = gap + thumbHeight;
}
thumb.setBounds(thumbPos, topBound, thumbPos + thumbWidth, bottomBound);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!isEnabled()) {
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
onStartTrackingTouch();
setPressed(true);
case MotionEvent.ACTION_MOVE:
onProgressChanged();
//設(shè)置進(jìn)度
int i = getMax() - (int) (getMax() * event.getY() / getHeight());
setProgress(i);
//每次拖動(dòng)SeekBar都會(huì)調(diào)用
onSizeChanged(getWidth(), getHeight(), 0, 0);
break;
case MotionEvent.ACTION_UP:
onStopTrackingTouch();
setPressed(false);
break;
case MotionEvent.ACTION_CANCEL:
onStopTrackingTouch();
setPressed(false);
break;
}
return true;
}
public void setThumb(Drawable thumb) {
mThumb = thumb;
super.setThumb(thumb);
}
void attemptClaimDrag() {
if (getParent() != null) {
getParent().requestDisallowInterceptTouchEvent(true);
}
}
}
重寫(xiě)后使用吻氧,可以實(shí)現(xiàn)原來(lái)想要的效果了溺忧,但是又出現(xiàn)了一個(gè)新的bug,因?yàn)樵谧鲆曨l播放器的項(xiàng)目盯孙,所以想把在屏幕上下移動(dòng)調(diào)節(jié)屏幕的亮度鲁森,但是在屏幕上拖動(dòng)的時(shí)候,控件會(huì)變成下面這個(gè)樣子振惰,thumb位置會(huì)錯(cuò)亂歌溉,但是TextView中實(shí)時(shí)顯示的值是正確的,onProgressChanged方法有被執(zhí)行到,弄了好久解決不了痛垛,重寫(xiě)了onProgressRefresh但是發(fā)現(xiàn)并沒(méi)有什么卵用草慧,因?yàn)闀r(shí)間的原因,暫時(shí)先決定重改一下布局匙头,不使用垂直的SeekBar漫谷,因?yàn)槭褂孟到y(tǒng)原生的SeekBar調(diào)節(jié)視頻播放進(jìn)度是沒(méi)有問(wèn)題的,所以直接改用原生SeekBar在屏幕頂部顯示蹂析。這個(gè)問(wèn)題先暫時(shí)記著舔示,等忙完再來(lái)繼續(xù)嘗試解決,如果有哪位大神识窿,知道怎么解決的斩郎,歡迎指導(dǎo),畢竟我還是Android新手喻频。