需要源码请点赞关注收藏后评论区留下QQ~~~
一、拖动条和滑动条
拖动条SeekBar继承自进度条ProgressBar,它与进度条的不同之处在于,进度条只能在代码中修改进度值,不能由用户改变进度值,拖动条不仅可以在代码中修改进度值,还可以由用户拖动操作改变进度值,在播放音频和视频时,用户通过拖动条控制播放器快进或快退到指定位置,然后从新位置开始播放,除此之外,拖动条还可以调节音量大小,屏幕亮度,字体大小等
尽管拖动条在多数情况下够用了,但它有一个毛病,拖动之后用户不能直观的看到当前进度值是多少,为此Android设计了全新的滑动条空间Slider,首先要增加以下配置
implementaion 'com.google.android.materia:material:1.4.0'
运行效果如下 可以手动点击控制音量
代码如下
Java类
package com.example.audio; import android.os.Bundle; import android.widget.SeekBar; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import com.google.android.material.slider.Slider; public class SliderActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_slider); SeekBar sb_progress = findViewById(R.id.sb_progress); sb_progress.setOnSeekBarChangeListener(mSeekListener); // 设置拖动条的拖动监听器 Slider sl_progress = findViewById(R.id.sl_progress); sl_progress.addOnSliderTouchListener(mSliderListener); // 设置滑动条的触摸监听器 } private SeekBar.OnSeekBarChangeListener mSeekListener = new SeekBar.OnSeekBarChangeListener() { // 在进度变更时触发。第三个参数为true表示用户拖动,为false表示代码设置进度 @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {} // 在开始拖动进度时触发 @Override public void onStartTrackingTouch(SeekBar seekBar) {} // 在停止拖动进度时触发 @Override public void onStopTrackingTouch(SeekBar seekBar) { Toast.makeText(SliderActivity.this, "您选择的进度是"+seekBar.getProgress(), Toast.LENGTH_SHORT).show(); } }; private Slider.OnSliderTouchListener mSliderListener = new Slider.OnSliderTouchListener() { // 在开始滑动进度时触发 @Override public void onStartTrackingTouch(Slider slider) {} // 在停止滑动进度时触发 @Override public void onStopTrackingTouch(Slider slider) { Toast.makeText(SliderActivity.this, "您选择的进度是"+slider.getValue(), Toast.LENGTH_SHORT).show(); } }; }
XML文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:gravity="center" android:text="下面是拖动条" android:textColor="@color/black" android:textSize="17sp" /> <SeekBar android:id="@+id/sb_progress" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:max="100" android:progress="50" android:thumb="@drawable/seekbar_point" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:gravity="center" android:text="下面是来自MaterialDesign库的滑动条" android:textColor="@color/black" android:textSize="17sp" /> <com.google.android.material.slider.Slider android:id="@+id/sl_progress" android:layout_width="match_parent" android:layout_height="wrap_content" android:stepSize="1" android:valueFrom="0" android:valueTo="100" android:value="0" /> </LinearLayout>
二、音频管理器
Android只有一个麦克风,却管理着6种铃声,分别是通话音,系统音,铃音,闹钟音,通知音等
管理这些铃声音量的工具是音频管理器AudioManager 下面是它的常用方法
getStreamMaxVolume 获取指定类型铃声的最大音量
getStreamVolume 获取指定类型铃声的当前音量
getRingerMode 获取指定类型铃声的响铃模式
音量调整效果如下 这个设置页面不但允许通过拖动条将音量直接调整到目标值,还允许通过加减按钮逐级调大或者调小音量
可以拖动条也可以点击按钮来调节
代码如下
Java类
package com.example.audio; import android.content.Context; import android.media.AudioManager; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageView; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; import androidx.appcompat.app.AppCompatActivity; public class AudioManagerActivity extends AppCompatActivity implements OnSeekBarChangeListener, OnClickListener { private static final String TAG = "VolumeManagerActivity"; private SeekBar sb_voice, sb_system, sb_ring, sb_music, sb_alarm, sb_notify; private ImageView iv_volumn_up, iv_system_up, iv_ring_up, iv_music_up, iv_alarm_up, iv_notify_up; private ImageView iv_volumn_down, iv_system_down, iv_ring_down, iv_music_down, iv_alarm_down, iv_notify_down; private int[] mStreamType = { // 音频流类型数组 AudioManager.STREAM_VOICE_CALL, AudioManager.STREAM_SYSTEM, AudioManager.STREAM_RING, AudioManager.STREAM_MUSIC, AudioManager.STREAM_ALARM, AudioManager.STREAM_NOTIFICATION}; private int[] mMaxVolume = {0, 0, 0, 0, 0, 0}; // 最大音量数组 private int[] mNowVolume = {0, 0, 0, 0, 0, 0}; // 当前音量数组 private SeekBar[] mSeekBar = { // 拖动条的控件数组 sb_voice, sb_system, sb_ring, sb_music, sb_alarm, sb_notify}; private int[] mStreamRes = { // 拖动条的资源编号数组 R.id.sb_voice, R.id.sb_system, R.id.sb_ring, R.id.sb_music, R.id.sb_alarm, R.id.sb_notify}; private ImageView[] mAddView = { // 增大音量按钮的控件数组 iv_volumn_up, iv_system_up, iv_ring_up, iv_music_up, iv_alarm_up, iv_notify_up}; private int[] mAddRes = { // 增大音量按钮的资源编号数组 R.id.iv_volumn_up, R.id.iv_system_up, R.id.iv_ring_up, R.id.iv_music_up, R.id.iv_alarm_up, R.id.iv_notify_up}; private ImageView[] mDelView = { // 减小音量按钮的控件数组 iv_volumn_down, iv_system_down, iv_ring_down, iv_music_down, iv_alarm_down, iv_notify_down}; private int[] mDelRes = { // 减小音量按钮的资源编号数组 R.id.iv_volumn_down, R.id.iv_system_down, R.id.iv_ring_down, R.id.iv_music_down, R.id.iv_alarm_down, R.id.iv_notify_down}; private int SEEK_BAR = 1, ADD_VIEW = 2, DEL_VIEW = 3; private AudioManager mAudioMgr; // 声明一个音频管理器对象 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_audio_manager); // 从布局文件中依次获取各音量类型的拖动条、增大音量按钮、减小音量按钮 for (int i = 0; i < mStreamType.length; i++) { mSeekBar[i] = findViewById(mStreamRes[i]); mAddView[i] = findViewById(mAddRes[i]); mDelView[i] = findViewById(mDelRes[i]); } setStreamVolume(); // 设置各音量类型的拖动条进度 for (int i = 0; i < mStreamType.length; i++) { // 给各音量类型的拖动条设置拖动变更监听器 mSeekBar[i].setOnSeekBarChangeListener(this); // 给各音量类型的增大音量按钮设置点击监听器 mAddView[i].setOnClickListener(this); // 给各音量类型的减小音量按钮设置点击监听器 mDelView[i].setOnClickListener(this); } } // 设置各音量类型的拖动条进度 void setStreamVolume() { // 从系统服务中获取音频管理器 mAudioMgr = (AudioManager) getSystemService(Context.AUDIO_SERVICE); for (int i = 0; i < mStreamType.length; i++) { int type = mStreamType[i]; // 获取指定音频类型的最大音量 mMaxVolume[i] = mAudioMgr.getStreamMaxVolume(type); // 获取指定音频类型的当前音量 mNowVolume[i] = mAudioMgr.getStreamVolume(type); // 设置拖动条的音量大小进度 mSeekBar[i].setProgress(mSeekBar[i].getMax() * mNowVolume[i] / mMaxVolume[i]); } } // 在进度变更时触发。第三个参数为true表示用户拖动,为false表示代码设置进度 @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {} // 在开始拖动进度时触发 @Override public void onStartTrackingTouch(SeekBar seekBar) {} // 在停止拖动进度时触发 @Override public void onStopTrackingTouch(SeekBar seekBar) { Log.d(TAG, "当前进度为:" + seekBar.getProgress() + ", 最大进度为" + seekBar.getMax()); int index = getArrayIndex(seekBar.getId(), SEEK_BAR); int type = mStreamType[index]; int volume = mMaxVolume[index] * seekBar.getProgress() / seekBar.getMax(); Log.d(TAG, "volume=" + volume + ", last volume=" + mNowVolume[index] + ", max volume=" + mMaxVolume[index]); if (volume != mNowVolume[index]) { mNowVolume[index] = volume; // 根据拖动位置,计算并设置拖动条的当前进度 seekBar.setProgress(seekBar.getMax() * mNowVolume[index] / mMaxVolume[index]); } // 设置该音频类型的当前音量 mAudioMgr.setStreamVolume(type, volume, AudioManager.FLAG_PLAY_SOUND); } @Override public void onClick(View v) { int add_index = getArrayIndex(v.getId(), ADD_VIEW); int del_index = getArrayIndex(v.getId(), DEL_VIEW); if (add_index != -1) { // 点击了增大音量按钮 SeekBar seekBar = mSeekBar[add_index]; if (mNowVolume[add_index] < mMaxVolume[add_index]) { mNowVolume[add_index] = mNowVolume[add_index] + 1; // 设置拖动条的音量大小进度 seekBar.setProgress(seekBar.getMax() * mNowVolume[add_index] / mMaxVolume[add_index]); // 把该音频类型的当前音量调大一级 mAudioMgr.adjustStreamVolume(mStreamType[add_index], AudioManager.ADJUST_RAISE, AudioManager.FLAG_PLAY_SOUND); } } else if (del_index != -1) { // 点击了减小音量按钮 SeekBar seekBar = mSeekBar[del_index]; if (mNowVolume[del_index] > 0) { mNowVolume[del_index] = mNowVolume[del_index] - 1; // 设置拖动条的音量大小进度 seekBar.setProgress(seekBar.getMax() * mNowVolume[del_index] / mMaxVolume[del_index]); // 把该音频类型的当前音量调小一级 mAudioMgr.adjustStreamVolume(mStreamType[del_index], AudioManager.ADJUST_LOWER, AudioManager.FLAG_PLAY_SOUND); } } } // 根据资源编号与类型寻找它在对应数组中的位置 private int getArrayIndex(int resid, int type) { int index = -1; if (type == SEEK_BAR) { // 这是拖动条 for (int i = 0; i < mSeekBar.length; i++) { if (mSeekBar[i].getId() == resid) { index = i; break; } } } else if (type == ADD_VIEW) { // 这是增大音量按钮 for (int i = 0; i < mAddView.length; i++) { if (mAddView[i].getId() == resid) { index = i; break; } } } else if (type == DEL_VIEW) { // 这是减小音量按钮 for (int i = 0; i < mDelView.length; i++) { if (mDelView[i].getId() == resid) { index = i; break; } } } return index; } }
XML文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ScrollView android:layout_width="match_parent" android:layout_height="wrap_content" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:orientation="horizontal" > <TextView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="bottom|center_horizontal" android:text="调节通话音量" android:textColor="#000000" android:textSize="17sp" /> <ImageView android:id="@+id/iv_volumn_down" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="30dp" android:src="@drawable/volumn_down" /> <ImageView android:id="@+id/iv_volumn_up" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="50dp" android:src="@drawable/volumn_up" /> </LinearLayout> <SeekBar android:id="@+id/sb_voice" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:thumb="@drawable/seekbar_point" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:orientation="horizontal" > <TextView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="bottom|center_horizontal" android:text="调节系统音量" android:textColor="#000000" android:textSize="17sp" /> <ImageView android:id="@+id/iv_system_down" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="30dp" android:src="@drawable/volumn_down" /> <ImageView android:id="@+id/iv_system_up" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="50dp" android:src="@drawable/volumn_up" /> </LinearLayout> <SeekBar android:id="@+id/sb_system" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:thumb="@drawable/seekbar_point" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:orientation="horizontal" > <TextView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="bottom|center_horizontal" android:text="调节铃声音量" android:textColor="#000000" android:textSize="17sp" /> <ImageView android:id="@+id/iv_ring_down" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="30dp" android:src="@drawable/volumn_down" /> <ImageView android:id="@+id/iv_ring_up" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="50dp" android:src="@drawable/volumn_up" /> </LinearLayout> <SeekBar android:id="@+id/sb_ring" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:thumb="@drawable/seekbar_point" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:orientation="horizontal" > <TextView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="bottom|center_horizontal" android:text="调节音乐音量" android:textColor="#000000" android:textSize="17sp" /> <ImageView android:id="@+id/iv_music_down" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="30dp" android:src="@drawable/volumn_down" /> <ImageView android:id="@+id/iv_music_up" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="50dp" android:src="@drawable/volumn_up" /> </LinearLayout> <SeekBar android:id="@+id/sb_music" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:thumb="@drawable/seekbar_point" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:orientation="horizontal" > <TextView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="bottom|center_horizontal" android:text="调节闹钟音量" android:textColor="#000000" android:textSize="17sp" /> <ImageView android:id="@+id/iv_alarm_down" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="30dp" android:src="@drawable/volumn_down" /> <ImageView android:id="@+id/iv_alarm_up" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="50dp" android:src="@drawable/volumn_up" /> </LinearLayout> <SeekBar android:id="@+id/sb_alarm" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:thumb="@drawable/seekbar_point" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:orientation="horizontal" > <TextView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="bottom|center_horizontal" android:text="调节通知音量" android:textColor="#000000" android:textSize="17sp" /> <ImageView android:id="@+id/iv_notify_down" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="30dp" android:src="@drawable/volumn_down" /> <ImageView android:id="@+id/iv_notify_up" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="50dp" android:src="@drawable/volumn_up" /> </LinearLayout> <SeekBar android:id="@+id/sb_notify" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:thumb="@drawable/seekbar_point" /> </LinearLayout> </ScrollView> </LinearLayout>
创作不易 觉得有帮助请点赞关注收藏~~~