自定义view(视频音量调控)

本文介绍了一种自定义音量调节条的实现方法,包括自定义属性、构造方法、重写onMeasure及onDraw方法等内容,并通过触摸监听实现音量调节功能。

        用手机看视频,调节音量时会出现一个小图标,如图:

       

向上滑动时,白点数目会增多(声音会变大),向下滑动时白点数目会减少(声音会变小),我尝试着自己做了一个(有图示效果,当没加声音效果)下面是我的实例分析:

         主要是自定义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();
	   }
   };	

下面是效果图:

             

资源下载!








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值