当前位置: 移动技术网 > 移动技术>移动开发>Android > Android自定义Material进度条效果

Android自定义Material进度条效果

2019年07月24日  | 移动技术网移动技术  | 我要评论

首先看下效果图

布局文件:

<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); 

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网