今天周末,好心情 ,前几天面试的三家公司,都拿到了offer , 对于选择困难症的人来说有点纠结 。
今天有空吧公司的项目整理下 ,准备交接 ,发现了一个界面 ,越看越不爽 ,
为啥不爽呢 ?这是一个下载的dialog ,左边显示速度,右边显示进度,没毛病啊 ,对于一个对代码有洁癖的人,一个LinearLayout嵌套一个RelativeLayout,一个ProgressBar,RelativeLayout里面放两个TexTView.
界面控件需要初始化,布局需要刷新,每个控件都要修改数据,白白多了几行代码 。 下午刚好有空,就整理一个双用的View,先看效果图吧
1:只有进度的ProgressBar
2:携带进度,和速度的进度条
平时项目下载用的比较多,系统内置的软件比较多,一般情况下,我们会不厌其烦的写一个自定义View的Progress,然后进度,速度单独用两个TextView.
今天我们就一次性解决这个问题,仅仅就加了一个参数,有时候就是需要整理这个功夫,可以省很多力气
看代码,简单明了 ,传一个参数的时候,另一个就不绘制,反之绘制
1:定义一个自定义的属性,Progresscolor 的颜色是全局的 ,进度的颜色和文字的颜色
xml version="1.0" encoding="utf-8"?>name="MyProgressView"> name="progresscolor" format="color" /> name="progressbg" format="color" />
2:因为这个控件平时几乎不会去修改其他属性,就没有去针对onMsur做适配、控件的尺寸可以标准化 ,基本不会变动尺寸
package com.cdl.progress; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Rect; import android.graphics.RectF; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.util.Log; import android.view.View; public class MyProgressView extends View { int COLOR_BLUE = 0xff538ede; int COLOR_GREY = 0xffd8dbde; int width; int height; int progressheight = 30; int textSize = 25; int proCicrle = progressheight / 2; //圆角半径 int color_bg; int color_progress; int progress = 30; //当前的进度 int speed = 240; //下载速度 private static final int SPEED_NULL = -2; //当前仅仅绘制进度,不绘制速度 private boolean isDrawSpeed = false; //是否绘制速度 public void setProgress(int progress) { setProgress(progress, SPEED_NULL); } public void setProgress(int progress, int speed) { isDrawSpeed = false; if (speed != SPEED_NULL) { isDrawSpeed = true; } this.speed = speed; this.progress = progress; invalidate(); } public MyProgressView(Context context) { this(context, null); } public MyProgressView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public MyProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.MyProgressView); color_progress = ta.getColor(R.styleable.MyProgressView_progresscolor, COLOR_BLUE); color_bg = ta.getColor(R.styleable.MyProgressView_progressbg, COLOR_GREY); ta.recycle(); init(); } //通用画笔 Paint mPaint; Path path; private void init() { path = new Path(); //初始化进度画笔 mPaint = new Paint(); mPaint.setAntiAlias(true); //抗锯齿 mPaint.setStyle(Paint.Style.FILL);//充满 mPaint.setDither(true);// 设置抖动,颜色过渡更均匀 mPaint.setStrokeCap(Paint.Cap.ROUND); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); width = getWidth(); height = getHeight(); drawBg(canvas); //绘制背景 drawProgress(canvas); drawTextProgress(canvas); //绘制底色文字 drawTextSpeed(canvas); } /** * 绘制下载速度 * * @param canvas */ private void drawTextSpeed(Canvas canvas) { if (!isDrawSpeed) { return; } mPaint.setColor(color_progress); mPaint.setTextSize(textSize); String textCanvas = speed + "kb"; Rect bounds = new Rect(); mPaint.getTextBounds(textCanvas, 0, textCanvas.length(), bounds); int textWith = bounds.width(); canvas.drawText(textCanvas, width - (textWith * 3 / 2), (height / 2) + (progressheight * 4 / 3), mPaint); } /*** * 绘制下载进度 * @param canvas */ private void drawTextProgress(Canvas canvas) { mPaint.setColor(color_progress); mPaint.setTextSize(textSize); String textCanvas = progress + "%"; Rect bounds = new Rect(); mPaint.getTextBounds(textCanvas, 0, textCanvas.length(), bounds); int textWith = bounds.width(); int right = width * progress / 100; canvas.drawText(textCanvas, right - textWith / 2, height / 2 - progressheight, mPaint); } private void drawProgress(Canvas canvas) { mPaint.setColor(color_progress); int top = height / 2 - progressheight / 2; int bottom = height / 2 + progressheight / 2; int right = width * progress / 100; Log.i("main", "right ==" + right + " /width =" + width); RectF oval3 = new RectF(0, top, right, bottom);// 设置个新的长方形 canvas.drawRoundRect(oval3, 20, 15, mPaint);//第二个参数是x半径,第三个参数是y半径 } private void drawBg(Canvas canvas) { mPaint.setColor(color_bg); int top = height / 2 - progressheight / 2; int bottom = height / 2 + progressheight / 2; RectF rectBg = new RectF(0, top, width, bottom);// 设置个新的长方形 canvas.drawRoundRect(rectBg, proCicrle, proCicrle, mPaint);//第二个参数是x半径,第三个参数是y半径 } }
布局引用
xml version="1.0" encoding="utf-8"?>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" android:padding="20dp" tools:context="com.cdl.progress.MainActivity"> android:id="@+id/progress" android:layout_width="match_parent" android:layout_height="wrap_content" />
界面,或者其他地方引用,这里为了展示效果 ,代码写的不忍直视,哈哈
package com.cdl.progress; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import java.util.Random; public class MainActivity extends AppCompatActivity { private MyProgressView progress; boolean isRun = true; int i = 0; int speed; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); progress = (MyProgressView) findViewById(R.id.progress); new Thread() { @Override public void run() { super.run(); while (true) { try { Thread.sleep(70); i++; speed = new Random().nextInt(1000); } catch (Exception e) { } runOnUiThread(new Runnable() { @Override public void run() { if (i >= 100) { i = 0; } progress.setProgress(i); progress.setProgress(i, speed); } }); } } }.start(); } }
有么有很简单, 这样就解决两个问题,以后妈妈再也不用担心我写的嵌套布局了,省时省力