本文共 5331 字,大约阅读时间需要 17 分钟。
前几天一个朋友问我一下图片这个进度条怎么好实现
总的来说呐,实现思路其实还是蛮简单,首先定义好自己想要的样式的进度条然后获取屏幕的宽度,减去你设置的外边距,也就是获取你进度条的总长度,然后算出每一个进度你需要的前进的宽度是多少,(因为这里是整数,所以在进度条满了的时候还需要补齐误差值),所有dp的单位根据屏幕密度换算成px单位,然后再通过线程通信动态更新进度条的进度,就O了。
直接贴代码了
这边之所以用个线性布局,是为了方便后期动态设置这个texview的layoutParams属性
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/