自定义View(进度条)
继承View重写带两个参数的构造方法,一个参数的不行不会加载视图,构造方法中初始化画笔这样不用没次刷新都要初始化浪费内存,在ondraw方法中绘图,invalidate方法会掉用ondraw方法重新绘制.在attrs中声明你将要设置的属性,名字要和自定义类名一样,在布局文件中引用属性,随便输入属性名然后alt+enter自动生成命名空间,就可以引用自定义属性了.最后在主activity中调用接口,使用传来的参数current
public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final CircleProgressView myView = findViewById(R.id.circle);
ValueAnimator animator = ValueAnimator.ofFloat(0, 100);
animator.setDuration(4000);
animator.setInterpolator(new LinearInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float current = (float) animation.getAnimatedValue();
myView.setmCurrent((int) current);
}
});
animator.start();
myView.setOnLoadingCompleteListener(new CircleProgressView.OnLoadingCompleteListener() {
@Override
public void complete(int current) {
System.out.println(current);
if (current == 100) {
myView.setVisibility(View.GONE);
Toast.makeText(MainActivity.this, "加载完成", Toast.LENGTH_SHORT).show();
}
}
});
}
}
主activity
public class CircleProgressView extends View {
private int mCurrent;//当前进度
private Paint mPaintOut;
private Paint mPaintCurrent;
private Paint mPaintText;
private float mPaintWidth;//画笔宽度
private int mPaintColor = Color.RED;//画笔颜色
private int mTextColor = Color.BLACK;//字体颜色
private float mTextSize;//字体大小
private int location;//从哪个位置开始
private float startAngle;//开始角度
public CircleProgressView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressView);
location = array.getInt(R.styleable.CircleProgressView_location, 1);
mPaintWidth = array.getDimension(R.styleable.CircleProgressView_progress_paint_width, dip2px(context,4));//默认4dp
mPaintColor = array.getColor(R.styleable.CircleProgressView_progress_paint_color, mPaintColor);
mTextSize = array.getDimension(R.styleable.CircleProgressView_progress_text_size, dip2px(context,18));//默认18sp
mTextColor = array.getColor(R.styleable.CircleProgressView_progress_text_color, mTextColor);
array.recycle();
//画笔->背景圆弧
mPaintOut = new Paint();
mPaintOut.setAntiAlias(true);
mPaintOut.setStrokeWidth(mPaintWidth);
mPaintOut.setStyle(Paint.Style.STROKE);
mPaintOut.setColor(Color.GRAY);
mPaintOut.setStrokeCap(Paint.Cap.ROUND);
//画笔->进度圆弧
mPaintCurrent = new Paint();
mPaintCurrent.setAntiAlias(true);
mPaintCurrent.setStrokeWidth(mPaintWidth);
mPaintCurrent.setStyle(Paint.Style.STROKE);
mPaintCurrent.setColor(mPaintColor);
mPaintCurrent.setStrokeCap(Paint.Cap.ROUND);
//画笔->绘制字体
mPaintText = new Paint();
mPaintText.setAntiAlias(true);
mPaintText.setStyle(Paint.Style.FILL);
mPaintText.setColor(mTextColor);
mPaintText.setTextSize(mTextSize);
if (location == 1) {//默认从左侧开始
startAngle = -180;
} else if (location == 2) {
startAngle = -90;
} else if (location == 3) {
startAngle = 0;
} else if (location == 4) {
startAngle = 90;
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
RectF rectF = new RectF(mPaintWidth / 2, mPaintWidth / 2, getWidth() - mPaintWidth / 2, getHeight() - mPaintWidth / 2);
canvas.drawArc(rectF, 0, 360, false, mPaintOut);
//绘制当前进度
float sweepAngle = 360 * mCurrent / 100;
canvas.drawArc(rectF, startAngle, sweepAngle, false, mPaintCurrent);
//绘制进度数字
String text = mCurrent + "%";
//获取文字宽度
float textWidth = mPaintText.measureText(text, 0, text.length());
float dx = getWidth() / 2 - textWidth / 2;
Paint.FontMetricsInt fontMetricsInt = mPaintText.getFontMetricsInt();
float dy = (fontMetricsInt.bottom - fontMetricsInt.top) / 2 - fontMetricsInt.bottom;
float baseLine = getHeight() / 2 + dy;
canvas.drawText(text, dx, baseLine, mPaintText);
if (mLoadingCompleteListener != null ) {
mLoadingCompleteListener.complete(mCurrent);
}
}
public void setmCurrent(int mCurrent) {
this.mCurrent = mCurrent;
invalidate();
}
public interface OnLoadingCompleteListener {
void complete(int current);
}
//暴露回调方法
public void setOnLoadingCompleteListener(OnLoadingCompleteListener loadingCompleteListener) {
this.mLoadingCompleteListener = loadingCompleteListener;
}
//监听
/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
*/
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
private OnLoadingCompleteListener mLoadingCompleteListener;
}
自定义view
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
xmlns:myview="http://schemas.android.com/apk/res-auto"
android:id="@+id/line1"
android:orientation="vertical"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.january.summer.CircleProgressView
android:id="@+id/circle"
android:layout_width="50dp"
myview:location="left"
android:layout_gravity="center"
android:layout_height="50dp" /> </LinearLayout>
布局文件
<resources>
<declare-styleable name="CircleProgressView">//要跟类名一样
<!--画笔宽度-->
<attr name="progress_paint_width" format="dimension" />
<!--画笔颜色-->
<attr name="progress_paint_color" format="color" />
<!--字体颜色-->
<attr name="progress_text_color" format="color" />
<!--字体尺寸-->
<attr name="progress_text_size" format="dimension" />
<!--加载进度的开始位置-->
<attr name="location" format="enum">
<enum name="left" value="1" />
<enum name="top" value="2" />
<enum name="right" value="3" />
<enum name="bottom" value="4" />
</attr>
</declare-styleable>
</resources>
attrs文件,注意,demension属性使用时自动把dp转为px
自定义View(进度条)的更多相关文章
- android新闻项目、饮食助手、下拉刷新、自定义View进度条、ReactNative阅读器等源码
Android精选源码 Android仿照36Kr官方新闻项目课程源码 一个优雅美观的下拉刷新布局,众多样式可选 安卓版本的VegaScroll滚动布局 android物流详情的弹框 健身饮食记录助手 ...
- 自定义环形进度条RoundProgressBar
一.效果图: Canvas画圆环说明: 圆环宽度不必在意,只是画笔宽度设置后达到的效果. 二.实现步骤 1.自定义View-RoundProgressBar 2.设置属性resources(decle ...
- Android 自定义水平进度条的圆角进度
有时项目中需要实现水平圆角进度,如下两种,其实很简单 下面开始看代码,先从主界面布局开始看起: <?xml version="1.0" encoding=" ...
- Android开发 View_自定义圆环进度条View
前言 一个实现,空心圆环的自定义View,已经封装完好,可以直接使用. 效果图 代码 import android.content.Context; import android.graphics.C ...
- 自定义带进度条的WebView , 增加获取web标题和url 回掉
1.自定义ProgressWebView package com.app.android05; import android.content.Context; import android.graph ...
- 【Android 应用开发】 自定义 圆形进度条 组件
转载著名出处 : http://blog.csdn.net/shulianghan/article/details/40351487 代码下载 : -- CSDN 下载地址 : http://down ...
- ProgressBar学习笔记,自定义横向进度条的样式(包含ActionBar上面的进度条)
点显示进度条后→ android:max="100" 进度条的最大值 android:progress 进度条已经完成的进度值 android:progressDrawab ...
- iOS开发:代码通用性以及其规范 第一篇(附带,自定义UITextView\进度条\双表显示\瀑布流 代码设计思路)
在iOS团队开发中,我见过一些人的代码,也修改过他们的代码.有的人的代码写的非常之规范.通用,几乎不用交流,就可以知道如何修改以及在它基础上扩展延生.有的人的代码写的很垃圾,一眼看过去,简直会怀疑自己 ...
- Android -- 自定义带进度条的按钮
1. 实现了一个带进度条的按钮,完成后显示提示信息,并设置按钮为不可再次被点击
随机推荐
- 11.深入k8s:kubelet工作原理及源码分析
转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 源码版本是1.19 kubelet信息量是很大的,通过我这一篇文章肯定是讲不全的,大家可 ...
- Java List 常用集合 ArrayList、LinkedList、Vector
Java 中的 List 是非常常用的数据类型.List 是有序的 Collection,Java List 一共有三个实现类,分别是:ArrayList.Vector.LinkedList 本文分析 ...
- Kubernetes客户端和管理界面大集合
今天给大家介绍目前市面上常用的kubernetes管理工具,总有一款适合您~~~ 简介 Kubectl K9s Kubernetes-Dashboard Rancher Kuboard Lens Oc ...
- is_mobile()判断手机移动设备
is_mobile()判断手机移动设备.md is_mobile()判断手机移动设备 制作响应式主题时会根据不同的设备推送不同的内容,是基于移动设备网络带宽压力,避免全局接收pc端内容. functi ...
- 从零搭建Golang开发环境--go修仙序章
1. 什么是go语言 Go(又称 Golang)是 Google 的 Robert Griesemer,Rob Pike 及 Ken Thompson 开发的一种静态 .强类型.编译型语言 .Go 语 ...
- 019 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 13 数据类型转换的代码示例
019 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 13 数据类型转换的代码示例 本文知识点:Java中的数据类型转换案例 学习视频有误,导致没法写文,文章内容 ...
- Java知识系统回顾整理01基础02面向对象02属性
一.根据实例给出"属性"的定义 一个英雄有姓名,血量,护甲等等状态 这些状态就叫做一个类的属性 二.属性的类型 属性的类型可以是基本类型,比如int整数,float 浮点数 也可以 ...
- Open CV leaning
刚接触Open CV 几个比较好的介绍: OpenCV学习笔记:https://blog.csdn.net/yang_xian521/column/info/opencv-manual/3 OpenC ...
- 【题解】NOIP2018 赛道修建
题目戳我 \(\text{Solution:}\) 根据题目信息简化题意,是让你在树上找出\(m\)条路径使得路径长度最小值最大. 看到题第一感先二分一个答案,问题转化为如何选择一些路径使得它们最小值 ...
- STM32之旅3——时钟数
STM32之旅3--时钟数 STM32F1是M3内核,它的时钟数很庞大,让一个初学者去看,估计会很吃力,和我们入门的8051单片机的时钟不同,这里又倍频.又分频,而且还分成好多个时钟,不同的外设时钟不 ...