自定义滑动音量
程序员文章站
2022-05-11 22:00:22
...
最近由于项目需求,自己写了个音量滑动View。其实滑动可以应用的范围还有很多,故此做以笔记,以便以后翻阅。
- 首先建立一个自定义View slip继承View
- 在构造方法里完成了对图片的获取以及一些初始化。
- 重写onDraw()方法具体可看源码。
- 重写onMeasure()这个方法比较重要!在源码里解释。
- 重写onTouchEvent();//在这个方法里完成滑动功能
- 写监听滑动接口代码如下
-
//监听slip滑动事件。 public interface OnslipListener { public void Onslip( ); }
8.在活动里写滑动事件
slip=(slip)findViewById(R.id.slip_volume);
slip.setOnslipListener(new OnslipListener() {
@Override
public void Onslip() {
AudioManager mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
//最大音量
int maxVolume = mAudioManager.getStreamMaxVolume( STREAM_SYSTEM);
//当前音量
int currentVolume = mAudioManager.getStreamVolume( STREAM_SYSTEM);
mAudioManager.setStreamVolume(STREAM_MUSIC,(int)(maxVolume*(slip.getProgress())),FLAG_SHOW_UI );
}
});
其中用到一些方法都在slip里可以查看
public class slip extends View{
OnslipListener onslipListener;//滑动监听接口
Bitmap v1;//音量喇叭
Bitmap v2;//浮球
Bitmap v3;//滑动条
float maxWidth;//滑动最大坐标
float sum;//V3坐标
float lastCur;//上次坐标
public int range;//滑动条长度
public float getProgress(){
return (sum-(v1.getWidth()+5))/range;
}
public void setOnslipListener(OnslipListener onslipListener){
this.onslipListener=onslipListener;
}
public slip(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
v1= BitmapFactory.decodeResource(getResources(), R.drawable.music_volume);
v2=BitmapFactory.decodeResource(getResources(), R.drawable.music_range);
v3=BitmapFactory.decodeResource(getResources(),R.drawable.volume_float);
range=v2.getWidth();
maxWidth=v1.getWidth()+5+v2.getWidth()-v3.getWidth();
sum=v1.getWidth()+5;
}
@Override
public void onDraw(Canvas canvas){
super.onDraw(canvas);
Paint paint=new Paint();//画笔
paint.setColor(Color.BLUE);//设置画笔颜色
canvas.drawBitmap(v1,0,0,paint);//画图片中间两个参数是坐标以屏幕左上角为原点
canvas.drawBitmap(v2,v1.getWidth()+5,0,paint);
Log.d("sum",sum+"");
canvas.drawBitmap(v3,sum,0,paint);
Log.d("wer","2313123");
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//MeasureSpec.getMode可以获取宽或高的布局模式
//MeasureSpec.getSize可以获取宽或高的布局中指定的尺寸。
int wSpecMode = MeasureSpec.getMode(widthMeasureSpec);
int wSpecSize = MeasureSpec.getSize(widthMeasureSpec);
int hSpecMode = MeasureSpec.getMode(heightMeasureSpec);
int hSpecSize = MeasureSpec.getSize(heightMeasureSpec);
//MeasureSpec.EXACTLY 表示布局的模式是具体尺寸,相当于在布局中指定了具体的dp值或者match_parent
//MeasureSpec.AT_MOST 表示布局模式是wrap_content,这时候需要你自己来指定控件的宽和高,否则就
//填充父母了。
if(wSpecMode == MeasureSpec.AT_MOST) {
wSpecSize = v1.getWidth()+5+v2.getWidth();
//设置view宽和高
setMeasuredDimension(wSpecSize,hSpecSize);
}
if(hSpecMode == MeasureSpec.AT_MOST) {
hSpecSize = v1.getHeight();
//设置view宽和高
setMeasuredDimension(wSpecSize,hSpecSize);
}
}
@Override
public boolean onTouchEvent(MotionEvent event){
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
lastCur=event.getX();
break;
case MotionEvent.ACTION_MOVE:
Log.d("23123123213","123123123123213");
float curX=event.getX();//获取此时坐标
float curChange=curX-lastCur;//计算移动大小
sum+=curChange;//累加
lastCur=curX;//存储
if(sum>maxWidth){//超出判断,如果超出则等于端点值
sum=maxWidth;
}else if(sum<v1.getWidth()+5){
sum=v3.getWidth();
}
onslipListener.Onslip();
break;
case MotionEvent.ACTION_UP:
break;
}
invalidate();//刷新界面
return true;
}
}