自定義垂直的seebar(原版發(fā)現(xiàn)問(wèn)題,更新最新版)

今天想使用垂直的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);
    }
}

}

圖片.png

重寫(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新手喻频。


圖片.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末缩宜,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子甥温,更是在濱河造成了極大的恐慌锻煌,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件姻蚓,死亡現(xiàn)場(chǎng)離奇詭異宋梧,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)狰挡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén)捂龄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人加叁,你說(shuō)我怎么就攤上這事倦沧。” “怎么了它匕?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵展融,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我豫柬,道長(zhǎng)告希,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任烧给,我火速辦了婚禮燕偶,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘础嫡。我一直安慰自己杭跪,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布驰吓。 她就那樣靜靜地躺著涧尿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪檬贰。 梳的紋絲不亂的頭發(fā)上姑廉,一...
    開(kāi)封第一講書(shū)人閱讀 49,784評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音翁涤,去河邊找鬼桥言。 笑死,一個(gè)胖子當(dāng)著我的面吹牛葵礼,可吹牛的內(nèi)容都是我干的号阿。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼鸳粉,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼扔涧!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起届谈,我...
    開(kāi)封第一講書(shū)人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤枯夜,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后艰山,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體湖雹,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年曙搬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了摔吏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡纵装,死狀恐怖征讲,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情搂擦,我是刑警寧澤稳诚,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站瀑踢,受9級(jí)特大地震影響扳还,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜橱夭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一氨距、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧棘劣,春花似錦俏让、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)寡喝。三九已至,卻和暖如春勒奇,著一層夾襖步出監(jiān)牢的瞬間预鬓,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工赊颠, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留格二,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓竣蹦,卻偏偏與公主長(zhǎng)得像顶猜,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子痘括,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容