版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】怎么在Android中通过自定义View实现渐变色进度条
今天就跟大家聊聊有关怎么在Android中通过自定义View实现渐变色进度条,可能很多人都不太了解,为了让大家更加了解,在下给大家总结了以下内容,希望大家根据这篇文章可以有所收获。效果分解:1.渐变色,看起来颜色变化并不复杂,使用LinearGradient应该可以实现。2.圆头,无非是画两个圆,外圆使用渐变色的颜色,内圆固定为白色。3.灰底,还没有走到的进度部分为灰色。4.进度值,使用文本来显示;5.弧形的头部,考虑使用直线进行连接,或者使用曲线,例如贝塞尔曲线;我首先初步实现了进度条的模样,发现样子有了,却不太美观。反思了一下,我只是个写代码的,对于哪种比例比较美观,是没有清晰的认识的,所以,还是参考原图吧。然后就进行了精细的测量:将图像放大4倍,进行测量,然后获取到各部分的比例关系,具体过程就不细说了,说一下测量结果(按比例的):视图总长300,其中前面留空5,进度长258,然后再留空5,显示文本占26,后面留空6;高度分为4个:外圆:10字高:9内圆:6线粗:5考虑上下各留空10,则视图的高度为30。考虑到视图整体的效果,可以由用户来设置长度值与高度值,按比例取最小值来进行绘图。首先计算出一个单位的实际像素数,各部分按比例来显示即可。还有一个弧形的头部,是怎么实现的呢?在放大之后,能看出来图形比较简单,看不出有弧度,那么,使用一小段直线连接就可以了。估算这小段直线:线粗为2,呈30度角,长为8-10即可,连接直线与弧顶,起点在弧顶之左下方。注意:在进度的起点时,不能画出。避免出现一个很突兀的小尾巴。在2%进度之后,才开始画。在文字的绘制过程中,遇到一个小问题,就是文字不居中,略微偏下,上网查了下,原因是这样的:我们绘制文本时,使用的这个函数:canvas.drawText(“30%”,x,y,paint);其中的参数y是指字符串baseline的的位置,不是文本的中心。通过计算可以调整为居中,如下://计算坐标使文字居中
FontMetrics
fontMetrics
=
mPaint.getFontMetrics();
float
fontHeight
=
fontMetrics.bottom
-
fontMetrics.top;
float
baseY
=
height/2
+
fontHeight/2
-
fontMetrics.bottom;按比例来绘制之后,就确实是原来那个修长优雅的感觉了。实际运行后,发现字体偏小,不太适合竖屏观看,调大了些。另外对于参数,做了如下几个自定义属性:前景色:开始颜色,结束颜色;进度条未走到时的默认颜色,字体颜色。属性xml如下:<?xml
version="1.0"
encoding="utf-8"?>
<resources>
<attr
name="startColor"
format="color"
/>
<attr
name="endColor"
format="color"
/>
<attr
name="backgroundColor"
format="color"
/>
<attr
name="textColor"
format="color"
/>
<declare-styleable
name="GoodProgressView">
<attr
name="startColor"
/>
<attr
name="endColor"
/>
<attr
name="backgroundColor"
/>
<attr
name="textColor"
/>
</declare-styleable>
</resources>自定义View文件:package
com.customview.view;
import
android.content.Context;
import
android.content.res.TypedArray;
import
android.graphics.Canvas;
import
android.graphics.Color;
import
android.graphics.LinearGradient;
import
android.graphics.Paint;
import
android.graphics.Shader;
import
android.graphics.Paint.Cap;
import
android.graphics.Paint.FontMetrics;
import
android.graphics.Paint.Style;
import
android.util.AttributeSet;
import
android.util.Log;
import
android.view.View;
import
com.customview.R;
public
class
GoodProgressView
extends
View
{
private
int[]
mColors
=
{
Color.RED,
Color.MAGENTA};//进度条颜色(渐变色的2个点)
private
int
backgroundColor
=
Color.GRAY;//进度条默认颜色
private
int
textColor
=
Color.GRAY;//文本颜色
private
Paint
mPaint;//画笔
private
int
progressValue=0;//进度值
//
private
RectF
rect;//绘制范围
public
GoodProgressView(Context
context,
AttributeSet
attrs)
{
this(context,
attrs,
0);
}
public
GoodProgressView(Context
context)
{
this(context,
null);
}
//
获得我自定义的样式属性
public
GoodProgressView(Context
context,
AttributeSet
attrs,
int
defStyle)
{
super(context,
attrs,
defStyle);
//
获得我们所定义的自定义样式属性
TypedArray
a
=
context.getTheme().obtainStyledAttributes(attrs,
R.styleable.GoodProgressView,
defStyle,
0);
int
n
=
a.getIndexCount();
for
(int
i
=
0;
i
<
n;
i++)
{
int
attr
=
a.getIndex(i);
switch
(attr)
{
case
R.styleable.GoodProgressView_startColor:
//
渐变色之起始颜色,默认设置为红色
mColors[0]
=
a.getColor(attr,
Color.RED);
break;
case
R.styleable.GoodProgressView_endColor:
//
渐变色之结束颜色,默认设置为品红
mColors[1]
=
a.getColor(attr,
Color.MAGENTA);
break;
case
R.styleable.GoodProgressView_backgroundColor:
//
进度条默认颜色,默认设置为灰色
backgroundColor
=
a.getColor(attr,
Color.GRAY);
break;
case
R.styleable.GoodProgressView_textColor:
//
文字颜色,默认设置为灰色
textColor
=
a.getColor(attr,
Color.GRAY);
break;
}
}
a.recycle();
mPaint
=
new
Paint();
progressValue=0;
}
public
void
setProgressValue(int
progressValue){
if(progressValue>100){
progressValue
=
100;
}
gressValue
=
progressValue;
Log.i("customView","log:
progressValue="+progressValue);
}
public
void
setColors(int[]
colors){
mColors
=
colors;
}
@Override
protected
void
onMeasure(int
widthMeasureSpec,
int
heightMeasureSpec)
{
int
width
=
0;
int
height
=
0;
/**
*
设置宽度
*/
int
specMode
=
MeasureSpec.getMode(widthMeasureSpec);
int
specSize
=
MeasureSpec.getSize(widthMeasureSpec);
switch
(specMode)
{
case
MeasureSpec.EXACTLY://
明确指定了
width
=
specSize;
break;
case
MeasureSpec.AT_MOST://
一般为WARP_CONTENT
width
=
getPaddingLeft()
+
getPaddingRight()
;
break;
}
/**
*
设置高度
*/
specMode
=
MeasureSpec.getMode(heightMeasureSpec);
specSize
=
MeasureSpec.getSize(heightMeasureSpec);
switch
(specMode)
{
case
MeasureSpec.EXACTLY://
明确指定了
height
=
specSize;
break;
case
MeasureSpec.AT_MOST://
一般为WARP_CONTENT
height
=
width/10;
break;
}
Log.i("customView","log:
w="+width+"
h="+height);
setMeasuredDimension(width,
height);
}
@Override
protected
void
onDraw(Canvas
canvas)
{
super.onDraw(canvas);
int
mWidth
=
getMeasuredWidth();
int
mHeight
=
getMeasuredHeight();
//按比例计算进度条各部分的值
float
unit
=
Math.min(((float)mWidth)/300,
((float)mHeight)/30);
float
lineWidth
=
5*unit;//线粗
float
innerCircleDiameter
=
6*unit;//内圆直径
float
outerCircleDiameter
=
10*unit;//外圆直径
float
wordHeight
=
12*unit;//字高//9*unit
//
float
wordWidth
=
26*unit;//字长
float
offsetLength
=
5*unit;//留空
//
float
width
=
300*unit;//绘画区域的长度
float
height
=
30*unit;//绘画区域的高度
float
progressWidth
=
258*unit;//绘画区域的长度
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth((float)
lineWidth
);
mPaint.setStyle(Style.STROKE);
mPaint.setStrokeCap(Cap.ROUND);
mPaint.setColor(Color.TRANSPARENT);
float
offsetHeight=height/2;
float
offsetWidth=offsetLength;
float
section
=
((float)progressValue)
/
100;
if(section>1)
section=1;
int
count
=
mColors.length;
int[]
colors
=
new
int[count];
System.arraycopy(mColors,
0,
colors,
0,
count);
//底部灰色背景,指示进度条总长度
mPaint.setShader(null);
mPaint.setColor(backgroundColor);
canvas.drawLine(offsetWidth+section
*
progressWidth,
offsetHeight,
offsetWidth+progressWidth,
offsetHeight,
mPaint);
//设置渐变色区域
LinearGradient
shader
=
new
LinearGradient(0,
0,
offsetWidth*2+progressWidth
,
0,
colors,
null,
Shader.TileMode.CLAMP);
mPaint.setShader(shader);
//画出渐变色进度条
canvas.drawLine(offsetWidth,
offsetHeight,
offsetWidth+section*progressWidth,
offsetHeight,
mPaint);
//渐变色外圆
mPaint.setStrokeWidth(1);
mPaint.setStyle(Paint.Style.FILL);
canvas.drawCircle(offsetWidth+section
*
progressWidth,
offsetHeight,
outerCircleDiameter/2,
mPaint);
//绘制两条斜线,使外圆到进度条的连接更自然
if(section*100>1.8){
mPaint.setStrokeWidth(2*unit);
canvas.drawLine(offsetWidth+section
*
progressWidth-6*unit,
offsetHeight-(float)1.5*unit,
offsetWidth+section
*
progressWidth-1*unit,offsetHeight-(float)3.8*unit,
mPaint);
canvas.drawLine(offsetWidth+section
*
progressWidth-6*unit,
offsetHeight+(float)1.5*unit,
offsetWidth+section
*
progressWidth-1*unit,offsetHeight+(float)3.8*unit,
mPaint);
}
//白色内圆
mPaint.setShader(null);
mPaint.setColor(Color.WHITE);
canvas.drawCircle(offsetWidth+section
*
progressWidth,
offsetHeight,
innerCircleDiameter/2,
mPaint);//白色内圆
//绘制文字--百分比
mPaint.setStrokeWidth(2*unit);
mPaint.setColor(textColor);
mPaint.setTextSize(wordHeight);
//计算坐标使文字居中
FontMetrics
fontMetrics
=
mPaint.getFontMetrics();
float
fontHeight
=
fontMetrics.bottom
-
fontMetrics.top;
float
baseY
=
height/2
+
fontHeight/2
-
fontMetrics.bottom;
canvas.drawText(""+progressValue+"%",
progressWidth+2*offsetWidth,
baseY,
mPaint);//略微偏下,baseline
}
}主xml:放了两个进度条,一个使用默认值,一个设置了进度条默认颜色与字体颜色:<RelativeLayout
xmlns:android="/apk/res/android"
xmlns:tools="/tools"
xmlns:custom="/apk/res/com.customview"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<com.customview.view.GoodProgressView
android:id="@+id/good_progress_view1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
/>
<com.customview.view.GoodProgressView
android:id="@+id/good_progress_view2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
custom:backgroundColor="#ffcccccc"
custom:textColor="#ff000000"
android:padding="10dp"
/>
</RelativeLayout>Activity文件:一个使用默认渐变色效果,一个的渐变色使用随机颜色,这样每次运行效果不同,比较有趣一些,另外我们也可以从随机效果中找到比较好的颜色组合。进度的变化,是使用了一个定时器来推进。package
com.customview;
import
android.os.Bundle;
import
android.os.Handler;
import
android.os.Message;
import
android.util.Log;
import
android.view.WindowManager;
import
java.util.Random;
import
java.util.Timer;
import
java.util.TimerTask;
import
com.customview.view.GoodProgressView;
import
android.app.Activity;
import
android.graphics.Color;
public
class
MainActivity
extends
Activity
{
GoodProgressView
good_progress_view1;
GoodProgressView
good_progress_view2;
int
progressValue=0;
@Override
protected
void
onCreate(Bundle
savedInstanceState)
{
super.onCreate(savedInstanceState);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);//去掉信息栏
setContentView(R.layout.activity_main);
good_progress_view1
=
(GoodProgressView)findViewById(R.id.good_progress_view1);
good_progress_view2
=
(GoodProgressView)findViewById(R.id.good_progress_view2);
//第一个进度条使用默认进度颜色,第二个指定颜色(随机生成)
good_progress_view2.setColors(randomColors());
timer.schedule(task,
1000,
1000);
//
1s后执行task,经过1s再次执行
}
Handler
handler
=
new
Handler()
{
public
void
handleMessage(Message
msg)
{
if
(msg.what
==
1)
{
Log.i(
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 【地理】吉林省四平市梨树县2023-2024学年七年级上学期期末试卷(解析版)
- 加油站自查报告范文(5篇)
- 加油站安全事故反思
- 糖尿病患者的营养状况分析
- 农业进步:石榴病虫害防治防法
- 社区传染病防控:防疫志愿者培训
- 穴位埋线减肥25例疗效观察报告
- 秋季农场动物疫病防控
- 消毒设备升级:传染病防控设备创新
- 妊娠高血压孕期并发症预防与处理
- 社群运营知识考试复习题库(含答案)
- 变压器油检测标准
- 钻探施工现场安全规范
- 压力性损伤风险评估及预防措施
- 广东省省级政务信息化服务预算编制标准(运维服务分册)
- 物业保洁工作计划表
- 人行天桥防滑层伸缩缝施工方案范文
- 农业机械设备采购投标方案
- 食品输送机械设备分类(食品机械与设备课件)
- 小学毕业班语文教学课件文言文
- 1例心力衰竭合并下肢深静脉血栓患者的护理
评论
0/150
提交评论