博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
html动态进度条代码_用textview+线程实现自定义进度条
阅读量:4964 次
发布时间:2019-06-12

本文共 5331 字,大约阅读时间需要 17 分钟。

文章目录

    • 1.activity_main.xml
    • 2.MianActivity

前几天一个朋友问我一下图片这个进度条怎么好实现

85fccecaddff3522c33697abbd608457.png

他说他的思路是progressBar+OnDraw方法绘制文字
当时看到这个图,我第一个想法就是可以通过TextView,然后通过线程去动态改变控件的宽度
他说没怎么明白,然后我自己就写了个demo,就顺便更到博客上

总的来说呐,实现思路其实还是蛮简单,首先定义好自己想要的样式的进度条然后获取屏幕的宽度,减去你设置的外边距,也就是获取你进度条的总长度,然后算出每一个进度你需要的前进的宽度是多少,(因为这里是整数,所以在进度条满了的时候还需要补齐误差值),所有dp的单位根据屏幕密度换算成px单位,然后再通过线程通信动态更新进度条的进度,就O了。

1.activity_main.xml

直接贴代码了

这边之所以用个线性布局,是为了方便后期动态设置这个texview的layoutParams属性

2.MianActivity

public class MainActivity extends AppCompatActivity {    /**     * 进度条     */    TextView tv_ma_progress;    /**     * 屏幕宽高     */    public static int screenWidth;    /**     * 总进度值     */    public int totalProgress = 100;    /**     * 起始进度值     */    public int beginProgress = 0;    /**     * 平均宽度     */    public int averageWidth = 1;    /**     * 因为求平均值的时候可能会除不尽  所以这里要求误差值     */    public int errorValue = 0;    /**     * 外边距magin   (dp)     */    public int marginSize = 30;    /**     * 屏幕密度     */    DisplayMetrics dm;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        dm = new DisplayMetrics();        dm = getResources().getDisplayMetrics();        screenWidth = getWindowManager().getDefaultDisplay().getWidth();        tv_ma_progress = findViewById(R.id.tv_ma_progress);        averageWidth = (screenWidth-convertPx(marginSize)*2)/totalProgress;        errorValue = screenWidth-convertPx(marginSize)*2 - averageWidth*totalProgress;        new Thread(new Runnable() {            @Override            public void run() {                while (beginProgress
=totalProgress){ //因为之前求平均值时会有偏差,所以进度最后要加上误差值 realShowWidth = realShowWidth+errorValue; } progressDto.setCurrentWidth(realShowWidth); message.obj = progressDto; message.what = 1; progressHandler.sendMessage(message); } } }).start(); } Handler progressHandler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what){ case 1: ProgressDto progressDto = (ProgressDto) msg.obj; LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(progressDto.getCurrentWidth(), convertPx(35)); layoutParams.setMargins(convertPx(marginSize), convertPx(marginSize), convertPx(marginSize), convertPx(marginSize)); if(progressDto.getCurrentProgress()<=5){ tv_ma_progress.setTextSize(TypedValue.COMPLEX_UNIT_SP, 4); }else if(progressDto.getCurrentProgress()<=10){ tv_ma_progress.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10); }else{ tv_ma_progress.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14); } tv_ma_progress.setLayoutParams(layoutParams); tv_ma_progress.setText("+"+progressDto.getCurrentProgress()); break; } } }; class ProgressDto{ private int currentProgress; private int currentWidth; public int getCurrentProgress() { return currentProgress; } public void setCurrentProgress(int currentProgress) { this.currentProgress = currentProgress; } public int getCurrentWidth() { return currentWidth; } public void setCurrentWidth(int currentWidth) { this.currentWidth = currentWidth; } } /** * 根据dp转换成px * px = dp*ppi/160 * dp = px / (ppi / 160) * px = sp*ppi/160 * * @return */ public int convertPx(int dp) { return dp * dm.densityDpi / 160; } }

先贴上所有代码,再分析

这里主要是拿取屏幕宽度,和密度,拿密度其实主要是为了将dp转换成px,因为我们拿到的宽度是px为单位,我们动态设置控件高度宽度外边距之类的时候,其实都是px单位,但是我平时是用dp用习惯了,所以这边需要用到转换

dm = new DisplayMetrics(); dm = getResources().getDisplayMetrics(); screenWidth = getWindowManager().getDefaultDisplay().getWidth();    public int convertPx(int dp) {        return dp * dm.densityDpi / 160;    }

这句代码应该好理解,用屏幕的宽度减去两边设置的外边距再除以总进度,从而得到每一个进度所对应的宽度是多少

averageWidth = (screenWidth-convertPx(marginSize)*2)/totalProgress;

这句代码是在计算误差值,因为上一句求宽度平均值的时候,难免会有余数,所以这边暂且叫他误差值吧,进度满的时候,需要自动补齐

errorValue = screenWidth-convertPx(marginSize)*2 - averageWidth*totalProgress;

设置宽度的时候,我建议是直接用layoutParams,用以下两种形式设置宽度,不管用

tv_ma_progress.getLayoutParams().width;

tv_ma_progress.setWidth();

LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(progressDto.getCurrentWidth(), convertPx(35)); layoutParams.setMargins(convertPx(marginSize), convertPx(marginSize), convertPx(marginSize), convertPx(marginSize));

这里其实就是动态设置字体大小的,本来没什么好说的,但是我之前踩过一个坑用的是tv_ma_progress.setTextSize()里面只有一个参数的,一个参数的确实会有问题,所以建议动态设置字体大小还是用下图这个

if(progressDto.getCurrentProgress()<=5){	tv_ma_progress.setTextSize(TypedValue.COMPLEX_UNIT_SP, 4);}else if(progressDto.getCurrentProgress()<=10){   tv_ma_progress.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10);}else{   tv_ma_progress.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);}

github地址:https://github.com/carriefeng/SelfProgressDemo

转载地址:http://twhhp.baihongyu.com/

你可能感兴趣的文章
python基础四-列表与元祖
查看>>
C#语法基础之第二节
查看>>
Maven 梳理 -聚合与继承
查看>>
GC roots
查看>>
DevExpress之XtraReport 学习
查看>>
php 获取mac地址
查看>>
斐波那契数列(升级版)
查看>>
题目1434:今年暑假不AC (项目安排类:结束时间快排,判断开始时间)
查看>>
关于new
查看>>
同步异步阻塞非阻塞可中断的睡眠不可中断的睡眠
查看>>
python-内置函数-callable,chr,ord,bytes,随机验证码生成
查看>>
数据分析与展示---Pandas库数据特征分析
查看>>
二叉搜索树、B树
查看>>
cf里的一些简单组合数题
查看>>
iOS开发UI篇—在UITableview的应用中使用动态单元格来完成app应用程序管理界面的搭建...
查看>>
竞争性需求分析
查看>>
js读取解析JSON数据
查看>>
swift 获取Appstore版本号并与本地版本比较 更新跳转到Appstore
查看>>
51Node 1065----最小正子段和
查看>>
特殊乘法(数位拆解)
查看>>