編輯:關於Android編程
Android中的控件中有一類是ProgressBar,其子類中有一個是AbsSeekBar。相信有不少童鞋對這個拖動條的父類比較感興趣吧!尤其是看到網易雲音樂的進度條上面是可以處理播放與暫停事件,是不是很羨慕的哈~ 俺在這裡告訴大家,不用羨慕,看了我下面的代碼分析,你也是可以做出那樣的效果的哦。Let's go.
下面先給大家列表一下AbsSeekBar的成員變量有哪些。
//當前的矩形
private final Rect mTempRect = new Rect();
//可以拖動的滑塊
private Drawable mThumb;
//顏色的狀態的列表
private ColorStateList mThumbTintList = null;
//對應的端口的融合
private PorterDuff.Mode mThumbTintMode = null;
//是否支持的歡快的tint
private boolean mHasThumbTint = false;
//對應的是滑塊的模式
private boolean mHasThumbTintMode = false;
//滑塊的偏移量
private int mThumbOffset;
//是否進行分割追蹤
private boolean mSplitTrack;在變量中我們大致需要知道一下幾點:
1、mTempRect是與SeekBar整個軌跡繪制相關的變量
2、mThumb是SeekBar上面的滑塊的Drawable的圖片
3、mThumbOffset是滑塊是距離x左邊距的距離
對於AbsSeekBar的成員方法,下面選取一個比較重要的,在實際的開發工作中經常用到的幾個方法給大家講解一下。
1、setThumbOffset
這個方法是設置滑塊距離左邊距的位置
2、
public synchronized void setMax(int max) {
super.setMax(max);
if ((mKeyProgressIncrement == 0) || (getMax() / mKeyProgressIncrement > 20)) {
// It will take the user too long to change this via keys, change it
// to something more reasonable
//設置為比較合理的數值
setKeyProgressIncrement(Math.max(1, Math.round((float) getMax() / 20)));
}
}1、設置當前的SeekBar的最大值
2、由於存在部分手機有向左的按鍵與向右的按鍵,就比如我曾經遇到過的一款三星的商務機。按照源碼的邏輯,控制左按鍵與右按鍵一次位移的邊距不要超過20.
關於軌跡的繪制與滑塊的繪制的更新,主要關注下面的一段代碼
if (track != null) {
track.setBounds(0, trackOffset, w - mPaddingRight - mPaddingLeft,
h - mPaddingBottom - trackOffset - mPaddingTop);
}
if (thumb != null) {
setThumbPos(w, thumb, getScale(), thumbOffset);
}void drawTrack(Canvas canvas) {
//獲取當前滑塊的引用
final Drawable thumbDrawable = mThumb;
if (thumbDrawable != null && mSplitTrack) {
final Insets insets = thumbDrawable.getOpticalInsets();
final Rect tempRect = mTempRect;
thumbDrawable.copyBounds(tempRect);
tempRect.offset(mPaddingLeft - mThumbOffset, mPaddingTop);
tempRect.left += insets.left;
tempRect.right -= insets.right;
final int saveCount = canvas.save();
//對當前的矩形進行裁剪
canvas.clipRect(tempRect, Op.DIFFERENCE);
super.drawTrack(canvas);
canvas.restoreToCount(saveCount);
} else {
super.drawTrack(canvas);
}
}針對上面的代碼塊,主要講下面的幾點:
1、mSlitTrack這個變量存在的原因是,我們通常遇到滑塊的左右的顏色不一樣,這個變量就是起到分割左右兩邊的目的。
滑塊的繪制也是比較重要的哦,下面也一起來看看吧:
void drawThumb(Canvas canvas) {
if (mThumb != null) {
canvas.save();
// Translate the padding. For the x, we need to allow the thumb to
// draw in its extra space
//主要是x軸上面的變化
canvas.translate(mPaddingLeft - mThumbOffset, mPaddingTop);
//繪制一些Canvas的對象
mThumb.draw(canvas);
canvas.restore();
}
}canvas.translate(mPaddingLeft - mThumbOffset, mPaddingTop);下面的內容主要是講解AbsSeekBar是如何處理touch事件,而我上面的所說的網易雲音樂如果做到點擊進度條實現播放與暫停的效果也與下面的講解有關:
與上面一樣,咱們先上代碼:
public boolean onTouchEvent(MotionEvent event) {
if (!mIsUserSeekable || !isEnabled()) {
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (isInScrollingContainer()) {
mTouchDownX = event.getX();
} else {
//設置當前的狀態是處於按下的狀態
setPressed(true);
if (mThumb != null) {
invalidate(mThumb.getBounds()); // This may be within the padding region
}
onStartTrackingTouch();
trackTouchEvent(event);
attemptClaimDrag();
}
break;
case MotionEvent.ACTION_MOVE:
if (mIsDragging) {
trackTouchEvent(event);
} else {
final float x = event.getX();
//超過一定的狀態
if (Math.abs(x - mTouchDownX) > mScaledTouchSlop) {
setPressed(true);
if (mThumb != null) {
invalidate(mThumb.getBounds()); // This may be within the padding region
}
onStartTrackingTouch();
trackTouchEvent(event);
attemptClaimDrag();
}
}
break;
case MotionEvent.ACTION_UP:
if (mIsDragging) {
trackTouchEvent(event);
onStopTrackingTouch();
setPressed(false);
} else {
// Touch up when we never crossed the touch slop threshold should
// be interpreted as a tap-seek to that location.
onStartTrackingTouch();
trackTouchEvent(event);
onStopTrackingTouch();
}
// ProgressBar doesn't know to repaint the thumb drawable
// in its inactive state when the touch stops (because the
// value has not apparently changed)
invalidate();
break;
case MotionEvent.ACTION_CANCEL:
if (mIsDragging) {
onStopTrackingTouch();
setPressed(false);
}
invalidate(); // see above explanation
break;
}
return true;
}1、如果當前的SeekBar已經設置了不能夠touch操作,廢話不用多說,直接return。
2、按照源碼的解釋,當當前的控件處於按下的狀態,主要進行下面的處理:
2、1 設置當前的狀態為Press的狀態
2、2 刷新當前的視圖
如果我們需要仿造網易雲音樂,需要處理暫停音樂的邏輯,
需要注意兩點
1、判斷當前的event的x的坐標是否是在滑塊的內部,如果是,不論當前的位移是多少,均不要改變當前的進度
2、修改當前的滑塊的圖片
好了,整個的源碼的講解就到這裡了,相信大家看到這裡,對Android中的SeekBar有了比以前更進一步的了解了吧!不用謝哦,叫我發哥就行。再見,
Android編程基礎之簡單Button事件響應綜合提示控件Toast應用示例
本文實例講述了Android簡單Button事件響應綜合提示控件Toast應用。分享給大家供大家參考,具體如下:前面講述了在main.xml裡定義了Button對象,這裡
Android 二維碼 生成和識別二維碼 附源碼下載
今天講一下目前移動領域很常用的技術——二維碼。現在大街小巷、各大網站都有二維碼的蹤跡,不管是IOS、Android、WP都有相關支持的軟件。之前我就想了解二維碼是如何工作
android 開發零起步學習筆記(九):android 控制控件的位置和大小及Layout相關屬性
方法一:Android的界面布局可以用兩種方法,一種是在xml中布局,一種是和JAVA中Swing一樣在JAVA代碼中實現Ui界面的布局,用xml的布局管理器布局是很方便
Android 項目中嵌入 ReactNative 模塊
ReactNative的發展已經進入了很多開發者視野,作為一名原生開發者更是對 RN 充滿了無限的好奇和期待,本節將詳細講述如何將一個原生的 Android App 項目