用手机看视频,调节音量时会出现一个小图标,如图:
向上滑动时,白点数目会增多(声音会变大),向下滑动时白点数目会减少(声音会变小),我尝试着自己做了一个(有图示效果,当没加声音效果)下面是我的实例分析:
主要是自定义view的四部曲 加上触摸监听:
1,自定义属性
2,从构造方法中获取自定义属性
3,重写onMeasure()方法
4,重写onDraw()方法
5,重写onDraw()方法
第 一步,自定义属性:
在res/values的目录下新建文件attrs.xml。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="firstColor" format="color"></attr>
<attr name="secondeColor" format="color"/>
<attr name="circleWidth" format="dimension"/>
<declare-styleable name="CustomVolumControlBar">
<attr name="firstColor"/>
<attr name="secondeColor"/>
<attr name="circleWidth"/>
<attr name="imageId" format="reference"></attr>
<attr name="spliteSize" format="integer"></attr>
<attr name="count" format="integer"></attr>
</declare-styleable>
</resources> 第二步,从构造方法中获取自定义属性:
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
public class CustomVolumControlBar extends View{
/*圆环的宽度*/
private int circleWidth;
/*椭圆点的个数*/
private int count;
/*椭圆点有效时的颜色*/
private int firstColor;
/*椭圆点无效时的颜色*/
private int secondColor;
/*中间的图片*/
private Bitmap mImage;
/*最后一个有效椭圆点的序号*/
private int currentIndex=3;
/*没移动前的序号*/
private int beforeMovedIndex=3;
/*两个椭圆点之间的间隔*/
private int spliteSize;
private Paint mPaint;
/*绘图时的矩形,限定方位和大小*/
private Rect rect;
public CustomVolumControlBar(Context context) {
this(context, null);
}
public CustomVolumControlBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
// TODO Auto-generated constructor stub
}
public CustomVolumControlBar(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
/*获得type数组*/
TypedArray tArray=context.getTheme()
.obtainStyledAttributes(attrs,
R.styleable.CustomVolumControlBar,
defStyle, 0);
/*获得属性的数量*/
int length=tArray.getIndexCount();
for(int i=0;i<length;i++){
/*获得属性下标*/
int attr=tArray.getIndex(i);
switch (attr) {
case R.styleable.CustomVolumControlBar_circleWidth:
circleWidth=tArray.getDimensionPixelSize(attr,
(int)TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 20, getResources().getDisplayMetrics()));
break;
case R.styleable.CustomVolumControlBar_count:
count=tArray.getInt(attr, 10);
break;
case R.styleable.CustomVolumControlBar_firstColor:
firstColor=tArray.getColor(attr, 0);
break;
case R.styleable.CustomVolumControlBar_secondeColor:
secondColor=tArray.getColor(attr, 0);
break;
case R.styleable.CustomVolumControlBar_spliteSize:
spliteSize=tArray.getInt(attr, 10);
break;
case R.styleable.CustomVolumControlBar_imageId:
mImage=BitmapFactory.decodeResource(getResources(), tArray.getResourceId(attr, 0));
}
}
Log.i("","firstColor:"+firstColor+";secondColor:"+secondColor);
tArray.recycle();
mPaint=new Paint();
rect=new Rect();
}
第三步重写onMeasure方法,自定义其高宽,在这里不需要做特殊的设置,所以不需要重写。
第四步重写onDraw()方法,
/**
* 画圆弧,和中间图片
* canvas的中文意思为帆布,个人认为他就像一块画布,我们都是在它身上作画
* (画布作为一个新的整体,最后再整个加载到父容器中)
*/
@Override
protected void onDraw(Canvas canvas) {
//设置画笔的宽度,即圆环的宽度
mPaint.setStrokeWidth(circleWidth);
//设置锯齿圆滑
mPaint.setStrokeCap(Paint.Cap.ROUND);
/*设置画笔的类型*/
mPaint.setStyle(Paint.Style.STROKE);
//圆心
int centre=getWidth()/2;
//半径
int radius=centre-circleWidth/2;
/*画椭圆块*/
drawOval(canvas,centre,radius);
/*画圆环中间的图片*/
//内切圆的半径
int incircleRadius=radius-circleWidth/2;
if(Math.sqrt(2)*incircleRadius<mImage.getWidth()){
rect.left=(int)( incircleRadius-Math.sqrt(2)*incircleRadius/2+circleWidth);
rect.right=(int) (rect.left+Math.sqrt(2)*incircleRadius);
rect.top=(int)( incircleRadius-Math.sqrt(2)*incircleRadius/2+circleWidth);
rect.bottom=(int) (rect.top+Math.sqrt(2)*incircleRadius);
}else{
rect.left=centre-mImage.getWidth()/2;
rect.top=centre-mImage.getHeight()/2;
rect.right=rect.left+mImage.getWidth();
rect.bottom=rect.top+mImage.getHeight();
}
canvas.drawBitmap(mImage, null, rect, mPaint);
}
/*画椭圆块*/
private void drawOval(Canvas canvas,int centre,int radius){
//根据所要花椭圆快的个数,来计算椭圆快的型号(弧度),
float itemSize;
if(count>1){
itemSize=(270*1.0f-spliteSize*(count-1))/count;
}else{
return;
}
RectF oval=new RectF(centre-radius, centre-radius, centre+radius, centre+radius);
mPaint.setColor(firstColor);
for(int i=0;i<currentIndex;i++){
canvas.drawArc(oval, 135+i*(itemSize+spliteSize), itemSize, false, mPaint);
//Log.i("", "firstdraw");
}
mPaint.setColor(secondColor);
for(int i=currentIndex;i<count;i++){
canvas.drawArc(oval, 135+i*(itemSize+spliteSize), itemSize, false, mPaint);
//Log.i("", "seconddraw");
}
Log.i("currentIndex",""+currentIndex);
}
private int yDown,yUp;
/**
* 滑动监听事件
*/ 第五步,重写onTouchEvent实现触摸监听
/**
* 滑动监听事件
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
int action=event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
yDown=(int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
int addIndex=((int)event.getY()-yDown)/20;
changeIndex(addIndex);
break;
case MotionEvent.ACTION_UP:
/*yUp=(int) event.getY();
if(yUp-yDown>5){
down();
}else if(yUp-yDown<-5){
up();
}*/
beforeMovedIndex=currentIndex;
break;
}
return true;
}
/**
* 移动后相应的操作
* @param changedCount
*/
private void changeIndex(int changedCount){
int afterMovedIndex=beforeMovedIndex+changedCount;
if(afterMovedIndex<0){
afterMovedIndex=0;
}else if(afterMovedIndex>count){
afterMovedIndex=count;
}
if(currentIndex!=afterMovedIndex){
currentIndex=afterMovedIndex;
postInvalidate();
}
};
下面是效果图:
本文介绍了一种自定义音量调节条的实现方法,包括自定义属性、构造方法、重写onMeasure及onDraw方法等内容,并通过触摸监听实现音量调节功能。
539

被折叠的 条评论
为什么被折叠?



