自古以來曾雕,第一個(gè)總是搶走了所有的聚光燈。
怎么辦助被,我是第二個(gè)剖张。
據(jù)說有一個(gè)國(guó)際慣例,要真相
那就來吧
看到了嗎揩环。
下邊那個(gè)圓環(huán)就是我們第二個(gè)主角啦搔弄。
上面那個(gè)是 傳說中的第一個(gè)。
沒辦法检盼,第二個(gè)不管再怎么好看也比不上 號(hào)稱第一的那位肯污。
這翘单,應(yīng)該是一個(gè)詛咒吨枉。
/**
* Created by Jimbray .
* on 2016/7/13
* Email: jimbray16@gmail.com
* Description: 這是我第二個(gè)自定義View。
* 第一個(gè)永遠(yuǎn)是被人銘記的哄芜,可是第二個(gè)呢
* 問你一個(gè)問題:世界上最高的山峰是貌亭?
* 答:當(dāng)然是珠穆朗瑪峰啦!
* 那第二高的呢认臊?
* 答:當(dāng)然是喬戈里峰啦圃庭!
* -_- 你不按套路出牌啊,套路里你是不知道的失晴!
*/
public class MySecondProgressbar extends View {
private Context mContext;
// 準(zhǔn)備好畫圓環(huán)的矩形區(qū)域
private RectF mRectF = new RectF(0, 0, 0, 0);
// 準(zhǔn)備好畫文字的矩形區(qū)域
private RectF mTextRrectF = new RectF(0, 0, 0, 0);
// 握好畫筆啊剧腻,有三個(gè)頻段,還有一個(gè)文字
private Paint mHeavyProgressPaint, mModerateProgressPaint, mLightProgressPaint, mTextPaint;
// 默認(rèn)值設(shè)置
private final float default_height = dp2px(45);
private final float default_width = dp2px(45);
private final int default_heavy_color = Color.rgb(255, 54, 102);
private final int default_moderate_color = Color.rgb(255, 128, 97);
private final int default_light_color = Color.rgb(8, 176, 242);
private final int default_text_color = Color.rgb(0, 0, 0);
private final float default_text_size = sp2px(14);
private final float default_heavy_progress_width = dp2px(12);
private final float defaule_moderate_progress_width = dp2px(12);
private final float default_light_progress_width = dp2px(12);
//三個(gè)頻段涂屁,三種顏色啊书在,還有一個(gè)是字體顏色
private int mHeavyColor, mModerateColor, mLightColor, mTextColor;
//畫的東西寬高,還是給個(gè)默認(rèn)值好了
private float mViewHeight, mViewWidth;
//我們畫的是圓環(huán)拆又,要多粗有多粗栏账,定海神針,啊不挡爵,定海神環(huán)
private float mHeavyProgressWidth, mModerateProgressWidth, mLightProgresswidth;
private boolean mIfDrawText; //是不是要畫一下中間的文字呢。還是 寫
private String mCurrentDrawText; //畫的文字你得告訴我吧
private float mTextSize; //字別太大茶鹃,會(huì)撐著
private int mTextBaseLine; //這個(gè) 我是抄的
private float mCircleOffset = dp2px(15); //人與人之間的距離不要太近,還是要有一定的安全距離艰亮。不然親上了怎么辦。
private float mCurrentProgress; //這第二個(gè)自定義View還是一個(gè)progressbar
private float mCurHeavy, mCurModerate, mCurLight; //三個(gè)頻段垃杖,三個(gè)單詞是突然想到的,不知道什么意思
public enum MySecondProgressTextVisibility {// 跟第一個(gè)自定義View最大的不同就是 :名字
Visible, Invisible
}
public MySecondProgressbar(Context context) {
super(context);
init(context, null, 0);
}
public MySecondProgressbar(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public MySecondProgressbar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}
/**
*
* 不想解釋
* @param context
* @param attrs
* @param defStyleAttr
*/
private void init(Context context, AttributeSet attrs, int defStyleAttr) {
this.mContext = context;
mHeavyColor = default_heavy_color;
mModerateColor = default_moderate_color;
mLightColor = default_light_color;
mTextColor = default_text_color;
mViewWidth = default_width;
mViewHeight = default_height;
mTextSize = default_text_size;
mHeavyProgressWidth = default_heavy_progress_width;
mModerateProgressWidth = defaule_moderate_progress_width;
mLightProgresswidth = default_light_progress_width;
mIfDrawText = true;
initPainters();
}
/**
* 上顏料
*/
private void initPainters() {
mHeavyProgressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mHeavyProgressPaint.setColor(mHeavyColor);
mHeavyProgressPaint.setStyle(Paint.Style.STROKE);
mHeavyProgressPaint.setStrokeWidth(mHeavyProgressWidth);
mModerateProgressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mModerateProgressPaint.setColor(mModerateColor);
mModerateProgressPaint.setStyle(Paint.Style.STROKE);
mModerateProgressPaint.setStrokeWidth(mModerateProgressWidth);
mLightProgressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mLightProgressPaint.setColor(mLightColor);
mLightProgressPaint.setStyle(Paint.Style.STROKE);
mLightProgressPaint.setStrokeWidth(mLightProgresswidth);
mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setColor(mTextColor);
mTextPaint.setTextAlign(Paint.Align.CENTER);
mTextPaint.setTextSize(mTextSize);
}
/**
* 最小寬度 由你定
* 不定我來給個(gè)最小值吧
* @return
*/
@Override
protected int getSuggestedMinimumWidth() {
return (int) mViewWidth;
}
/**
* 跟寬度一個(gè)意思
* @return
*/
@Override
protected int getSuggestedMinimumHeight() {
return (int) mViewHeight;
}
/**
* @param canvas
* 咱先分析一下
* 要畫什么
* 我要畫一個(gè)圓環(huán)
* 圓環(huán)里面有三個(gè)頻段的顯示(不同顏色)
* 這三個(gè)頻段呢伶棒,分別代表三個(gè)數(shù)值的占比關(guān)系
* 中間放個(gè)文字吧肤无,不然太空
* 好像就這樣
*/
@Override
protected void onDraw(Canvas canvas) {
if(mIfDrawText) {
calWithText();
} else {
calWithoutText();
}
//上面已經(jīng)把我們要畫的區(qū)域圈出來了
//可以施展拳腳,不對(duì)骇钦,是畫筆了
float heavy_sweep_angle = mCurHeavy / mCurrentProgress; //算一下占比
heavy_sweep_angle = heavy_sweep_angle * 360; //占比最終還是要轉(zhuǎn)換成角度的宛渐,0.5的話就是180度
if(mCurHeavy != 0) {
//從上面12點(diǎn)鐘的位置開始,就是270啦眯搭,我不喜歡負(fù)數(shù)窥翩,掃過多大的角度呢
canvas.drawArc(mRectF, 270, heavy_sweep_angle, false, mHeavyProgressPaint); //試試把false改為true玩一玩,順便把paint 的stroke屬性去掉鳞仙。有驚喜哦寇蚊!
}
//跟上面的意思差不多啦。
float moderate_sweep_angle = mCurModerate / mCurrentProgress;
moderate_sweep_angle = moderate_sweep_angle * 360;
if(mCurModerate != 0) {
canvas.drawArc(mRectF, 270 + heavy_sweep_angle, moderate_sweep_angle, false, mModerateProgressPaint);
}
//還是一樣的棍好。
float light_sweep_angle = mCurLight / mCurrentProgress;
light_sweep_angle = light_sweep_angle * 360;
if(mCurLight != 0) {
canvas.drawArc(mRectF, 270 + heavy_sweep_angle + moderate_sweep_angle, light_sweep_angle, false, mLightProgressPaint);
}
//上面已經(jīng)把圓環(huán)都畫完了
//畫個(gè)原點(diǎn)仗岸,我是來確定我寫的字是不是在中間,不能我說在中間就是在中間是吧借笙。如果它不是在中間扒怖,我把它說成在中間,然后被你發(fā)現(xiàn)它不在中間业稼,那我不是很尷尬盗痒。
// canvas.drawOval(getWidth() /2 - 1 , getHeight() / 2 - 1, getWidth() / 2 + 1, getHeight() / 2 + 1, mHeavyProgressPaint); //畫個(gè)圓點(diǎn),看看文字是不是居中的
if(mIfDrawText) { //準(zhǔn)備書法
// canvas.drawRect(mTextRrectF, mLightProgressPaint); //畫個(gè)矩形 把text 框起來 ,參照物
//第一種
//這個(gè)是不對(duì)的做法盼忌,我以為是寫在了中間
// canvas.drawText(mCurrentDrawText, getWidth() / 2.0f, getHeight() / 2.0f + (mTextPaint.descent() + mTextPaint.ascent()), mTextPaint);
//第二種
// 后來我知道我錯(cuò)了积糯,所以我就將錯(cuò)就錯(cuò)掂墓,再錯(cuò)一次
// float text_width = mTextPaint.measureText(mCurrentDrawText);
// canvas.drawText(mCurrentDrawText, mTextRrectF.left + text_width/2.0f, mTextRrectF.bottom, mTextPaint);
//第三種
//又來了!快看我找到的解決方案:[等燈等燈](http://blog.csdn.net/hursing/article/details/18703599)
canvas.drawText(mCurrentDrawText, mTextRrectF.centerX(), mTextBaseLine, mTextPaint);
}
}
/**
* 精華1
* 這里不寫字
*/
private void calWithoutText() {
mRectF.left = getPaddingLeft() + mCircleOffset;
mRectF.top = getPaddingTop() + mCircleOffset;
mRectF.right = getWidth() - getPaddingRight() - mCircleOffset;
mRectF.bottom = getHeight() - getPaddingBottom() - mCircleOffset;
//就完啦?
//你說的對(duì)呀
//我就確定個(gè)區(qū)域看成,咋滴啦
}
/**
* 精華2
*/
private void calWithText() {
mRectF.left = getPaddingLeft() + mCircleOffset;
mRectF.top = getPaddingTop() + mCircleOffset;
mRectF.right = getWidth() - getPaddingRight() - mCircleOffset;
mRectF.bottom = getHeight() - getPaddingBottom() - mCircleOffset;
if(!TextUtils.isEmpty(mCurrentDrawText)) {
float text_width = mTextPaint.measureText(mCurrentDrawText);
mTextRrectF.left = getWidth() / 2.0f - text_width / 2.0f;
mTextRrectF.top = getHeight() / 2.0f - mTextSize / 2.0f;
mTextRrectF.right = getWidth() / 2.0f + text_width / 2.0f;
mTextRrectF.bottom = getHeight() / 2.0f + mTextSize / 2.0f;
//這里是計(jì)算 文字居中的解決方案 具體請(qǐng)?jiān)L問我搜到的 [這是我找到的](http://blog.csdn.net/hursing/article/details/18703599)
Paint.FontMetricsInt fontMetrics = mTextPaint.getFontMetricsInt();
mTextBaseLine = (int) ((mTextRrectF.bottom + mTextRrectF.top - fontMetrics.bottom - fontMetrics.top) / 2);
} else {
mIfDrawText = false;
}
//這里還是確定個(gè)區(qū)域的問題
//只不過多了文字的區(qū)域
}
/**
* 這個(gè)套路還是可以再深一點(diǎn)
* 不過我是新司機(jī)
* 不會(huì)換檔
* @param widthMeasureSpec
* @param heightMeasureSpec
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(measure(widthMeasureSpec, true), measure(heightMeasureSpec, false));
}
/**
* 測(cè)量 view 的 寬高信息
* @param measureSpec
* @param isWidth
* @return
*/
private int measure(int measureSpec, boolean isWidth) {
int result;
int mode = MeasureSpec.getMode(measureSpec);
int size = MeasureSpec.getSize(measureSpec);
int padding = isWidth ? getPaddingLeft() + getPaddingRight() : getPaddingTop() + getPaddingBottom();
if (mode == MeasureSpec.EXACTLY) {
result = size;
} else {
result = isWidth ? getSuggestedMinimumWidth() : getSuggestedMinimumHeight();
result += padding;
if (mode == MeasureSpec.AT_MOST) {
if (isWidth) {
result = Math.max(result, size);
} else {
result = Math.min(result, size);
}
}
}
return result;
}
public float dp2px(float dp) {
final float scale = getResources().getDisplayMetrics().density;
return dp * scale + 0.5f;
}
public float sp2px(float sp) {
final float scale = getResources().getDisplayMetrics().scaledDensity;
return sp * scale;
}
private void setProgressTextVisibility(MySecondProgressTextVisibility visibility) {
mIfDrawText = visibility == MySecondProgressTextVisibility.Visible;
}
public void setProgress(float heavy, float moderate, float light) {
this.mCurrentProgress = heavy + moderate + light;
this.mCurHeavy = heavy;
this.mCurModerate = moderate;
this.mCurLight = light;
invalidate();
}
/**
* 加個(gè)動(dòng)畫
* 就會(huì)變成屌屌的
* 我知道我為什么選progressbar來做第一個(gè)自定義View了
* 因?yàn)? * 其他的我也不會(huì)啊
* @param heavy
* @param moderate
* @param light
*/
public void animProgress(float heavy, float moderate, float light) {
this.mCurrentProgress = heavy + moderate + light;
ValueAnimator heavy_animator = ValueAnimator.ofFloat(0, heavy);
heavy_animator.setInterpolator(new LinearInterpolator());
heavy_animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mCurHeavy = (float) animation.getAnimatedValue();
postInvalidate();
}
});
ValueAnimator moderate_animator = ValueAnimator.ofFloat(0, moderate);
moderate_animator.setInterpolator(new LinearInterpolator());
moderate_animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mCurModerate = (float) animation.getAnimatedValue();
postInvalidate();
}
});
ValueAnimator light_animator = ValueAnimator.ofFloat(0, light);
light_animator.setInterpolator(new LinearInterpolator());
light_animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mCurLight = (float) animation.getAnimatedValue();
postInvalidate();
}
});
AnimatorSet animSet = new AnimatorSet();
animSet.setDuration(1000);
animSet.playTogether(light_animator, moderate_animator, heavy_animator);
animSet.start();
}
public void setProgressText(String text) {
this.mCurrentDrawText = text;
invalidate();
}
}
第二個(gè)也寫完了君编。
這個(gè)我沒有抄別人的啊。
我抄的是第一個(gè)自定義View 的川慌。
敲完了吃嘿。