欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android自定义Material进度条效果

程序员文章站 2024-02-16 23:31:46
首先看下效果图 布局文件:

首先看下效果图

Android自定义Material进度条效果

布局文件:

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

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