Android SeekBar 自定義thumb,thumb旋轉動畫效果
簡介
某些音樂播放或者視訊播放的介面上,資源還在載入時,進度條的原點(thumb)會顯示一個轉圈的效果。
資源載入完成後,又切換回靜態效果。這個效果增強了使用者體驗。
一般來說有美術人員負責設計和切圖。嘗試實現時,我們可以使用使用drawable,來模擬實現這個轉圈的效果。
示例
dimens.xml
為方便管理,可以新增一些尺寸設定
<dimen name="audio_course_item_seek_bar_progress_height">6dp</dimen> <dimen name="audio_course_item_seek_bar_radius">2dp</dimen> <dimen name="audio_seek_bar_thumb_size">20dp</dimen> <dimen name="audio_seek_bar_thumb_ring_width">4dp</dimen>
drawable
我們一共要新增4個drawable檔案。分別是2種thumb,1個動畫,1個進度條“底座”。
shape_thumb_round_1.xml # 靜態thumb
layers_seek_bar_progress_1.xml
layers_thumb_ring_sweep_1.xml
rotate_thumb_1.xml
shape_thumb_round_1.xml
用solid和stroke做出的圓環效果
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <solid android:color="#ffffff" /> <stroke android:width="@dimen/audio_seek_bar_thumb_ring_width" android:color="#7095fc" /> <size android:width="@dimen/audio_seek_bar_thumb_size" android:height="@dimen/audio_seek_bar_thumb_size" /> </shape>
layers_thumb_ring_sweep_1.xml
這是準備拿來轉圈的thumb。使用layer-list,疊加多層效果。
底部是一個半白色的圓(android:shape="oval"
)。
再疊加上一層圓環(android:shape="ring"
),使用了漸變色,增加動感。
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item> <shape android:shape="oval"> <size android:width="@dimen/audio_seek_bar_thumb_size" android:height="@dimen/audio_seek_bar_thumb_size" /> <solid android:color="#ffffff" /> </shape> </item> <item> <shape android:innerRadius="4dp" android:thicknessRatio="6" android:shape="ring" android:useLevel="false"> <gradient android:endColor="#ffffff" android:startColor="#7095fc" android:type="sweep" /> <size android:width="@dimen/audio_seek_bar_thumb_size" android:height="@dimen/audio_seek_bar_thumb_size" /> </shape> </item> </layer-list>
rotate_thumb_1.xml
定義旋轉效果。注意它的drawable
使用了上面定義的layers_thumb_ring_sweep_1.xml。
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/layers_thumb_ring_sweep_1"
android:duration="100"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="-360" />
旋轉引數android:toDegrees
可以根據需求定義。
layers_seek_bar_progress_1.xml
定義進度條的樣式。這個是“底座”。顏色要和上面的匹配,看起來好看一點。
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<size
android:width="5dp"
android:height="@dimen/audio_course_item_seek_bar_progress_height" />
<solid android:color="#e1e5e8" />
</shape>
</item>
<item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<solid android:color="#b7bdc8" />
</shape>
</clip>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<gradient
android:angle="0"
android:centerColor="#b8cafd"
android:endColor="#86a4fd"
android:startColor="#eef2ff" />
</shape>
</clip>
</item>
</layer-list>
layout
上面的資原始檔準備完畢後。在我們的佈局中新增一個SeekBar
android:maxHeight
和android:minHeight
需要設定android:progressDrawable
用前面定義好的“底座”android:thumb
先使用靜態的樣式
<SeekBar
android:id="@+id/play_sb"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="@null"
android:maxHeight="@dimen/audio_course_item_seek_bar_progress_height"
android:minHeight="@dimen/audio_course_item_seek_bar_progress_height"
android:progress="40"
android:progressDrawable="@drawable/layers_seek_bar_progress_1"
android:thumb="@drawable/shape_thumb_round_1"
app:layout_constraintTop_toTopOf="parent" />
Activity中呼叫
由Activity來持有Drawable變數和動畫。例子中使用了dataBinding。
private RotateDrawable mRotateThumbDrawable; // 載入中的thumb,由Activity來持有這個drawable
private Drawable mSolidThumb;
private ObjectAnimator mThumbAnimator; // 控制動畫
// ...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBinding = DataBindingUtil.setContentView(this, R.layout.act_seekbar_1);// ...
mRotateThumbDrawable = (RotateDrawable) AppCompatResources.getDrawable(getApplicationContext(), R.drawable.rotate_thumb_1);
mSolidThumb = AppCompatResources.getDrawable(getApplicationContext(), R.drawable.shape_thumb_round_1);
}
Drawable物件由activity直接持有,操作起來比較方便。
改變seekbar的thumb,使用方法setThumb(Drawable thumb)
使用靜態的thumb
mBinding.playSb.setThumb(mSolidThumb);
使用轉圈圈的效果,先setThumb
,並且需要啟動動畫
mBinding.playSb.setThumb(mRotateThumbDrawable);
mThumbAnimator = ObjectAnimator.ofInt(mRotateThumbDrawable, "level", 0, 10000);
mThumbAnimator.setDuration(1000);
mThumbAnimator.setRepeatCount(ValueAnimator.INFINITE);
mThumbAnimator.setInterpolator(new LinearInterpolator());
mThumbAnimator.start();
效果如下圖
可以在靜態和動態之間相互切換。
離開頁面時記得關閉動畫
@Override
protected void onDestroy() {
if (null != mThumbAnimator) {
mThumbAnimator.cancel();
}
super.onDestroy();
}
小結
要實現轉圈的效果。主要還是直接操作drawable物件,把動畫加進去。
setThumb(Drawable thumb)
方法接受的是Drawable物件,那麼我們的思路就是從控制Drawable這點下手。
全部使用drawable可以達到文中的效果。有條件的也可以使用圖片資源。做出更豐富的效果。
參考:
- 使用
layer-list
的環形drawable https://stackoverflow.com/questions/30676208/how-to-create-ring-shape-drawable-in-android/30677289 - https://stackoverflow.com/questions/15083811/programmatically-rotate-drawable-or-view
- https://stackoverflow.com/questions/5872257/how-do-i-use-rotatedrawable/17123794
更多Android文章可參考 https://an.rustfisher.com/
一個軟體工程師的記錄