这篇文章主要为大家详细介绍了Android自定义环形LoadingView效果的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
最近项目有要用到环形的进度条,Github上有一个类似的DashedCircularProgress控件,但是他画的进度是通过设置画笔的虚线效果来实现间隔的:progressPaint.setPathEffect(new DashPathEffect(new float[]{dashWith, dashSpace}, dashSpace));如果内层还有一层圆环,在动态设置时,内层和外层有细微的偏差.于是我在原有基础上改了一个,实现了我要的效果(设置进度时可以选择加动画或者不加动画):
控件实现:
这个控件继承RelativeLayout,在onDraw时做了两件事:
1、先画出底部的黑色环形;
2、按照当时的进度值画出对应比例的外层绿色环形.
对外提供一个接口,回调当前进度值:
public interface OnValueChangeListener {
void onValueChange(float value);
}
核心绘制类:
InternalCirclePainterImp2,绘制内层的黑色的环形:
/**
* @author Chuck
*/
public class InternalCirclePainterImp2 implements InternalCirclePainter {
private RectF internalCircle;//画出圆弧时,圆弧的外切矩形
private Paint internalCirclePaint;
private int color;
private float startAngle = 270f;
int arcQuantity=100;//等分(圆弧加间隔),比如arcQuantity=100时,表示将有100个圆弧,和100个空白间隔
float ratio=0.5f;//每段圆弧与圆弧加间隔之和的比例,ratio=0.5表示每个圆弧与相邻的间隔弧度比是1:1
private int width;
private int height;
private int internalStrokeWidth = 48;//圆环宽度
public InternalCirclePainterImp2(int color, int progressStrokeWidth, int arcQuantity,float ratio) {
this.color = color;
this.internalStrokeWidth = progressStrokeWidth;
this.arcQuantity = arcQuantity;
if(ratio>0&&ratio<1){
this.ratio = ratio;
}
init();
}
private void init() {
initExternalCirclePainter();
}
private void initExternalCirclePainter() {
internalCirclePaint = new Paint();
internalCirclePaint.setAntiAlias(true);
internalCirclePaint.setStrokeWidth(internalStrokeWidth);
internalCirclePaint.setColor(color);
internalCirclePaint.setStyle(Paint.Style.STROKE);
}
//圆弧外切矩形
private void initExternalCircle() {
internalCircle = new RectF();
float padding = internalStrokeWidth * 0.5f;
internalCircle.set(padding, padding , width - padding, height - padding);
initExternalCirclePainter();
}
@Override
public void draw(Canvas canvas) {
float eachAngle=360f/arcQuantity;
float eachArcAngle=eachAngle*ratio;
for(int i=0;i<arcQuantity*2;i++){
if(i%2==0){//遇到偶数就画圆弧,基数则跳过
canvas.drawArc(internalCircle, startAngle+eachAngle*i/2, eachArcAngle, false, internalCirclePaint);
}
else{
continue;
}
}
}
public void setColor(int color) {
this.color = color;
internalCirclePaint.setColor(color);
}
@Override
public int getColor() {
return color;
}
@Override
public void onSizeChanged(int height, int width) {
this.width = width;
this.height = height;
initExternalCircle();
}
}
ProgressPainterImp2,绘制内层的黑色的环形:
/**
* @author Chuck
*/
public class ProgressPainterImp2 implements ProgressPainter {
private RectF progressCircle;
private Paint progressPaint;
private int color = Color.RED;
private float startAngle = 270f;
private int internalStrokeWidth = 48;
private float min;
private float max;
private int width;
private int height;
private int currentPecent;//当前的百分比
int arcQuantity=100;//等分(圆弧加间隔),比如arcQuantity=100时,表示将有100个圆弧,和100个空白间隔
float ratio=0.5f;//每段圆弧与圆弧加间隔之和的比例,ratio=0.5表示每个圆弧与相邻的间隔弧度比是1:1
public ProgressPainterImp2(int color, float min, float max, int progressStrokeWidth, int arcQuantity,float ratio) {
this.color = color;
this.min = min;
this.max = max;
this.internalStrokeWidth = progressStrokeWidth;
this.arcQuantity = arcQuantity;
this.ratio = ratio;
init();
Log.e(ProgressPainterImp,构造函数执行);
}
private void init() {
initInternalCirclePainter();
}
private void initInternalCirclePainter() {
progressPaint = new Paint();
progressPaint.setAntiAlias(true);
progressPaint.setStrokeWidth(internalStrokeWidth);
progressPaint.setColor(color);
progressPaint.setStyle(Paint.Style.STROKE);
}
//初始化外切的那个矩形
private void initInternalCircle() {
progressCircle = new RectF();
float padding = internalStrokeWidth * 0.5f;
progressCircle.set(padding, padding , width - padding, height - padding);
initInternalCirclePainter();
}
@Override
public void draw(Canvas canvas) {
float eachAngle=360f/arcQuantity;
float eachArcAngle=eachAngle*ratio;
int quantity=2*arcQuantity*currentPecent/100;
for(int i=0;i<quantity;i++){
if(i%2==0){//遇到偶数就画圆弧,基数则跳过
canvas.drawArc(progressCircle, startAngle+eachAngle*i/2, eachArcAngle, false, progressPaint);
}
else{
continue;
}
}
}
public float getMin() {
return min;
}
public void setMin(float min) {
this.min = min;
}
public float getMax() {
return max;
}
public void setMax(float max) {
this.max = max;
}
public void setValue(float value) {
this.currentPecent = (int) (( 100f * value) / max);
}
@Override
public void onSizeChanged(int height, int width) {
Log.e(ProgressPainterImp,onSizeChanged执行);
this.width = width;
this.height = height;
initInternalCircle();
}
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
progressPaint.setColor(color);
}
}
可以自定义的属性:
<declare-styleable name=CircularLoadingView> <attr name=base_color format=color /> <!--内层圆环的颜色--> <attr name=progress_color format=color /><!--进度圆环的颜色--> <attr name=max format=float /><!--最小值--> <attr name=min format=float /><!--最大值--> <attr name=duration format=integer /><!--动画时长--> <attr name=progress_stroke_width format=integer /><!--圆环宽度--> <!--等分(圆弧加间隔),比如arcQuantity=100时,表示将有100个圆弧,和100个空白间隔--> <attr name=argQuantity format=integer /> <!--每段圆弧与圆弧加间隔之和的比例,ratio=0.5表示每个圆弧与相邻的间隔弧度比是1:1--> <attr name=ratio format=float /> </declare-styleable>
调用:
main_activity.xml:
<?xml version=1.0 encoding=utf-8?>
<RelativeLayout
xmlns:android=http://schemas.android.com/apk/res/android
android:layout_width=match_parent
android:layout_height=match_parent
android:paddingBottom=@dimen/activity_vertical_margin
android:paddingLeft=@dimen/activity_horizontal_margin
android:paddingRight=@dimen/activity_horizontal_margin
android:paddingTop=@dimen/activity_vertical_margin
xmlns:custom=http://schemas.android.com/apk/res-auto
android:background=#ffffff
>
<!--自定义控件,继承RelativeLayout-->
<qdong.com.mylibrary.CircularLoadingView
android:id=@+id/simple
custom:base_color=@color/pager_bg
custom:min=0
custom:max=100
custom:argQuantity=100
custom:ratio=0.6
custom:progress_color=@android:color/holo_green_light
custom:progress_icon=@mipmap/ic_launcher
custom:duration=1000
custom:progress_stroke_width=28
android:layout_centerInParent=true
android:layout_width=200dp
android:layout_height=200dp>
<RelativeLayout
android:layout_centerInParent=true
android:layout_width=match_parent
android:layout_height=match_parent>
<TextView
android:layout_centerInParent=true
android:textSize=20sp
android:layout_centerHorizontal=true
android:id=@+id/number
android:text=0
android:gravity=center
android:textColor=@color/pager_bg
android:layout_width=wrap_content
android:layout_height=wrap_content />
</RelativeLayout>
</qdong.com.mylibrary.CircularLoadingView>
<Button
android:layout_width=wrap_content
android:layout_height=wrap_content
android:text=Set_Value
android:id=@+id/button
android:layout_alignParentBottom=true
android:layout_alignParentStart=true/>
<Button
android:layout_width=wrap_content
android:layout_height=wrap_content
android:text=Animation
android:id=@+id/button3
android:layout_alignTop=@+id/button
android:layout_alignParentEnd=true/>
</RelativeLayout>
MainActivity:
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
mDashedCircularProgress.setValue(66);//没有动画的,直接设置
} catch (Exception e) {
e.printStackTrace();
}
}
});
findViewById(R.id.button3).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
mDashedCircularProgress.setValue(0);//无动画,归零
mDashedCircularProgress.setValueWithAnimation(100,2000);//带动画
} catch (Exception e) {
e.printStackTrace();
}
}
});
Github地址:https://github.com/506954774/AndroidCircularLoadingView
以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!
相关推荐:
jQuery实现的AJAX简单弹出层效果
jQuery的ajax下载blob文件的方法
以上就是Android自定义环形LoadingView效果的详细内容,更多请关注双恒网络其它相关文章!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
8. 精力有限,不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别
9.本站默认解压密码为:www.sudo1.com
本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。
不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。
本站信息来自网络收集整理,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。
如果您喜欢该程序和内容,请支持正版,购买注册,得到更好的正版服务。
我们非常重视版权问题,如有侵权请邮件与我们联系处理。敬请谅解!
云资源网 » Android自定义环形LoadingView效果
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 你们有qq群吗怎么加入?