編輯:關於Android編程
效果圖
直接在xml文件中添加即可,在代碼中調用setProgress(int) 即可。代碼注釋寫的很清楚,有興趣的隨便改改。
package com.xk.testdemo.view; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Rect; import android.graphics.RectF; import android.util.AttributeSet; import android.util.Log; import android.view.View; import com.xk.testdemo.config.ConfigColor; import static android.R.attr.angle; import static android.R.attr.baseline; import static android.R.attr.dial; import static android.R.attr.end; import static android.R.attr.path; import static android.R.attr.radius; import static android.R.attr.width; import static android.R.attr.x; import static android.R.attr.y; /** * Created by xuekai on 2016/10/26. */ public class InstrumentView extends View { private String color_outcircle = "#DEDEDE"; private String color_bg_outcircle = "#2690F8"; private String color_bg_incircle = "#58ADE4"; private String color_progress = "#87CEEB"; private String color_smart_circle = "#C2B9B0"; private String color_indicator_left = "#E1DCD6"; private String color_indicator_right = "#F4EFE9"; /** * 當前進度 */ private int progress = 50; /** * 要畫的內容的實際寬度 */ private int contentWidth; /** * view的實際寬度 */ private int viewWidth; /** * view的實際高度 */ private int viewHeight; /** * 外環線的寬度 */ private int outCircleWidth = 1; /** * 外環的半徑 */ private int outCircleRadius = 0; /** * 內環的半徑 */ private int inCircleRedius = 0; /** * 內環與外環的距離 */ private int outAndInDistance = 0; /** * 內環的寬度 */ private int inCircleWidth = 0; /** * 刻度盤距離它外面的圓的距離 */ private int dialOutCircleDistance = 0; /** * 內容中心的坐標 */ private int[] centerPoint = new int[2]; /** * 刻度線的數量 */ private int dialCount = 0; /** * 每隔幾次出現一個長線 */ private int dialPer = 0; /** * 長線的長度 */ private int dialLongLength = 0; /** * 短線的長度 */ private int dialShortLength = 0; /** * 刻度線距離圓心最遠的距離 */ private int dialRadius = 0; /** * 圓弧開始的角度 */ private int startAngle = 0; /** * 圓弧劃過的角度 */ private int allAngle = 0; private Paint mPaint; /** * 刻度盤上數字的數量 */ private int figureCount = 6; public InstrumentView(Context context) { this(context, null); } public InstrumentView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public InstrumentView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { mPaint = new Paint(); mPaint.setStyle(Paint.Style.STROKE); mPaint.setAntiAlias(true); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); initValues(); } /** * 初始化尺寸 */ private void initValues() { viewWidth = getMeasuredWidth(); viewHeight = getMeasuredHeight(); contentWidth = viewWidth > viewHeight ? viewHeight : viewWidth; outCircleRadius = contentWidth / 2 - outCircleWidth; outAndInDistance = (int) (contentWidth / 26.5); inCircleWidth = (int) (contentWidth / 18.7); centerPoint[0] = viewWidth / 2; centerPoint[1] = viewHeight / 2; inCircleRedius = outCircleRadius - outAndInDistance - inCircleWidth / 2; startAngle = 150; allAngle = 240; dialOutCircleDistance = inCircleWidth; dialCount = 50; dialPer = 5; dialLongLength = (int) (dialOutCircleDistance / 1.2); dialShortLength = (int) (dialLongLength / 1.8); dialRadius = inCircleRedius - dialOutCircleDistance; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); drawStatic(canvas); drawDynamic(canvas); } /** * 繪制靜態的部分 * * @param canvas */ private void drawStatic(Canvas canvas) { drawOutCircle(canvas); drawCircleWithRound(startAngle, allAngle, inCircleWidth, inCircleRedius, color_outcircle, canvas); drawDial(startAngle, allAngle, dialCount, dialPer, dialLongLength, dialShortLength, dialRadius, canvas); drawBackGround(canvas); drawFigure(canvas, figureCount); } private void drawFigure(Canvas canvas, int count) { int figure = 0; int angle; for (int i = 0; i < count; i++) { figure = (int) (100 / (1f * count-1) * i); angle = (int) ((allAngle) / ((count-1) * 1f) * i) + startAngle; int[] pointFromAngleAndRadius = getPointFromAngleAndRadius(angle, dialRadius - dialLongLength * 2 ); mPaint.setTextSize(15); mPaint.setTextAlign(Paint.Align.CENTER); canvas.save(); canvas.rotate(angle+90,pointFromAngleAndRadius[0],pointFromAngleAndRadius[1]); canvas.drawText(figure+"%",pointFromAngleAndRadius[0],pointFromAngleAndRadius[1],mPaint); canvas.restore(); } } /** * 畫內層背景 * * @param canvas */ private void drawBackGround(Canvas canvas) { mPaint.setColor(Color.parseColor(color_bg_outcircle)); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(outCircleRadius / 3 / 2); canvas.drawCircle(centerPoint[0], centerPoint[1], outCircleRadius / 3, mPaint); mPaint.setColor(Color.parseColor(color_bg_incircle)); mPaint.setStyle(Paint.Style.FILL); canvas.drawCircle(centerPoint[0], centerPoint[1], (outCircleRadius / 3f / 2), mPaint); } /** * 畫刻度盤 * * @param startAngle 開始畫的角度 * @param allAngle 總共劃過的角度 * @param dialCount 總共的線的數量 * @param per 每隔幾個出現一次長線 * @param longLength 長仙女的長度 * @param shortLength 短線的長度 * @param radius 距離圓心最遠的地方的半徑 */ private void drawDial(int startAngle, int allAngle, int dialCount, int per, int longLength, int shortLength, int radius, Canvas canvas) { int length; int angle; for (int i = 0; i <= dialCount; i++) { angle = (int) ((allAngle) / (dialCount * 1f) * i) + startAngle; if (i % 5 == 0) { length = longLength; } else { length = shortLength; } drawSingleDial(angle, length, radius, canvas); } } /** * 畫刻度中的一條線 * * @param angle 所處的角度 * @param length 線的長度 * @param radius 距離圓心最遠的地方的半徑 */ private void drawSingleDial(int angle, int length, int radius, Canvas canvas) { int[] startP = getPointFromAngleAndRadius(angle, radius); int[] endP = getPointFromAngleAndRadius(angle, radius - length); canvas.drawLine(startP[0], startP[1], endP[0], endP[1], mPaint); } /** * 畫最外層的圓 * * @param canvas */ private void drawOutCircle(Canvas canvas) { mPaint.setStrokeWidth(outCircleWidth); mPaint.setStyle(Paint.Style.STROKE); mPaint.setColor(Color.parseColor(color_outcircle)); canvas.drawCircle(centerPoint[0], centerPoint[1], outCircleRadius, mPaint); } /** * 繪制動態的部分 * * @param canvas */ private void drawDynamic(Canvas canvas) { drawProgress(progress, canvas); drawIndicator(progress, canvas); drawCurrentProgressTv(progress, canvas); } /** * 繪制當前進度是文字 * * @param progress * @param canvas */ private void drawCurrentProgressTv(int progress, Canvas canvas) { // canvas.drawText("當前進度:"+progress+"%",); mPaint.setTextSize(25); mPaint.setTextAlign(Paint.Align.CENTER); Paint.FontMetrics fontMetrics = mPaint.getFontMetrics(); float baseLine1 = centerPoint[1] + (outCircleRadius / 20f * 11 - fontMetrics.top - fontMetrics.bottom); canvas.drawText("當前進度", centerPoint[0], baseLine1, mPaint); float baseLine2 = outCircleRadius / 20f * 11 - 3 * (fontMetrics.bottom + fontMetrics.top) + centerPoint[1]; canvas.drawText(progress + "%", centerPoint[0], baseLine2, mPaint); } /** * 畫指針以及他的背景 * * @param progress * @param canvas */ private void drawIndicator(int progress, Canvas canvas) { drawPointer(canvas); drawIndicatorBg(canvas); } /** * 指針的最遠處的半徑和刻度線的一樣 */ private void drawPointer(Canvas canvas) { RectF rectF = new RectF(centerPoint[0] - (int) (outCircleRadius / 3f / 2 / 2), centerPoint[1] - (int) (outCircleRadius / 3f / 2 / 2), centerPoint[0] + (int) (outCircleRadius / 3f / 2 / 2), centerPoint[1] + (int) (outCircleRadius / 3f / 2 / 2)); int angle = (int) ((allAngle) / (100 * 1f) * progress) + startAngle; //指針的定點坐標 int[] peakPoint = getPointFromAngleAndRadius(angle, dialRadius); //頂點朝上,左側的底部點的坐標 int[] bottomLeft = getPointFromAngleAndRadius(angle - 90, (int) (outCircleRadius / 3f / 2 / 2)); //頂點朝上,右側的底部點的坐標 int[] bottomRight = getPointFromAngleAndRadius(angle + 90, (int) (outCircleRadius / 3f / 2 / 2)); Path path = new Path(); mPaint.setColor(Color.parseColor(color_indicator_left)); path.moveTo(centerPoint[0], centerPoint[1]); path.lineTo(peakPoint[0], peakPoint[1]); path.lineTo(bottomLeft[0], bottomLeft[1]); path.close(); canvas.drawPath(path, mPaint); canvas.drawArc(rectF, angle - 180, 100, true, mPaint); Log.e("InstrumentView", "drawPointer" + angle); mPaint.setColor(Color.parseColor(color_indicator_right)); path.reset(); path.moveTo(centerPoint[0], centerPoint[1]); path.lineTo(peakPoint[0], peakPoint[1]); path.lineTo(bottomRight[0], bottomRight[1]); path.close(); canvas.drawPath(path, mPaint); canvas.drawArc(rectF, angle + 80, 100, true, mPaint); } private void drawIndicatorBg(Canvas canvas) { mPaint.setColor(Color.parseColor(color_smart_circle)); mPaint.setStyle(Paint.Style.FILL); canvas.drawCircle(centerPoint[0], centerPoint[1], (outCircleRadius / 3f / 2 / 4), mPaint); } /** * 根據進度畫進度條 * * @param progress 最大進度為100.最小為0 */ private void drawProgress(int progress, Canvas canvas) { float ratio = progress / 100f; int angle = (int) (allAngle * ratio); drawCircleWithRound(startAngle, angle, inCircleWidth, inCircleRedius, color_progress, canvas); } public int getProgress() { return progress; } public void setProgress(int progress) { this.progress = progress; invalidate(); } /** * 畫一個兩端為圓弧的圓形曲線 * * @param startAngle 曲線開始的角度 * @param allAngle 曲線走過的角度 * @param radius 曲線的半徑 * @param width 曲線的厚度 */ private void drawCircleWithRound(int startAngle, int allAngle, int width, int radius, String color, Canvas canvas) { mPaint.setStrokeWidth(width); mPaint.setStyle(Paint.Style.STROKE); mPaint.setColor(Color.parseColor(color)); RectF rectF = new RectF(centerPoint[0] - radius, centerPoint[1] - radius, centerPoint[0] + radius, centerPoint[1] + radius); canvas.drawArc(rectF, startAngle, allAngle, false, mPaint); drawArcRoune(radius, startAngle, width, canvas); drawArcRoune(radius, startAngle + allAngle, width, canvas); } /** * 繪制圓弧兩端的圓 * * @param radius 圓弧的半徑 * @param angle 所處於圓弧的多少度的位置 * @param width 圓弧的寬度 */ private void drawArcRoune(int radius, int angle, int width, Canvas canvas) { int[] point = getPointFromAngleAndRadius(angle, radius); mPaint.setStrokeWidth(0); mPaint.setStyle(Paint.Style.FILL); mPaint.setStyle(Paint.Style.FILL); canvas.drawCircle(point[0], point[1], width / 2, mPaint); } /** * 根據角度和半徑,求一個點的坐標 * * @param angle * @param radius * @return */ private int[] getPointFromAngleAndRadius(int angle, int radius) { double x = radius * Math.cos(angle * Math.PI / 180) + centerPoint[0]; double y = radius * Math.sin(angle * Math.PI / 180) + centerPoint[1]; return new int[]{(int) x, (int) y}; } }
package com.xk.testdemo; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.widget.SeekBar; import com.xk.testdemo.view.IndicatorContainer; import com.xk.testdemo.view.InstrumentView; public class MainActivity extends AppCompatActivity { private IndicatorContainer myView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final InstrumentView viewById = (InstrumentView) findViewById(R.id.instrumentView); SeekBar viewById1 = (SeekBar) findViewById(R.id.sb); viewById1.setMax(100); viewById1.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { viewById.setProgress(progress); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }); } }
Android越來越普及,那已經安裝的應用要如何更新呢?在應用市場中常會有顯示某某應用已經更新之類的信息,那我們是否也可以實現類似的功能呢?如果要實現又要做
下面是HTC官方的一個圖片,展示了Android系統從發布最終到用戶手中的一個完整的過程: Awesome Infographic: HTC Shows Us “Th
本文實例講述了android編程實現局部界面動態切換的方法。分享給大家供大家參考,具體如下:局部界面固定,局部界面可以動態切換。效果如下:這個效果由3個layout構成m
一、概述距離上一篇博客有段時間沒更新了,主要是最近有些私事導致的,那麼就先來一篇簡單一點的博客脈動回來。對於加載圖片,大家都不陌生,一般為了盡可能避免OOM都