自定義 音量view

      實現通過滑動的手勢,進行音量的控制,每滑動10的距離,增加一格的音量


1.attrs文件

<?xml version="1.0" encoding="utf-8"?>
<resources>
    
    <attr name="imageSrc" format="reference"></attr>
    <attr name="firstColor" format="color"></attr>
    <attr name="secondColor" format="color"></attr>
    <attr name="ovalWide" format="dimension"></attr>
    <attr name="dotCount" format="integer"></attr>
    <attr name="dotWide" format="dimension"></attr>
    
    <!-- 自定義view四 -->
    <declare-styleable name="VoiceView">
        <attr name="firstColor"></attr>
        <attr name="secondColor"></attr>
        <attr name="ovalWide"></attr>
        <attr name="dotCount"></attr>
        <attr name="dotWide"></attr>  
        <attr name="imageSrc"></attr>
    </declare-styleable>
</resources>


2.調用view的佈局文件

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:tw="http://schemas.android.com/apk/res/com.example.textmyview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin" >

    
    <com.example.textmyview.myview.VoiceView 
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginTop="100dp"
        android:layout_gravity="center_horizontal"
        tw:firstColor="@color/actionsheet_gray"
        tw:secondColor="@color/a_black"
        tw:ovalWide="5dp"
        tw:dotCount="13"
        tw:dotWide="8dp"
        tw:imageSrc="@drawable/ic_volum"/>

</LinearLayout>


3.view類對象


package com.example.textmyview.myview;

import com.example.textmyview.R;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
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 VoiceView extends View{
	private static final int TOTAL_ANGLE=270;//弧形的總角度
	private static final int BEGIN_ANGLE=-225;//弧形的起始角度

	private int mFirstColor;//第一圈的顏色
	private int mSecondColor;//第二圈的顏色
	private int mVoiceWide;//圈的寬度
	private int mDotCount;//點的總數量
	private int mDotWide;//點與點之間的距離
	private Bitmap mBitmap;//中間顯示的圖片
	private int mCurrentDot=0;//當前顯示的點的數量
	private float mTouchX;//點擊時的x座標
	private int center;//view的中心位置
	private int radius;//畫筆的半徑
	
	private Canvas canvas;//畫布對象
	private Paint mPaint;//畫筆對象
	
	public VoiceView(Context context) {
		this(context, null);
		// TODO Auto-generated constructor stub
	}
	
	public VoiceView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
		// TODO Auto-generated constructor stub
	}
	
	public VoiceView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		// TODO Auto-generated constructor stub
		//獲取填寫的屬性值
		TypedArray a=context.getTheme().obtainStyledAttributes(attrs, R.styleable.VoiceView, defStyleAttr, 0);
		int count =a.getIndexCount();
		for (int i = 0; i < count; i++) {
			switch (a.getIndex(i)) {
			case R.styleable.VoiceView_firstColor:
				mFirstColor=a.getColor(a.getIndex(i), Color.BLUE);
				break;
			case R.styleable.VoiceView_secondColor:
				mSecondColor=a.getColor(a.getIndex(i), Color.CYAN);	
				break;
			case R.styleable.VoiceView_dotCount:
				mDotCount=a.getInteger(a.getIndex(i), 13);
				break;
			case R.styleable.VoiceView_dotWide:
				mDotWide=a.getDimensionPixelSize(a.getIndex(i), 
						(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, getResources().getDisplayMetrics()));
				break;
			case R.styleable.VoiceView_ovalWide:
				mVoiceWide=a.getDimensionPixelSize(a.getIndex(i), 
						(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, getResources().getDisplayMetrics()));
				break;
			case R.styleable.VoiceView_imageSrc:
				mBitmap=BitmapFactory.decodeResource(getResources(), a.getResourceId(a.getIndex(i), 0));
				break;

			default:
				break;
			}
		}
		a.recycle();
		mPaint=new Paint();
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
		this.canvas=canvas;
		mPaint.setAntiAlias(false);//去除鋸齒
		mPaint.setStrokeCap(Paint.Cap.ROUND);//畫出來的線的末端以橢圓形結尾
		mPaint.setStyle(Paint.Style.STROKE);//空心
		mPaint.setStrokeWidth(mVoiceWide);//畫筆畫出的線的寬度
		center =getWidth()/2;//目前的view的中心位置
		radius=center-mVoiceWide/2;//畫筆的半徑
		//畫點
		drawDot();
		//圖片的顯示載體
		Rect imageRect=new Rect();
		//計算圓形內矩形的長度
		int imageRealWide=(int) ((radius-mVoiceWide/2)*(1/Math.sqrt(2)));
		imageRect.left=center-imageRealWide;
		imageRect.top=center-imageRealWide;
		imageRect.right=center+imageRealWide;
		imageRect.bottom=center+imageRealWide;
		canvas.drawBitmap(mBitmap, null, imageRect, mPaint);
	}
	
	//畫點
	private void drawDot(){
		//以270度作爲全部的角度  去掉中間的 空餘部分,求出每個點的長度
		float itemwide=(TOTAL_ANGLE-(mDotCount-1)*mDotWide)/mDotCount;
		//弧形所在的區域限制範圍
		RectF rectf=new RectF(center-radius, center-radius, center+radius, center+radius);
		mPaint.setColor(mFirstColor);
		for (int i = 0; i < mDotCount; i++) {
			//以-225度爲起始度數,計算每個點的位置畫點,由於近似值所以每個點的位置加上  0.27
			canvas.drawArc(rectf, i*(itemwide+mDotWide)+BEGIN_ANGLE+(float)(mDotCount*0.27), itemwide, false, mPaint);
		}
		
		mPaint.setColor(mSecondColor);
		for (int i = 0; i < mCurrentDot; i++) {
			canvas.drawArc(rectf, i*(itemwide+mDotWide)+BEGIN_ANGLE+(float)(mDotCount*0.27), itemwide, false, mPaint);
		}
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			mTouchX=event.getX();
			break;
		case MotionEvent.ACTION_MOVE:
			//通過滑動判斷用戶的滑動距離是否是超過 10 超過後判斷是前進還是後退進行畫圖處理
			if(event.getX()-mTouchX>10){
				mTouchX=event.getX();
				dealDot(1);
			}else if(mTouchX-event.getX()>10){
				mTouchX=event.getX();
				dealDot(-1);
			}
			break;

		default:
			break;
		}
		return true;
	}
	
	private void dealDot(int dot){
		mCurrentDot=mCurrentDot+dot;
		//判斷是否已經滿點數量了
		if(mCurrentDot>mDotCount){
			mCurrentDot=mDotCount;
		}
		postInvalidate();
	}
	
}

以下是實現後的效果圖





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章