Android实现百分比下载进度条效果
程序员文章站
2022-04-12 11:45:47
现在很多app中都会集成下载功能,所以有一个方便好看又实用的进度条来展示下载进度很有必要,也能提高用户体验,在这里我就把项目里的下载进度条抽取出来分享给大家,话不多说,先看...
现在很多app中都会集成下载功能,所以有一个方便好看又实用的进度条来展示下载进度很有必要,也能提高用户体验,在这里我就把项目里的下载进度条抽取出来分享给大家,话不多说,先看效果图:
这个进度条是自定义的一个view,其中有一个自定义属性就是百分比文字的大小(也可以把那两条显示颜色的进度条自定义属性,这里就没有实现,在代码里面写的)。
先说说实现原理:
1:由于自定义了属性,所以先获取属性的值。
2:绘制底色那条灰色的线。
3:根据传入的数据计算当前百分比,然后绘制那条橘黄色的线。
4:再在橘黄色线后面把百分比的文字绘制出来就ok了。
现在来看看代码:
一:属性设置attrs.xml文件
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="downloadprogressbar"> <attr name="dptextsize" format="dimension"/> </declare-styleable> </resources>
其中dptextsize就是自定义属性的名字
二:自定义view downloadprogressbar.java
package com.ywl5320.downloadprogressdemo.downloadview; import android.content.context; import android.content.res.typedarray; import android.graphics.canvas; import android.graphics.paint; import android.graphics.rect; import android.util.attributeset; import android.view.view; import android.view.viewtreeobserver.ongloballayoutlistener; import com.ywl5320.downloadprogressdemo.r; /** * 下载进度条 * * @author ywl * */ public class downloadprogressbar extends view { private paint paint = new paint(); // 绘制背景灰色线条画笔 private paint painttext = new paint(); // 绘制下载进度画笔 private float offset = 0f; // 下载偏移量 private float maxvalue = 0f; // 下载的总大小 private float currentvalue = 0f; // 下载了多少 private rect mbound = new rect(); // 获取百分比数字的长宽 private string percentvalue = "0%"; // 要显示的现在百分比 private float offsetright = 0f; // 灰色线条距离右边的距离 private int textsize = 25; // 百分比的文字大小 private float offsettop = 18f; // 距离顶部的偏移量 public downloadprogressbar(context context) { this(context, null); // todo auto-generated constructor stub } public downloadprogressbar(context context, attributeset attribute) { this(context, attribute, 0); } public downloadprogressbar(context context, attributeset attrs, int defstyleattr) { super(context, attrs, defstyleattr); // todo auto-generated constructor stub // 获取自定义属性,给textsize赋初始值 typedarray t = getcontext().obtainstyledattributes(attrs, r.styleable.downloadprogressbar); textsize = (int) t.getdimension( r.styleable.downloadprogressbar_dptextsize, 36); gettextwidth(); } @override protected void ondraw(canvas canvas) { // todo auto-generated method stub super.ondraw(canvas); // 绘制底色 paint.setcolor(getresources().getcolor(r.color.no1_gray_light)); paint.setstrokewidth(1); canvas.drawline(0, offsettop, getwidth(), offsettop, paint); // 绘制进度条颜色 paint.setcolor(getresources().getcolor(r.color.no2_orange)); paint.setstrokewidth(2); canvas.drawline(0, offsettop, offset, offsettop, paint); // 绘制白色区域及百分比 paint.setcolor(getresources().getcolor(r.color.no3_white)); paint.setstrokewidth(1); painttext.setcolor(getresources().getcolor(r.color.no2_orange)); painttext.settextsize(textsize); painttext.setantialias(true); painttext.gettextbounds(percentvalue, 0, percentvalue.length(), mbound); canvas.drawline(offset, offsettop, offset + mbound.width() + 4, offsettop, paint); canvas.drawtext(percentvalue, offset, offsettop + mbound.height() / 2 - 2, painttext); } /** * 设置当前进度值 * * @param currentvalue */ public void setcurrentvalue(float currentvalue) { this.currentvalue = currentvalue; int value = (int) (this.currentvalue / maxvalue * 100); if (value < 100) { percentvalue = value + "%"; } else { percentvalue = "100%"; } initcurrentprogressbar(); invalidate(); } /** * 设置最大值 * * @param maxvalue */ public void setmaxvalue(float maxvalue) { this.maxvalue = maxvalue; } /** * 获取当前进度条长度 * * @param maxvalue * @param currentvalue * @return */ public void initcurrentprogressbar() { getviewtreeobserver().addongloballayoutlistener(new ongloballayoutlistener() { @override public void ongloballayout() { // todo auto-generated method stub if (currentvalue < maxvalue) { offset = (getwidth() - offsetright) * currentvalue / maxvalue; } else { offset = getwidth() - offsetright; } } }); } /** * 获取“100%”的宽度 */ public void gettextwidth() { paint paint = new paint(); rect rect = new rect(); paint.settextsize(textsize); paint.setantialias(true); paint.gettextbounds("100%", 0, "100%".length(), rect); offsetright = rect.width() + 5; } }
这就是实现代码,代码不多,注解也有,不是很难。使用时只需传入文件最大值,当前下载了多少就能自动计算出百分比。如果循环传入,就实现了动态跑动的效果。
三:activity布局文件 activity_main.xml
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:ywl="http://schemas.android.com/apk/res/com.ywl5320.downloadprogressdemo" <!-- 这就是为自定义属性添加命名空间,注意res后的是:程序包名--> android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/no3_white" tools:context="${relativepackage}.${activityclass}" > <textview android:id="@+id/tv_start" android:layout_width="match_parent" android:layout_height="50dip" android:layout_below="@+id/rl_progress" android:layout_margintop="40dip" android:layout_marginleft="20dip" android:layout_marginright="20dip" android:gravity="center" android:background="@drawable/btn_blue_selector" android:text="开始"/> <relativelayout android:id="@+id/rl_progress" android:layout_width="match_parent" android:layout_marginleft="20dip" android:layout_marginright="20dip" android:layout_margintop="30dip" android:layout_height="50dip"> <textview android:id="@+id/tv_size" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margintop="4dip" android:textcolor="@color/no5_gray_silver" android:textsize="12sp" /> <textview android:id="@+id/tv_speed" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignparentright="true" android:layout_margintop="6dip" android:textcolor="@color/no5_gray_silver" android:textsize="12sp" /> <com.ywl5320.downloadprogressdemo.downloadview.downloadprogressbar android:id="@+id/dp_game_progress" android:layout_width="match_parent" android:layout_height="wrap_content" ywl:dptextsize="14sp" <!-- 这里设置控件的字体大小为14sp --> android:layout_below="@+id/tv_size"> </com.ywl5320.downloadprogressdemo.downloadview.downloadprogressbar> </relativelayout> </relativelayout>
程序中的文件大小,当前下载量和下载速度,都是在这里布局的,用的时候可以动态设置就行了,也可以把这个布局文件封装为listview的item布局文件,那样就可以制作下载列表了。
四:mainacativity.java
package com.ywl5320.downloadprogressdemo; import android.app.activity; import android.os.bundle; import android.os.handler; import android.view.view; import android.view.view.onclicklistener; import android.widget.textview; import com.ywl5320.downloadprogressdemo.downloadview.downloadprogressbar; public class mainactivity extends activity { private textview mstart; private textview msize; private textview mspeed; private downloadprogressbar mprogress; private int max = 100; //总的大小 private int current = 0; //当前下载大小 private string speed = "1"; //下载速度 @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); mstart = (textview) findviewbyid(r.id.tv_start); mprogress = (downloadprogressbar) findviewbyid(r.id.dp_game_progress); msize = (textview) findviewbyid(r.id.tv_size); mspeed = (textview) findviewbyid(r.id.tv_speed); //初始化下载进度 msize.settext(current + "mb/" + max + "mb"); //初始化下载速度 mspeed.settext(speed + "mb/s"); mstart.setonclicklistener(new onclicklistener() { @override public void onclick(view v) { // todo auto-generated method stub start(); } }); } //循环模拟下载过程 public void start() { if (current <= max) { msize.settext(current + "mb/" + max + "mb"); mspeed.settext(speed + "mb/s"); mprogress.setmaxvalue(max); mprogress.setcurrentvalue(current); handler.postdelayed(runnable, 100); } else { handler.removecallbacks(runnable); } } handler handler = new handler(); runnable runnable = new runnable() { @override public void run() { // todo auto-generated method stub current = current + 1; start(); } }; }
就这样一个简单实用的下载百分比进度条就实现了,有需要可以直接用就行:android百分比下载进度条
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。