欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android实现百分比下载进度条效果

程序员文章站 2022-04-12 11:45:47
现在很多app中都会集成下载功能,所以有一个方便好看又实用的进度条来展示下载进度很有必要,也能提高用户体验,在这里我就把项目里的下载进度条抽取出来分享给大家,话不多说,先看...

现在很多app中都会集成下载功能,所以有一个方便好看又实用的进度条来展示下载进度很有必要,也能提高用户体验,在这里我就把项目里的下载进度条抽取出来分享给大家,话不多说,先看效果图:

Android实现百分比下载进度条效果

这个进度条是自定义的一个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百分比下载进度条

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。