Android自定义Progress控件的方法
程序员文章站
2022-04-13 22:49:35
progress各种各样的都有,自定义大多数也是简单的,根据业务需求来自己定义,记录一下,先上效果图
本来想找个第三方改改就上的,不过自己的业务需求有点不搭,一下子没...
progress各种各样的都有,自定义大多数也是简单的,根据业务需求来自己定义,记录一下,先上效果图
本来想找个第三方改改就上的,不过自己的业务需求有点不搭,一下子没找到合适的,也没这么多时间去找了,想想还是自己写个吧,因为也简单。
主要就是需求就是椭圆进度,百分比跟随渐变背景,这样一想其实就是一个布局,然后控制里面的进度长度,或者移动,我这是控制长度,这样毕竟简单,而且扩展好,以后进度条有什么奇葩需求也好改。
import android.content.context; import android.content.res.typedarray; import android.graphics.color; import android.support.annotation.attrres; import android.support.annotation.nonnull; import android.support.annotation.nullable; import android.util.attributeset; import android.view.gravity; import android.view.view; import android.view.viewgroup; import android.widget.framelayout; import android.widget.textview; /** * created by liuzhen on 2017/7/8. */ public class updateprogressbar extends framelayout { private textview tv_progress; private int width; private viewgroup.layoutparams params; /** * the progress text offset. */ private int moffset; /** * the progress text size. */ private float mtextsize; /** * the progress text color. */ private int mtextcolor; private float default_text_size; /** * the progress area bar color. */ private int mreachedbarcolor; /** * the bar unreached area color. */ private int munreachedbarcolor; private final int default_reached_color = color.rgb(66, 145, 241); private final int default_unreached_color = color.rgb(204, 204, 204); private final int default_text_color = color.rgb(66, 145, 241); public updateprogressbar(@nonnull context context) { this(context,null); } public updateprogressbar(@nonnull context context, @nullable attributeset attrs) { this(context, attrs,0); } public updateprogressbar(@nonnull context context, @nullable attributeset attrs, @attrres int defstyleattr) { super(context, attrs, defstyleattr); init(attrs, defstyleattr); } @override protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { int desiredwidth = 100; int desiredheight = 100; int widthmode = measurespec.getmode(widthmeasurespec); int widthsize = measurespec.getsize(widthmeasurespec); int heightmode = measurespec.getmode(heightmeasurespec); int heightsize = measurespec.getsize(heightmeasurespec); int height; //measure width if (widthmode == measurespec.exactly) { //must be this size width = widthsize; } else if (widthmode == measurespec.at_most) { //can't be bigger than... width = math.min(desiredwidth, widthsize); } else { //be whatever you want width = desiredwidth; } //measure height if (heightmode == measurespec.exactly) { //must be this size height = heightsize; } else if (heightmode == measurespec.at_most) { //can't be bigger than... height = math.min(desiredheight, heightsize); } else { //be whatever you want height = desiredheight; } int childcount = getchildcount(); for (int i = 0; i < childcount; i++) { view child = getchildat(i); viewgroup.layoutparams lp = child.getlayoutparams(); int childwidthspec = getchildmeasurespec(widthmeasurespec, 0, lp.width); int childheightspec = getchildmeasurespec(heightmeasurespec, 0, lp.height); child.measure(childwidthspec, childheightspec); } params = tv_progress.getlayoutparams(); params.width = viewgroup.layoutparams.wrap_content; params.height = viewgroup.layoutparams.match_parent; tv_progress.setlayoutparams(params); height = tv_progress.getmeasuredheight(); //must call this setmeasureddimension(width, height); } private void init(attributeset attrs, int defstyleattr){ default_text_size = 8; //load styled attributes. final typedarray attributes = getcontext().gettheme().obtainstyledattributes(attrs, r.styleable.updateprogressbar, defstyleattr, 0); mtextsize = attributes.getdimension(r.styleable.updateprogressbar_update_text_size, default_text_size); mreachedbarcolor = attributes.getresourceid(r.styleable.updateprogressbar_update_reached_color, default_reached_color); munreachedbarcolor = attributes.getresourceid(r.styleable.updateprogressbar_update_unreached_color, default_unreached_color); mtextcolor = attributes.getcolor(r.styleable.updateprogressbar_update_text_color, default_text_color); setdefaultprogressbar(); moffset = px2dip(3); attributes.recycle(); } private void setdefaultprogressbar(){ setbackgroundresource(munreachedbarcolor); tv_progress = new textview(getcontext()); tv_progress.settextsize(mtextsize); tv_progress.setgravity(gravity.right | gravity.center_vertical); tv_progress.settextcolor(mtextcolor); tv_progress.setlines(1); tv_progress.setbackgroundresource(mreachedbarcolor); tv_progress.setpadding(0,0,5,1); tv_progress.settext("0%"); addview(tv_progress); } public void setprogress(int progress){ tv_progress.settext(progress+"%"); int prowidth = width*progress/100; if (tv_progress.getwidth() < prowidth) params.width = prowidth;//这里不能填充moffset,因为是椭圆进度条,填充会导致椭圆宽度被进度条覆盖,导致不美观 tv_progress.setlayoutparams(params); } /** * 根据手机的分辨率从 dp 的单位 转成为 px(像素) */ public int dip2px(context context, float dpvalue) { final float scale = context.getresources().getdisplaymetrics().density; return (int) (dpvalue * scale + 0.5f); } /** * 根据手机的分辨率从 px(像素) 的单位 转成为 dp */ public int px2dip(float pxvalue) { final float scale = getcontext().getresources().getdisplaymetrics().density; return (int) (pxvalue / scale + 0.5f); } /** * 将px值转换为sp值,保证文字大小不变 */ public int px2sp(float pxvalue) { final float fontscale = getcontext().getresources().getdisplaymetrics().scaleddensity; return (int) (pxvalue / fontscale + 0.5f); } /** * 将sp值转换为px值,保证文字大小不变 */ public int sp2px(float spvalue) { final float fontscale = getcontext().getresources().getdisplaymetrics().scaleddensity; return (int) (spvalue * fontscale + 0.5f); } }
用法布局文件
<com.progressbar.example.updateprogressbar xmlns:pro="http://schemas.android.com/apk/res-auto" android:id="@+id/progress" android:layout_width="match_parent" android:layout_height="wrap_content" pro:update_text_size="6sp" pro:update_text_color="#ffffff" pro:update_unreached_color="@drawable/shape_corner_progressbg" pro:update_reached_color="@drawable/shape_corner_progressbar"/>
mainactivity
import android.os.bundle; import android.support.v7.app.actionbaractivity; import android.support.v7.app.appcompatactivity; import android.view.menu; import android.view.menuitem; import android.widget.toast; import com.progressbar.numberprogressbar; import java.util.timer; import java.util.timertask; public class mainactivity extends appcompatactivity { private timer timer; private updateprogressbar progressbar; private int progress; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); progressbar = (updateprogressbar)findviewbyid(r.id.progress); timer = new timer(); timer.schedule(new timertask() { @override public void run() { runonuithread(new runnable() { @override public void run() { progress++; progressbar.setprogress(progress); if(progress == 100) { toast.maketext(getapplicationcontext(), getstring(r.string.finish), toast.length_short).show(); // progress = 0; // progressbar.setprogress(0); timer.cancel(); } } }); } }, 1000, 100); } @override public boolean oncreateoptionsmenu(menu menu) { // inflate the menu; this adds items to the action bar if it is present. getmenuinflater().inflate(r.menu.main, menu); return true; } @override public boolean onoptionsitemselected(menuitem item) { // handle action bar item clicks here. the action bar will // automatically handle clicks on the home/up button, so long // as you specify a parent activity in androidmanifest.xml. int id = item.getitemid(); if (id == r.id.action_settings) { return true; } return super.onoptionsitemselected(item); } @override protected void ondestroy() { super.ondestroy(); timer.cancel(); } }
渐变背景
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#4984f2"/> <gradient android:startcolor="#4984f2" android:endcolor="#000" /> <corners android:topleftradius="15dp" android:toprightradius="15dp" android:bottomleftradius="15dp" android:bottomrightradius="15dp"/> </shape>
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#dadada"/> <gradient android:startcolor="#fff" android:endcolor="#000" /> <corners android:topleftradius="15dp" android:toprightradius="15dp" android:bottomleftradius="15dp" android:bottomrightradius="15dp"/> </shape>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。