您的位置:首页 > 移动开发 > Android开发

Android自定义view之ProgressBar的实现

2016-05-25 19:57 363 查看
在学习自定义view之前我们必须先来了解一下attrs.xml这个文件,这个文件实际上定义了所有的控件的属性,就是我们在布局文件中设置的各类属性,因此在自定义控件属性的时候,创建一个attrs.xml文件来定义控件属性是十分重要的,下面我们开始进行项目的第一部分

一、attrs.xml文件的编写

首先在values文件下新建attrs.xml文件



<?xml version="1.0" encoding="utf-8"?>
<resources>

<!--属性的申明-->

<attr name="progress_unreach_color" format="color"/>  //没有到达的时候进度条的颜色
<attr name="progress_unreach_height" format="dimension"/>
<attr name="progress_reach_color" format="color"/>
<attr name="progress_reach_height" format="dimension"/>
<attr name="progress_text_color" format="color"/>   //<span style="font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px;">format的意思是说:这个textColor可以以两种方式设置,要么是关联一个值,要么<span style="white-space:pre">													</span>//是直接设置一个颜色的RGB值,这个不难理解,因为我们可以平时也这样做过。</span>
<attr name="progress_text_size" format="dimension"/>
<attr name="progress_text_offset" format="dimension"/>  //文本与两边的距离

<!--属性的使用,不需要formet-->

<declare-styleable name="HorizontalProgressBar">

<attr name="progress_unreach_color" />
<attr name="progress_unreach_height" />
<attr name="progress_reach_color" />
<attr name="progress_reach_height"/>
<attr name="progress_text_color" />
<attr name="progress_text_size" />
<attr name="progress_text_offset" />  //文本与两边的距离

</declare-styleable>

</resources>


接下来是自定义view class的编写以及view的绘制

package com.ricahrd.customprogressbar.view;

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

import com.ricahrd.customprogressbar.R;

/**
* Created by jiangwei on 16/5/23.
*/
public class HorizontalProgressBar extends ProgressBar {

private static final int DEFAULT_TEXT_SIZE = 10; //sp
private static final int DEFAULT_TEXT_COLOR = 0xFFFC00D1;
private static final int DEFAULT_COLOR_UNREACH = 0XFFD3D6DA;
private static final int DEFAULT_HEIGHT_UNREACH = 2; //dp
private static final int DEFAULT_COLOR_REACH = 0xFFFC00D1;
private static final int DEFAULT_HEIGHT_REACH = 2; //dp
private static final int DEFAULT_TEXT_OFFSET = 10; //dp

//自定义所需成员变量
private int mTextSize = sp2px(DEFAULT_TEXT_SIZE);
private int mTextColor = DEFAULT_TEXT_COLOR;
private int mUnReachColor = DEFAULT_COLOR_UNREACH;
private int mUnReachHeight = dp2px(DEFAULT_HEIGHT_UNREACH);
private int mReachColor = DEFAULT_COLOR_REACH;
private int mReachHeight = dp2px(DEFAULT_HEIGHT_REACH);
private int mTextOffSet = dp2px(DEFAULT_TEXT_OFFSET);

private Paint mPaint = new Paint();
private int mRealWidth;

public HorizontalProgressBar(Context context) {
this(context, null);
}

public HorizontalProgressBar(Context context, AttributeSet attrs) {
super(context, attrs, 0);
}

public HorizontalProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);

obtainStyleAttrs(attrs);
}

/**
* 获取自定义属性
*
* @param attrs
*/

private void obtainStyleAttrs(AttributeSet attrs) {
TypedArray ta = getContext().obtainStyledAttributes(attrs,
R.styleable.HorizontalProgressBar);

mTextSize = (int) ta.getDimension(R.styleable.HorizontalProgressBar_progress_text_size
, mTextSize);
mTextColor = ta.getColor(R.styleable.HorizontalProgressBar_progress_text_color,
mTextColor);
mTextOffSet = (int) ta.getDimension(R.styleable.HorizontalProgressBar_progress_text_offset,
mTextOffSet);
mUnReachColor = ta.getColor(R.styleable.HorizontalProgressBar_progress_unreach_color,
mUnReachColor);
mUnReachHeight = (int) ta.getDimension(R.styleable.HorizontalProgressBar_progress_unreach_height,
mUnReachHeight);
mReachColor = ta.getColor(R.styleable.HorizontalProgressBar_progress_reach_color,
mReachColor);
mReachHeight = (int) ta.getDimension(R.styleable.HorizontalProgressBar_progress_reach_height,
mReachHeight);

ta.recycle();
mPaint.setTextSize(mTextSize);

}

@Override
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//宽度默认用户一定会给一个确定的值
//        int widthMod = MeasureSpec.getMode(widthMeasureSpec);
int widthVal = MeasureSpec.getSize(widthMeasureSpec);
int height = measureHeight(heightMeasureSpec);
setMeasuredDimension(widthVal, height);

mRealWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();

}

//测量高度
private int measureHeight(int heightMeasureSpec) {

int result = 0;
int mode = MeasureSpec.getMode(heightMeasureSpec);
int size = MeasureSpec.getSize(heightMeasureSpec);

//用户给具体值
if (mode == MeasureSpec.EXACTLY) {
result = size;
} else {
int textheight = (int) (mPaint.descent() - mPaint.ascent());
result = getPaddingBottom() + getPaddingTop() + Math.max(Math.max(mReachHeight, mUnReachHeight),
Math.abs(textheight));
if (mode == MeasureSpec.AT_MOST) {
result = Math.min(result, size);
}

}

return result;
}

@Override
protected synchronized void onDraw(Canvas canvas) {

canvas.save();

canvas.translate(getPaddingLeft(), getHeight() / 2);
boolean noneedUnReach = false;

String text = getProgress() + "%";
//达到的长度百分比
float radio = getProgress() * 1.0f / getMax();
float progressX = radio * mRealWidth;

int textwidth = (int) mPaint.measureText(text);
if (progressX + textwidth > 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);

}

//drawtext
mPaint.setColor(mTextColor);
mPaint.setTextSize(mTextSize);
int y = (int) -(mPaint.descent() + mPaint.ascent()) / 2;
canvas.drawText(text, progressX, y, mPaint);

//draw unreachbar
if (!noneedUnReach) {
float start = progressX + mTextOffSet / 2 + textwidth;
mPaint.setColor(mUnReachColor);
mPaint.setStrokeWidth(mUnReachHeight);
canvas.drawLine(start, 0, mRealWidth, 0, mPaint);

}
canvas.restore();
}

//dp转换成int的方法
public int dp2px(int dpVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpVal,
getResources().getDisplayMetrics());

}

//sp转换成int的方法
public int sp2px(int spVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, spVal,
getResources().getDisplayMetrics());

}

}


布局文件activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:hyman="http://schemas.android.com/apk/res-auto"
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.ricahrd.customprogressbar.view.HorizontalProgressBar

android:id="@+id/progress_01"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:padding="5dp"
hyman:progress_reach_color="#ffff0000"
hyman:progress_text_color="#ffff0000"
hyman:progress_unreach_color="#44ff0000"
android:progress="40" />

</LinearLayout>

</ScrollView>


实现效果:



这就是一个简单的自定义水平进度条工程,欢迎大家与我交流~~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: