博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
自定义进度条(圆形、横向进度条)
阅读量:4556 次
发布时间:2019-06-08

本文共 8348 字,大约阅读时间需要 27 分钟。

自定义进度条实现大体流程

  1、自定义属性声明(attrs文件)
  2、自定义属性获取
  3、测量(onMeasure)
  4、绘制(onDraw)

代码:

 attrs文件:

  

<!-- 自定义声明 -->

<attr name="progress_unreach_color" format="color"></attr>
<attr name="progress_unreach_height" format="dimension"></attr>
<attr name="progress_reach_color" format="color"></attr>
<attr name="progress_reach_height" format="dimension"></attr>
<attr name="progress_text_color" format="color"></attr>
<attr name="progress_text_size" format="dimension"></attr>
<attr name="progress_text_offset" format="dimension"></attr>
<!-- 自定义使用 -->
<declare-styleable name="ProgressbarView">
<attr name="progress_unreach_color"></attr>
<attr name="progress_unreach_height"></attr>
<attr name="progress_reach_color"></attr>
<attr name="progress_reach_height"></attr>
<attr name="progress_text_color"></attr>
<attr name="progress_text_size"></attr>
<attr name="progress_text_offset"></attr>
</declare-styleable>

  布局文件:

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"
xmlns:hyman="http://schemas.android.com/apk/res/com.Horizontal.horizontalprogressbar"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<LinearLayout

android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >

<com.Horizontal.view.ProgressbarView

android:id="@+id/progress01"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dip"
hyman:progress_reach_color="#f00"
hyman:progress_text_color="#f00"
hyman:progress_unreach_color="#000"
android:background="#d1d3d7"
android:padding="10dip"
android:progress="0" />
<com.Horizontal.view.RoundProgressbar
android:id="@+id/progress02"
android:layout_width="match_parent"
android:layout_height="wrap_content"
hyman:progress_reach_color="#f3d4e3"
hyman:progress_text_color="#f00"
hyman:progress_unreach_color="#000"
android:layout_marginTop="30dp"
hyman:rudio="80dp"
android:padding="10dip"
android:progress="0"
/>
</LinearLayout>

</ScrollView>

ProgressbarView文件:

package com.Horizontal.view;

import com.Horizontal.horizontalprogressbar.R;

import android.content.Context;

import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.ProgressBar;

public class ProgressbarView extends ProgressBar {

private static final int DEFAULT_TEXT_SIZE = 10;// 字体大小 sp
private static final int DEFAULT_TEXT_COLOR = 0xFC00D1;
private static final int DEFAULT_REACH_HEIGHT = 3;// 左进度条高度 dp
private static final int DEFAULT_REACH_COLOR = DEFAULT_TEXT_COLOR;
private static final int DEFAULT_UNREACH_HEIGHT = 2;// 右进度条高度 dp
private static final int DEFAULT_UNREACH_COLOR = 0xD3D6D1;
private static final int DEFAULT_TEXT_OFFSET = 10;// 做进度条与文字的距离 dp

protected int mTextSize = sp2px(DEFAULT_TEXT_SIZE);

protected int mTextColor = DEFAULT_TEXT_COLOR;
protected int mReachHeight = dp2px(DEFAULT_REACH_HEIGHT);
protected int mReachColor = DEFAULT_REACH_COLOR;
protected int mUnReachHeight = dp2px(DEFAULT_UNREACH_HEIGHT);
protected int mUnReachColor = DEFAULT_UNREACH_COLOR;
protected int mTextOffset = dp2px(DEFAULT_TEXT_OFFSET);

protected Paint mPaint = new Paint();

// 控件的宽度
private int mRealWidth;

public ProgressbarView(Context context) {

this(context, null);
}

public ProgressbarView(Context context, AttributeSet attrs) {

this(context, attrs, 0);
}

public ProgressbarView(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);
obtainStyledAttrs(attrs);
}

/** 获取自定义属性 **/

private void obtainStyledAttrs(AttributeSet attrs) {
// 获取attr文件中的styleable(ProgressbarView)
TypedArray ta = getContext().obtainStyledAttributes(attrs,
R.styleable.ProgressbarView);
// 获取自定义属性和默认值
mTextSize = (int) ta.getDimension(
R.styleable.ProgressbarView_progress_text_size, mTextSize);
mTextColor = ta.getColor(
R.styleable.ProgressbarView_progress_text_color, mTextColor);
mReachHeight = (int) ta
.getDimension(
R.styleable.ProgressbarView_progress_reach_height,
mReachHeight);
mReachColor = ta.getColor(
R.styleable.ProgressbarView_progress_reach_color, mReachColor);
mUnReachHeight = (int) ta.getDimension(
R.styleable.ProgressbarView_progress_unreach_height,
mUnReachHeight);
mUnReachColor = ta.getColor(
R.styleable.ProgressbarView_progress_unreach_color,
mUnReachColor);
mTextOffset = (int) ta.getDimension(
R.styleable.ProgressbarView_progress_text_offset, mTextOffset);

ta.recycle();

mPaint.setTextSize(mTextSize);
}

/** 宽度和高度的测量 **/

@Override
protected synchronized void onMeasure(int widthMeasureSpec,
int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// 拿宽度的模式
// int widthMode = MeasureSpec.getMode(widthMeasureSpec);
// 宽度的值(横向精度条要给明确值,所以不需要判断)
int widthVal = MeasureSpec.getSize(widthMeasureSpec);
int heigth = MeasureSpecHeigth(heightMeasureSpec);
setMeasuredDimension(widthVal, heigth);
// 实际绘画的宽度
mRealWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
}

/** 高度测量 **/

private int MeasureSpecHeigth(int heightMeasureSpec) {
int result = 0;
int mode = MeasureSpec.getMode(heightMeasureSpec);
int size = MeasureSpec.getSize(heightMeasureSpec);
// EXACTLY 父结点要求其子节点的大小指定为某个确切的值。其子节点以及其他子孙结点都需要适应该大小。
if (mode == MeasureSpec.EXACTLY) {
result = size;
} else {
int textHeigth = (int) (mPaint.descent() - mPaint.ascent());
result = getPaddingTop()
+ getPaddingBottom()
+ Math.max(Math.max(mReachHeight, mUnReachHeight),
Math.abs(textHeigth));
// AT_MOST 父结点要求其子节点的大小不能超过某个最大值,其子节点以及其他子孙结点的大小都需要小于这个值
if (mode == MeasureSpec.AT_MOST) {
result = Math.min(result, size);
}
}

return result;

}

/** 画控件 **/

@Override
protected synchronized void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
// 抗锯齿
canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG
| Paint.FILTER_BITMAP_FLAG));
// 设置画布的原点
canvas.translate(getPaddingLeft(), getHeight() / 2);
// /draw reach
boolean noNeedUnreach = false;
String text = getProgress() + "%";
int textWidth = (int) mPaint.measureText(text);
float radio = getProgress() * 1.0f / getMax();
float progressX = radio * mRealWidth;
if (textWidth + progressX > mRealWidth) {
progressX = mRealWidth - textWidth;
noNeedUnreach = true;
}

float endX = progressX - mTextOffset / 2;

if (endX > 0) {
mPaint.setColor(mReachColor);
mPaint.setStrokeWidth(mReachHeight);
canvas.drawLine(0, 0, endX, 0, mPaint);
}

// draw text

mPaint.setColor(mTextColor);
int y = (int) (-(mPaint.descent() + mPaint.ascent()) / 2);
canvas.drawText(text, progressX, y, mPaint);
// draw unreach bar
if (!noNeedUnreach) {
float start = progressX + mTextOffset / 2 + textWidth;
mPaint.setColor(mUnReachColor);
mPaint.setStrokeWidth(mUnReachHeight);
canvas.drawLine(start, 0, mRealWidth, 0, mPaint);
}

canvas.restore();

}

/** dp转px **/

protected int dp2px(int dpVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dpVal, getResources().getDisplayMetrics());
}

/** sp转px **/

protected int sp2px(int spVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
spVal, getResources().getDisplayMetrics());
}
}

  MainActivity:

package com.Horizontal.horizontalprogressbar;

import com.Horizontal.view.ProgressbarView;

import com.Horizontal.view.RoundProgressbar;

import android.os.Bundle;

import android.os.Handler;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends Activity {

private ProgressbarView progressbarView;
// private RoundProgressbar roundProgressbar;
private static final int MSG_UPDATE = 0X110;

@Override

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressbarView = (ProgressbarView) findViewById(R.id.progress01);
// roundProgressbar=(RoundProgressbar) findViewById(R.id.progress02);
handler.sendEmptyMessage(MSG_UPDATE);
}

private Handler handler = new Handler() {

public void handleMessage(android.os.Message msg) {
int progress = progressbarView.getProgress();
// roundProgressbar.setProgress(++progress);
progressbarView.setProgress(++progress);
if (progress >= 100) {
handler.removeMessages(MSG_UPDATE);
}
handler.sendEmptyMessageDelayed(MSG_UPDATE, 100);
};
};

}

 源码下载:链接: 密码: whs7

转载于:https://www.cnblogs.com/Jason-123/p/5704286.html

你可能感兴趣的文章
【NOIP1999】【Luogu1015】回文数(高精度,模拟)
查看>>
Linux上安装Python3.5
查看>>
crt安装
查看>>
git切换分支报错:error: pathspec 'origin/XXX' did not match any file(s) known to git
查看>>
c++中static的用法详解
查看>>
转 我修改的注册表,但是程序运行起来,还是记着以前的
查看>>
图片轮播功能
查看>>
第六周小组作业:软件测试和评估
查看>>
linux Cacti监控服务器搭建
查看>>
debian(kali Linux) 安装net Core
查看>>
centos 7防火墙设置
查看>>
自定义进度条(圆形、横向进度条)
查看>>
spark-streaming-kafka采坑
查看>>
9.Mongodb与python交互
查看>>
18-[JavaScript]-函数,Object对象,定时器,正则表达式
查看>>
读取短信回执
查看>>
EF 数据初始化
查看>>
PreparedStatement与Statement
查看>>
WebService -- Java 实现之 CXF ( 使用CXF工具生成client 程序)
查看>>
[LeetCode]Two Sum
查看>>