實現通過滑動的手勢,進行音量的控制,每滑動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>
<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>
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();
}
}
以下是實現後的效果圖