Android自定义Material进度条效果
程序员文章站
2023-12-20 23:45:16
首先看下效果图
布局文件:
首先看下效果图
布局文件:
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" android:gravity="center" android:orientation="vertical" android:paddingbottom="@dimen/activity_vertical_margin" android:paddingleft="@dimen/activity_horizontal_margin" android:paddingright="@dimen/activity_horizontal_margin" android:paddingtop="@dimen/activity_vertical_margin" > <com.example.mytest.view.circleprogressbar android:id="@+id/progress1" android:layout_width="60dp" android:layout_height="60dp" app:mlpb_progress_color="#566da9" app:mlpb_progress_stoke_width="3dp" /> </linearlayout>
声明属性
<declare-styleable name="circleprogressbar"> <attr name="mlpb_inner_radius" format="dimension"/> <attr name="mlpb_background_color" format="color"/> <attr name="mlpb_progress_color" format="color"/> <attr name="mlpb_progress_stoke_width" format="dimension"/> <attr name="mlpb_show_arrow" format="boolean"/> <attr name="mlpb_enable_circle_background" format="boolean"/> <attr name="mlpb_arrow_width" format="dimension"/> <attr name="mlpb_arrow_height" format="dimension"/> <attr name="mlpb_progress" format="integer"/> <attr name="mlpb_max" format="integer"/> <attr name="mlpb_progress_text_size" format="dimension"/> <attr name="mlpb_progress_text_color" format="color"/> <!--<attr name="mlpb_progress_text_offset" format="dimension"/>--> <attr name="mlpb_progress_text_visibility" format="enum"> <enum name="visible" value="0"/> <enum name="invisible" value="1"/> </attr> </declare-styleable>
自定义控件:
/* * copyright (c) 2014 the android open source project * * licensed under the apache license, version 2.0 (the "license"); * you may not use this file except in compliance with the license. * you may obtain a copy of the license at * * http://www.apache.org/licenses/license-2.0 * * unless required by applicable law or agreed to in writing, software * distributed under the license is distributed on an "as is" basis, * without warranties or conditions of any kind, either express or implied. * see the license for the specific language governing permissions and * limitations under the license. */ package com.example.mytest.view; import android.content.context; import android.content.res.resources; import android.content.res.typedarray; import android.graphics.canvas; import android.graphics.color; import android.graphics.paint; import android.graphics.radialgradient; import android.graphics.shader; import android.graphics.drawable.drawable; import android.graphics.drawable.shapedrawable; import android.graphics.drawable.shapes.ovalshape; import android.net.uri; import android.support.v4.view.viewcompat; import android.util.attributeset; import android.view.animation.animation; import android.widget.imageview; import com.example.mytest.r; /** * private class created to work around issues with animationlisteners being * called before the animation is actually complete and support shadows on older * platforms. */ public class circleprogressbar extends imageview { private static final int key_shadow_color = 0x1e000000; private static final int fill_shadow_color = 0x3d000000; // px private static final float x_offset = 0f; private static final float y_offset = 1.75f; private static final float shadow_radius = 3.5f; private static final int shadow_elevation = 4; private static final int default_circle_bg_light = 0xfffafafa; private static final int default_circle_diameter = 56; private static final int stroke_width_large = 3; public static final int default_text_size = 9; private animation.animationlistener mlistener; private int mshadowradius; private int mbackgroundcolor; private int mprogresscolor; private int mprogressstokewidth; private int marrowwidth; private int marrowheight; private int mprogress; private int mmax; private int mdiameter; private int minnerradius; private paint mtextpaint; private int mtextcolor; private int mtextsize; private boolean mifdrawtext; private boolean mshowarrow; private materialprogressdrawable mprogressdrawable; private shapedrawable mbgcircle; private boolean mcirclebackgroundenabled; private int[] mcolors = new int[]{color.black}; public circleprogressbar(context context) { super(context); init(context, null, 0); } public circleprogressbar(context context, attributeset attrs) { super(context, attrs); init(context, attrs, 0); } public circleprogressbar(context context, attributeset attrs, int defstyleattr) { super(context, attrs, defstyleattr); init(context, attrs, defstyleattr); } private void init(context context, attributeset attrs, int defstyleattr) { final typedarray a = context.obtainstyledattributes( attrs, r.styleable.circleprogressbar, defstyleattr, 0); // <attr name="mlpb_inner_radius" format="dimension"/> // <attr name="mlpb_background_color" format="color"/> // <attr name="mlpb_progress_color" format="color"/> // <attr name="mlpb_progress_stoke_width" format="dimension"/> // <attr name="mlpb_arrow_width" format="dimension"/> // <attr name="mlpb_arrow_height" format="dimension"/> // // <attr name="mlpb_progress" format="integer"/> // <attr name="mlpb_max" format="integer"/> // // // <attr name="mlpb_progress_text_size" format="dimension"/> // <attr name="mlpb_progress_text_color" format="color"/> // // <attr name="mlpb_progress_text_offset" format="dimension"/> // // <attr name="mlpb_progress_text_visibility" format="enum"> // <enum name="visible" value="0"/> // <enum name="invisible" value="1"/> // </attr> final float density = getcontext().getresources().getdisplaymetrics().density; mbackgroundcolor = a.getcolor( r.styleable.circleprogressbar_mlpb_background_color, default_circle_bg_light); mprogresscolor = a.getcolor( r.styleable.circleprogressbar_mlpb_progress_color, default_circle_bg_light); mcolors = new int[]{mprogresscolor}; minnerradius = a.getdimensionpixeloffset( r.styleable.circleprogressbar_mlpb_inner_radius, -1); mprogressstokewidth = a.getdimensionpixeloffset( r.styleable.circleprogressbar_mlpb_progress_stoke_width, (int) (stroke_width_large * density)); marrowwidth = a.getdimensionpixeloffset( r.styleable.circleprogressbar_mlpb_arrow_width, -1); marrowheight = a.getdimensionpixeloffset( r.styleable.circleprogressbar_mlpb_arrow_height, -1); mtextsize = a.getdimensionpixeloffset( r.styleable.circleprogressbar_mlpb_progress_text_size, (int) (default_text_size * density)); mtextcolor = a.getcolor( r.styleable.circleprogressbar_mlpb_progress_text_color, color.black); mshowarrow = a.getboolean(r.styleable.circleprogressbar_mlpb_show_arrow, false); mcirclebackgroundenabled = a.getboolean(r.styleable.circleprogressbar_mlpb_enable_circle_background, true); mprogress = a.getint(r.styleable.circleprogressbar_mlpb_progress, 0); mmax = a.getint(r.styleable.circleprogressbar_mlpb_max, 100); int textvisible = a.getint(r.styleable.circleprogressbar_mlpb_progress_text_visibility, 1); if (textvisible != 1) { mifdrawtext = true; } mtextpaint = new paint(); mtextpaint.setstyle(paint.style.fill); mtextpaint.setcolor(mtextcolor); mtextpaint.settextsize(mtextsize); mtextpaint.setantialias(true); a.recycle(); mprogressdrawable = new materialprogressdrawable(getcontext(), this); super.setimagedrawable(mprogressdrawable); } private boolean elevationsupported() { return android.os.build.version.sdk_int >= 21; } @override protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { super.onmeasure(widthmeasurespec, heightmeasurespec); if (!elevationsupported()) { setmeasureddimension(getmeasuredwidth() + mshadowradius * 2, getmeasuredheight() + mshadowradius * 2); } } @override protected void onlayout(boolean changed, int left, int top, int right, int bottom) { super.onlayout(changed, left, top, right, bottom); final float density = getcontext().getresources().getdisplaymetrics().density; mdiameter = math.min(getmeasuredwidth(), getmeasuredheight()); if (mdiameter <= 0) { mdiameter = (int) density * default_circle_diameter; } if (getbackground() == null && mcirclebackgroundenabled) { final int shadowyoffset = (int) (density * y_offset); final int shadowxoffset = (int) (density * x_offset); mshadowradius = (int) (density * shadow_radius); if (elevationsupported()) { mbgcircle = new shapedrawable(new ovalshape()); viewcompat.setelevation(this, shadow_elevation * density); } else { ovalshape oval = new ovalshadow(mshadowradius, mdiameter - mshadowradius * 2); mbgcircle = new shapedrawable(oval); viewcompat.setlayertype(this, viewcompat.layer_type_software, mbgcircle.getpaint()); mbgcircle.getpaint().setshadowlayer(mshadowradius, shadowxoffset, shadowyoffset, key_shadow_color); final int padding = (int) mshadowradius; // set padding so the inner image sits correctly within the shadow. setpadding(padding, padding, padding, padding); } mbgcircle.getpaint().setcolor(mbackgroundcolor); setbackgrounddrawable(mbgcircle); } mprogressdrawable.setbackgroundcolor(mbackgroundcolor); mprogressdrawable.setcolorschemecolors(mcolors); mprogressdrawable.setsizeparameters(mdiameter, mdiameter, minnerradius <= 0 ? (mdiameter - mprogressstokewidth * 2) / 4 : minnerradius, mprogressstokewidth, marrowwidth < 0 ? mprogressstokewidth * 4 : marrowwidth, marrowheight < 0 ? mprogressstokewidth * 2 : marrowheight); if (isshowarrow()) { mprogressdrawable.showarrowonfirststart(true); mprogressdrawable.setarrowscale(1f); mprogressdrawable.showarrow(true); } super.setimagedrawable(null); super.setimagedrawable(mprogressdrawable); mprogressdrawable.setalpha(255); if(getvisibility()==visible) { mprogressdrawable.start(); } } @override protected void ondraw(canvas canvas) { super.ondraw(canvas); if (mifdrawtext) { string text = string.format("%s%%", mprogress); int x = getwidth() / 2 - text.length() * mtextsize / 4; int y = getheight() / 2 + mtextsize / 4; canvas.drawtext(text, x, y, mtextpaint); } } @override final public void setimageresource(int resid) { } public boolean isshowarrow() { return mshowarrow; } public void setshowarrow(boolean showarrow) { this.mshowarrow = showarrow; } @override final public void setimageuri(uri uri) { super.setimageuri(uri); } @override final public void setimagedrawable(drawable drawable) { } public void setanimationlistener(animation.animationlistener listener) { mlistener = listener; } @override public void onanimationstart() { super.onanimationstart(); if (mlistener != null) { mlistener.onanimationstart(getanimation()); } } @override public void onanimationend() { super.onanimationend(); if (mlistener != null) { mlistener.onanimationend(getanimation()); } } /** * set the color resources used in the progress animation from color resources. * the first color will also be the color of the bar that grows in response * to a user swipe gesture. * * @param colorresids */ public void setcolorschemeresources(int... colorresids) { final resources res = getresources(); int[] colorres = new int[colorresids.length]; for (int i = 0; i < colorresids.length; i++) { colorres[i] = res.getcolor(colorresids[i]); } setcolorschemecolors(colorres); } /** * set the colors used in the progress animation. the first * color will also be the color of the bar that grows in response to a user * swipe gesture. * * @param colors */ public void setcolorschemecolors(int... colors) { mcolors = colors; if (mprogressdrawable != null) { mprogressdrawable.setcolorschemecolors(colors); } } /** * update the background color of the mbgcircle image view. */ public void setbackgroundcolor(int colorres) { if (getbackground() instanceof shapedrawable) { final resources res = getresources(); ((shapedrawable) getbackground()).getpaint().setcolor(res.getcolor(colorres)); } } public boolean isshowprogresstext() { return mifdrawtext; } public void setshowprogresstext(boolean mifdrawtext) { this.mifdrawtext = mifdrawtext; } public int getmax() { return mmax; } public void setmax(int max) { mmax = max; } public int getprogress() { return mprogress; } public void setprogress(int progress) { if (getmax() > 0) { mprogress = progress; } } public boolean circlebackgroundenabled() { return mcirclebackgroundenabled; } public void setcirclebackgroundenabled(boolean enablecirclebackground) { this.mcirclebackgroundenabled = enablecirclebackground; } @override public int getvisibility() { return super.getvisibility(); } @override public void setvisibility(int visibility) { super.setvisibility(visibility); if (mprogressdrawable != null) { mprogressdrawable.setvisible(visibility == visible, false); if (visibility != visible) { mprogressdrawable.stop(); } else { if (mprogressdrawable.isrunning()) { mprogressdrawable.stop(); } mprogressdrawable.start(); } } } @override protected void onattachedtowindow() { super.onattachedtowindow(); if (mprogressdrawable != null) { mprogressdrawable.stop(); mprogressdrawable.setvisible(getvisibility() == visible, false); requestlayout(); } } @override protected void ondetachedfromwindow() { super.ondetachedfromwindow(); if (mprogressdrawable != null) { mprogressdrawable.stop(); mprogressdrawable.setvisible(false, false); } } private class ovalshadow extends ovalshape { private radialgradient mradialgradient; private int mshadowradius; private paint mshadowpaint; private int mcirclediameter; public ovalshadow(int shadowradius, int circlediameter) { super(); mshadowpaint = new paint(); mshadowradius = shadowradius; mcirclediameter = circlediameter; mradialgradient = new radialgradient(mcirclediameter / 2, mcirclediameter / 2, mshadowradius, new int[]{ fill_shadow_color, color.transparent }, null, shader.tilemode.clamp); mshadowpaint.setshader(mradialgradient); } @override public void draw(canvas canvas, paint paint) { final int viewwidth = circleprogressbar.this.getwidth(); final int viewheight = circleprogressbar.this.getheight(); canvas.drawcircle(viewwidth / 2, viewheight / 2, (mcirclediameter / 2 + mshadowradius), mshadowpaint); canvas.drawcircle(viewwidth / 2, viewheight / 2, (mcirclediameter / 2), paint); } } }
在java代码中设置进度条上的颜色值
progress1 = (circleprogressbar) findviewbyid(r.id.progress1); progress1.setcolorschemeresources(android.r.color.holo_green_light,android.r.color.holo_orange_light,android.r.color.holo_red_light);
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。