編輯:關於android開發

1.在values建立attrs.xml,寫出你需要的屬性:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="firstColor" format="color" />
<attr name="secondColor" format="color" />
<attr name="circleWidth" format="dimension" />
<attr name="dotCount" format="integer" />
<attr name="splitSize" format="integer" />
<attr name="bg" format="reference" />
<declare-styleable name="CustomVolumControlBar">
<attr name="firstColor" />
<attr name="secondColor" />
<attr name="circleWidth" />
<attr name="dotCount" />
<attr name="splitSize" />
<attr name="bg" />
</declare-styleable>
</resources>
2.創建view類並實現所需要的業務,具體看代碼,代碼中寫的很詳細:
package com.zzw.Custom.widget;
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.media.AudioManager;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import com.zzw.Custom.R;
/**
* Created by zzw on 2016/6/1.
* 描述:
*/
public class CustomVolumControlBar extends View {
/**
* 第一圈的顏色
*/
private int mFirstColor;
/**
* 第二圈的顏色
*/
private int mSecondColor;
/**
* 圈的寬度
*/
private int mCircleWidth;
/**
* 畫筆
*/
private Paint mPaint;
/**
* 當前進度
*/
private int mCurrentCount = 3;
/**
* 中間的圖片
*/
private Bitmap mImage;
/**
* 每個塊塊間的間隙
*/
private int mSplitSize;
/**
* 個數
*/
private int mCount;
/**
* 中間圖片界限
*/
private Rect mRect;
private AudioManager mAudioManager;
private Handler mHandler = new Handler();
public CustomVolumControlBar(Context context) {
this(context, null);
}
public CustomVolumControlBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomVolumControlBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}
private void init(Context context, AttributeSet attrs, int defStyleAttr) {
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomVolumControlBar, defStyleAttr, 0);
int n = a.getIndexCount();
for (int i = 0; i < n; i++) {
int attr = a.getIndex(i);
switch (attr) {
case R.styleable.CustomVolumControlBar_firstColor:
this.mFirstColor = a.getColor(attr, Color.BLACK);
break;
case R.styleable.CustomVolumControlBar_secondColor:
this.mSecondColor = a.getColor(attr, Color.WHITE);
break;
case R.styleable.CustomVolumControlBar_circleWidth:
this.mCircleWidth = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_PX, 20, getResources().getDisplayMetrics()));
break;
case R.styleable.CustomVolumControlBar_dotCount:
this.mCount = a.getInt(attr, 20);// 默認20
break;
case R.styleable.CustomVolumControlBar_splitSize:
this.mSplitSize = a.getInt(attr, 20);
break;
case R.styleable.CustomVolumControlBar_bg:
this.mImage = BitmapFactory.decodeResource(getResources(), a.getResourceId(attr, 0));
break;
}
}
a.recycle();
mPaint = new Paint();
mRect = new Rect();
if (mAudioManager == null)
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
/**
* 獲取到最大音量和當前音量
*/
mCount = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
mCurrentCount = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
Log.e("=====", "mCount:" + mCount + " mCurrentCount:" + mCurrentCount);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setAntiAlias(true);//消除鋸齒
mPaint.setStrokeWidth(mCircleWidth);//設置圓圈寬度
mPaint.setStrokeCap(Paint.Cap.ROUND);//定義線段電形狀圓頭
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);//設置空心
int centre = getWidth() / 2;//得到圓心
int radius = centre - mCircleWidth / 2;//得到半徑
drawOval(canvas, centre, radius);
/**
* 計算內切正方形的位置
*/
int relRadius = radius - mCircleWidth / 2;// 獲得內圓的半徑
/**
* 內切正方形的距離頂部 = mCircleWidth + relRadius - √2 / 2
*/
mRect.left = (int) (relRadius - Math.sqrt(2) * 1.0f / 2 * relRadius) + mCircleWidth;
/**
* 內切正方形的距離左邊 = mCircleWidth + relRadius - √2 / 2
*/
mRect.top = (int) (relRadius - Math.sqrt(2) * 1.0f / 2 * relRadius) + mCircleWidth;
mRect.bottom = (int) (mRect.left + Math.sqrt(2) * relRadius);
mRect.right = (int) (mRect.left + Math.sqrt(2) * relRadius);
/**
* 如果圖片比較小,那麼根據圖片的尺寸放置到正中心
*/
if (mImage.getWidth() < Math.sqrt(2) * relRadius) {
mRect.left = (int) (mRect.left + Math.sqrt(2) * relRadius * 1.0f / 2 - mImage.getWidth() * 1.0f / 2);
mRect.top = (int) (mRect.top + Math.sqrt(2) * relRadius * 1.0f / 2 - mImage.getHeight() * 1.0f / 2);
mRect.right = (int) (mRect.left + mImage.getWidth());
mRect.bottom = (int) (mRect.top + mImage.getHeight());
}
// 繪圖
canvas.drawBitmap(mImage, null, mRect, mPaint);
}
/**
* 畫塊塊去
*/
private void drawOval(Canvas canvas, int centre, int radius) {
/**
* 根據需要畫的個數以及間隙計算每個塊塊所占的比例*360
*/
float itemSize = (360 * 1.0f - mCount * mSplitSize) / mCount;
/**
* 用於定義的圓弧的形狀和大小的界限
*/
RectF oval = new RectF(centre - radius, centre - radius, centre + radius, centre + radius);
mPaint.setColor(mFirstColor);// 設置圓環的顏色
for (int i = 0; i < mCount; i++) {
canvas.drawArc(oval, i * (itemSize + mSplitSize), itemSize, false, mPaint);// 根據進度畫圓弧
}
mPaint.setColor(mSecondColor); // 設置圓環的顏色
for (int i = 0; i < mCurrentCount; i++) {
canvas.drawArc(oval, i * (itemSize + mSplitSize), itemSize, false, mPaint); // 根據進度畫圓弧
}
}
/**
* 當前數量+1
*/
public synchronized void up() {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mCurrentCount++;
if (mCurrentCount > mCount)
mCurrentCount = mCount;
postInvalidate();
setVolume(mCurrentCount);
}
}, 100);
}
/**
* 設置音量
*
* @param index
*/
private void setVolume(int index) {
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, index, 1);
}
/**
* 當前數量-1
*/
public synchronized void down() {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mCurrentCount--;
if (mCurrentCount < 0)
mCurrentCount = 0;
postInvalidate();
setVolume(mCurrentCount);
}
}, 100);
}
private int lastY, nowY;
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
lastY = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
nowY = (int) event.getY();
int updateYCount = (nowY - lastY) / 30;
if (updateYCount > 0) {
for (int i = 0; i < updateYCount; i++) {
down();
}
} else if (updateYCount < 0) {
for (int i = updateYCount; i < 0; i++) {
up();
}
}
lastY = nowY;
break;
}
return true;
}
}
3.在xml中引用:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.zzw.Custom.MainActivity">
<com.zzw.Custom.widget.CustomVolumControlBar
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_centerInParent="true"
app:bg="@mipmap/ic_horn"
app:circleWidth="5dp"
app:firstColor="@color/colorPrimary"
app:secondColor="@color/colorAccent"
app:splitSize="10" />
</RelativeLayout>
當然,在實際操作中OnTouch事件一般是放在activity或者Fragment裡面的,只需在代碼中復制出去即可
最後十分感謝鴻洋大神,讓我們學到了很多,該篇與鴻洋大神相關的的博客地址:http://blog.csdn.net/lmj623565791/article/details/24529807
CustomVolumControlBar
MySQL新特性之mysql_config_editor源碼解析
MySQL新特性之mysql_config_editor源碼解析從mysql5.6開始,mysql推出了加密工具mysql_config_editor。在此之前我們通過將
【騰訊Bugly干貨分享】微信Tinker的一切都在這裡,包括源碼(一),buglytinker
【騰訊Bugly干貨分享】微信Tinker的一切都在這裡,包括源碼(一),buglytinker微信Tinker的一切都在這裡,包括源碼(一) 最近半年以來,Androi
對沉浸式狀態欄的理解,沉浸式狀態欄理解
對沉浸式狀態欄的理解,沉浸式狀態欄理解Android 4.4版本加入了沉浸式者這項功能,相信大家手中的安卓機也早已是Android 4.4甚至更高版本。越來越
Intent屬性詳解二 Action、Category,intentcategory
Intent屬性詳解二 Action、Category,intentcategory先看效果圖: 1、Action:該activity可以執行的動作 該標識用來說明這