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

Android自定义Progress控件的方法

程序员文章站 2022-04-13 22:49:35
progress各种各样的都有,自定义大多数也是简单的,根据业务需求来自己定义,记录一下,先上效果图 本来想找个第三方改改就上的,不过自己的业务需求有点不搭,一下子没...

progress各种各样的都有,自定义大多数也是简单的,根据业务需求来自己定义,记录一下,先上效果图

Android自定义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>

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