SeekBar介紹
SeekBar是ProgressBar的子類咱扣,通過(guò)對(duì)ProgressBar進(jìn)行功能性的補(bǔ)充,可以響應(yīng)用戶的點(diǎn)擊和拖動(dòng)事件。接下來(lái)將要介紹屬性設(shè)置、樣式設(shè)置以及功能設(shè)置母谎。并且通過(guò)SeekBar來(lái)控制系統(tǒng)音量。
SeekBar常用屬性介紹
首先在xml當(dāng)中對(duì)SeekBar進(jìn)行屬性的設(shè)置
<SeekBar
android:id="@+id/seek_bar"
style="@android:style/Widget.Material.SeekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="200"
android:padding="20dp"
android:progress="0"
android:visibility="visible"
android:progressDrawable="@drawable/seek_bar_voice_bg"
android:thumb="@drawable/seek_bar_voice_circle"/>
其中京革,android:max是對(duì)進(jìn)度條的最大值進(jìn)行設(shè)定奇唤,在這里進(jìn)行設(shè)置之后幸斥,還可以通過(guò)使用seekBar.setMax()函數(shù)進(jìn)行設(shè)置,SeekBar的默認(rèn)范圍是[0,100]咬扇。
android:progress顯示的是進(jìn)度條的初始值甲葬,其值不能大于設(shè)置的最大值,在這里進(jìn)行設(shè)置之后懈贺,還可以通過(guò)使用seekBar.setProgress()函數(shù)進(jìn)行設(shè)置
android:progressDrawable="@drawable/seek_bar_voice_bg"经窖,對(duì)進(jìn)度條的樣式進(jìn)行設(shè)置
android:thumb="@drawable/seek_bar_voice_circle",對(duì)進(jìn)度條的按鈕樣式進(jìn)行設(shè)置
SeekBar樣式屬性設(shè)置
首先對(duì)進(jìn)度條樣式進(jìn)行設(shè)置梭灿,在drawable路徑下画侣,設(shè)置seek_bar_voice_bg
<?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>
<solid android:color="#65686A" />
</shape>
</item>
<item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<solid android:color="#ff51495e" />
</shape>
</clip>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<solid android:color="#2287FE" />
</shape>
</clip>
</item>
</layer-list>
其中,backgroud是進(jìn)度條的背景顏色堡妒,progress是已經(jīng)滑過(guò)的進(jìn)度條的顏色配乱,secondaryProgress是還未滑過(guò)的進(jìn)度條的顏色。
接下來(lái)對(duì)進(jìn)度條的樣式進(jìn)行設(shè)置:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<solid
android:color="#FF9A33"
/>
<size
android:width="20dp"
android:height="20dp"/>
</shape>
SeekBar功能的設(shè)置
初始化設(shè)置
am = (AudioManager)getSystemService(AUDIO_SERVICE);
//獲取系統(tǒng)最大音量
int maxVolume = am.getStreamMaxVolume(AudioManager.STREAM_SYSTEM );
seekBar.setMax(maxVolume);
//獲取當(dāng)前音量
int currentVolume = am.getStreamVolume(AudioManager.STREAM_SYSTEM);
Log.i("init", String.valueOf(currentVolume));
seekBar.setProgress(currentVolume);
textView.setText(""+currentVolume+"/"+maxVolume);
這里有一個(gè)問(wèn)題涕蚤,在一開始編這段代碼的時(shí)候宪卿,參考網(wǎng)上的代碼時(shí)發(fā)現(xiàn),并不能改變系統(tǒng)聲音進(jìn)度條的變化万栅,后來(lái)發(fā)現(xiàn)是AudioManager有很多的音量設(shè)置來(lái)源,包括:
/** Used to identify the volume of audio streams for phone calls */
**public** **static** **final** **int** [STREAM_VOICE_CALL](http://androidxref.com/8.0.0_r4/s?refs=STREAM_VOICE_CALL&project=frameworks) = [AudioSystem](http://androidxref.com/8.0.0_r4/s?defs=AudioSystem&project=frameworks).[STREAM_VOICE_CALL](http://androidxref.com/8.0.0_r4/s?refs=STREAM_VOICE_CALL&project=frameworks);
/** Used to identify the volume of audio streams for system sounds */
**public** **static** **final** **int** [STREAM_SYSTEM](http://androidxref.com/8.0.0_r4/s?refs=STREAM_SYSTEM&project=frameworks) = [AudioSystem](http://androidxref.com/8.0.0_r4/s?defs=AudioSystem&project=frameworks).[STREAM_SYSTEM](http://androidxref.com/8.0.0_r4/s?refs=STREAM_SYSTEM&project=frameworks);
/** Used to identify the volume of audio streams for the phone ring */
**public** **static** **final** **int** [STREAM_RING](http://androidxref.com/8.0.0_r4/s?refs=STREAM_RING&project=frameworks) = [AudioSystem](http://androidxref.com/8.0.0_r4/s?defs=AudioSystem&project=frameworks).[STREAM_RING](http://androidxref.com/8.0.0_r4/s?refs=STREAM_RING&project=frameworks);
/** Used to identify the volume of audio streams for music playback */
**public** **static** **final** **int** [STREAM_MUSIC](http://androidxref.com/8.0.0_r4/s?refs=STREAM_MUSIC&project=frameworks) = [AudioSystem](http://androidxref.com/8.0.0_r4/s?defs=AudioSystem&project=frameworks).[STREAM_MUSIC](http://androidxref.com/8.0.0_r4/s?refs=STREAM_MUSIC&project=frameworks);
/** Used to identify the volume of audio streams for alarms */
**public** **static** **final** **int** [STREAM_ALARM](http://androidxref.com/8.0.0_r4/s?refs=STREAM_ALARM&project=frameworks) = [AudioSystem](http://androidxref.com/8.0.0_r4/s?defs=AudioSystem&project=frameworks).[STREAM_ALARM](http://androidxref.com/8.0.0_r4/s?refs=STREAM_ALARM&project=frameworks);
/** Used to identify the volume of audio streams for notifications */
**public** **static** **final** **int** [STREAM_NOTIFICATION](http://androidxref.com/8.0.0_r4/s?refs=STREAM_NOTIFICATION&project=frameworks) = [AudioSystem](http://androidxref.com/8.0.0_r4/s?defs=AudioSystem&project=frameworks).[STREAM_NOTIFICATION](http://androidxref.com/8.0.0_r4/s?refs=STREAM_NOTIFICATION&project=frameworks);
/** **@hide** Used to identify the volume of audio streams for phone calls when connected
* to bluetooth */
**public** **static** **final** **int** [STREAM_BLUETOOTH_SCO](http://androidxref.com/8.0.0_r4/s?refs=STREAM_BLUETOOTH_SCO&project=frameworks) = [AudioSystem](http://androidxref.com/8.0.0_r4/s?defs=AudioSystem&project=frameworks).[STREAM_BLUETOOTH_SCO](http://androidxref.com/8.0.0_r4/s?refs=STREAM_BLUETOOTH_SCO&project=frameworks);
/** **@hide** Used to identify the volume of audio streams for enforced system sounds
* in certain countries (e.g camera in Japan) */
**public** **static** **final** **int** [STREAM_SYSTEM_ENFORCED](http://androidxref.com/8.0.0_r4/s?refs=STREAM_SYSTEM_ENFORCED&project=frameworks) = [AudioSystem](http://androidxref.com/8.0.0_r4/s?defs=AudioSystem&project=frameworks).[STREAM_SYSTEM_ENFORCED](http://androidxref.com/8.0.0_r4/s?refs=STREAM_SYSTEM_ENFORCED&project=frameworks);
/** Used to identify the volume of audio streams for DTMF Tones */
**public** **static** **final** **int** [STREAM_DTMF](http://androidxref.com/8.0.0_r4/s?refs=STREAM_DTMF&project=frameworks) = [AudioSystem](http://androidxref.com/8.0.0_r4/s?defs=AudioSystem&project=frameworks).[STREAM_DTMF](http://androidxref.com/8.0.0_r4/s?refs=STREAM_DTMF&project=frameworks);
/** **@hide** Used to identify the volume of audio streams exclusively transmitted through the
* speaker (TTS) of the device */
**public** **static** **final** **int** [STREAM_TTS](http://androidxref.com/8.0.0_r4/s?refs=STREAM_TTS&project=frameworks) = [AudioSystem](http://androidxref.com/8.0.0_r4/s?defs=AudioSystem&project=frameworks).[STREAM_TTS](http://androidxref.com/8.0.0_r4/s?refs=STREAM_TTS&project=frameworks);
/** Used to identify the volume of audio streams for accessibility prompts */
**public** **static** **final** **int** [STREAM_ACCESSIBILITY]
所以在代碼中使用的AudioManager當(dāng)中的STREAM_SYSTEM來(lái)進(jìn)行的設(shè)置音量最大值以及當(dāng)前值西疤。
響應(yīng)音量調(diào)節(jié)
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(fromUser){
seekBarProgress = progress;
am.setStreamVolume(AudioManager.STREAM_SYSTEM , progress, 0);
int currentVolume = am.getStreamVolume(AudioManager.STREAM_SYSTEM );
seekBar.setProgress(currentVolume);
}
textView.setText(""+progress);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
textView.setText("開始了");
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
textView.setText("停止了烦粒,當(dāng)前值為:"+seekBarProgress);
if(seekBarProgress == seekBar.getMax()){
textView.setText("達(dá)到最值");
}
}
});
可以看到,SeekBar需要注冊(cè)監(jiān)聽器來(lái)進(jìn)行進(jìn)度條值改變后的響應(yīng)代赁,包括進(jìn)度條被拖動(dòng)后的響應(yīng)public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)扰她,其中fromUser的含義是判斷,進(jìn)度條的拖動(dòng)是否由用戶操作芭碍,在這個(gè)函數(shù)當(dāng)中設(shè)置了系統(tǒng)的聲音徒役;后面的兩個(gè)函數(shù),用來(lái)監(jiān)聽是否開始移動(dòng)以及停止拖動(dòng)進(jìn)度條窖壕。
監(jiān)聽聲音設(shè)置更改
通過(guò)注冊(cè)廣播接收器忧勿,監(jiān)聽手機(jī)按鍵更改的聲音,來(lái)同步設(shè)置進(jìn)度條的更改瞻讽。
private class VolumeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("android.media.VOLUME_CHANGED_ACTION")){
int currentVolume = am.getStreamVolume(AudioManager.STREAM_SYSTEM);
seekBar.setProgress(currentVolume);
}
}
}
這個(gè)廣播監(jiān)聽器是通過(guò)內(nèi)部類來(lái)動(dòng)態(tài)注冊(cè)的鸳吸,注冊(cè)方法是:
receiver = new VolumeReceiver();
IntentFilter filter = new IntentFilter() ;
filter.addAction("android.media.VOLUME_CHANGED_ACTION") ;
this.registerReceiver(receiver, filter) ;
通過(guò)設(shè)置對(duì)VOLUME_CHANGED_ACTION的更改進(jìn)行監(jiān)聽,可以動(dòng)態(tài)更改進(jìn)度條速勇。
動(dòng)態(tài)的廣播監(jiān)聽器需要在程序退出的時(shí)候取消注冊(cè)晌砾,以防內(nèi)存泄漏。
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}