android 心形进度条,心形进度条
废话不多说,先上效果图:
这个进度就是模拟心形填充的过程
实现原理是:首先将空心形图片绘制出来,然后根据进度大小再将实心的心形图片一部分一部分的绘制出来。也就是两张完全相同大小的空心图和圆心图重叠绘制,利用canvas的clipRect绘制实心部分,实现进度条效果。
首先在res->values先新建一个文件atrrs.xml,然后定义两个属性
max是最大进度值,progress是当前进度。
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.View;
import com.helen.funnyview.R;
/** * Created by Helen on 2015/5/14. */
public class HeartProgressBar extends View{
private Bitmap mHeartBitmap;//空心图片
private Bitmap mHeartedBitmap;//实心图
private Paint mPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
private int progress=0;//当前进度
private int max=100;//最大进度
private boolean isFinish=false;//是否填充完成
private boolean isAutoFill=false;//是否自动填充
public HeartProgressBar(Context context) {
super(context);
init();
}
public HeartProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
init();
TypedArray a=context.obtainStyledAttributes(attrs,R.styleable.HeartProgressBar);
progress=a.getInteger(R.styleable.HeartProgressBar_progress,0);
max=a.getInteger(R.styleable.HeartProgressBar_max,100);
if(max<=0){
max=100;
}
a.recycle();
}
public HeartProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init(){
if(mHeartBitmap==null){
mHeartBitmap=BitmapFactory.decodeResource(getResources(), R.mipmap.heart);
}
if(mHeartedBitmap==null){
mHeartedBitmap= BitmapFactory.decodeResource(getResources(), R.mipmap.hearted);
}
}
@Override
protected void onDraw(Canvas canvas) {
final int width=getWidth();//mHeartBitmap.getWidth();
final int height=getHeight();//mHeartBitmap.getHeight();
float percent=progress*1.0f/max;//进度百分比
if(percent>=1){
percent=1;
}
canvas.save();
//绘制空心图
canvas.drawBitmap(mHeartBitmap, 0, 0,mPaint);
//计算绘制实心图的范围
canvas.clipRect(0, height * (1 - percent), width, height);
//绘制实心图
canvas.drawBitmap(mHeartedBitmap, 0, 0, mPaint);
canvas.restore();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//int widthMode=MeasureSpec.getMode(widthMeasureSpec);
//if(widthMode==MeasureSpec.AT_MOST){//layout_width=wrap_content
//设置控件宽高跟图片一样
setMeasuredDimension(mHeartBitmap.getWidth(), mHeartBitmap.getHeight());
//}
//setMeasuredDimension(getMeasureSize(widthMeasureSpec, true), getMeasureSize(heightMeasureSpec, true));
}
private int getMeasureSize(int spec,boolean isWidth){
int size=MeasureSpec.getSize(spec);
int mode=MeasureSpec.getMode(spec);
if(mode==MeasureSpec.AT_MOST){
if(isWidth) {
size =mHeartBitmap.getWidth();
}else{
size=mHeartBitmap.getHeight();
}
}
return size;
}
/** * 设置当前进度 *@param progress */
public void setProgress(int progress) {
if(isAutoFill) return;
this.progress = progress;
if(!isFinish) {
invalidate();
}
if(progress>=max){
isFinish=true;
}
}
public int getProgress() {
return progress;
}
/** * 是否完成 *@return */
public boolean isFinish() {
return isFinish;
}
public boolean isAutoFill() {
return isAutoFill;
}
/** * 设置最大进度值 */
public void setMax(int max) {
this.max = max;
}
public int getMax() {
return max;
}
/** * 开启自动填充 */
public void startAutoFill(){
isAutoFill=true;
final int step=10;
final Handler handler=new Handler();
handler.post(new Runnable() {
@Override
public void run() {
progress += step;
invalidate();
if (progress >= max) {
isFinish = true;
}
if (!isFinish()) {
handler.postDelayed(this, 100 - progress);
} else {
handler.removeCallbacks(this);
}
}
});
}
}
然后就是使用它了。首先是布局文件:
设置了起始进度为50,最大进度为150
接着是activity内容:
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import com.helen.funnyview.R;
import com.helen.funnyview.view.HeartProgressBar;
/** * Created by Helen on 2015/5/14 16:56. * TODO */
public class HeartProgressBarActivity extends Activity{
private HeartProgressBar bar;
private Handler handler=new Handler();
private int progress=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_heart_progress_bar);
bar=(HeartProgressBar)findViewById(R.id.bar);
progress=bar.getProgress();
handler.postDelayed(new Runnable() {
@Override
public void run() {
progress+=5;
bar.setProgress(progress);
if(!bar.isFinish()) {
handler.postDelayed(this, 500);
}else{
handler.removeCallbacks(this);
}
}
},3000);
//bar.startAutoFill();
}
}
handler是模拟一个网络请求,进度加载的过程。这样就实现了开始那种效果了。
还有就是,该控件也可以用于类似于‘收藏’的功能,就是一开始没有收藏是空心的,点击收藏后就动态填充了心形,也就是上面注释掉的代码startAutoFill()方法。
需要源码的请戳这里
android 心形进度条,心形进度条相关推荐
- 程序员表白神器。安卓程序员表白软件。程序员追女友利器=android+雪花效果+彩色气泡+心形花园+心形玫瑰花+相爱天数计时器
程序员表白神器.安卓程序员表白软件.程序员追女友利器=android+雪花效果+彩色气泡+心形花园+心形玫瑰花 +相爱天数计时器. APK下载(把这个给女朋友,她一定会高兴的):http://down ...
- 精通Android自定义View(十二)绘制圆形进度条
1 绘图基础简析 1 精通Android自定义View(一)View的绘制流程简述 2 精通Android自定义View(二)View绘制三部曲 3 精通Android自定义View(三)View绘制 ...
- Android可触摸圆形进度条,Android 可滚动圆形进度条 滑块和进度在进度条上面跟着滚动...
Android 可滚动圆形进度条 滑块和进度在进度条上面跟着滚动.package com.example.test; import android.content.Context; import an ...
- android 动态进度条,Android实用view系列------炫酷的进度条
不知不觉距离上次写文章已经过去大半个月了,原本计划每周写一篇的想法在坚持几周之后最终还是被生活中各种各样的琐事打乱,无奈中夹杂这对自己的一点失望. 心痛.jpg 当初的愿望实现了吗 事到如今只好祭奠吗 ...
- Android BGradualProgress 多种渐变、直角or弧角、进度条、加载条
可实现多种渐变.直角or弧角.进度条.加载条 (Various gradient, right or arc angle, progress bar and loading bar can be re ...
- Android中的常用控件之进度条(ProgressBar)
ProgressBar的常用属性 style(进度条的样式,默认为圆形:用style="?android:attr/progressBarStyleHorizontal"可以将进度 ...
- Android自定义半圆进度条 半圆渐变色进度条带指示 半圆开口大小可自由修改
Android自定义半圆进度条 半圆渐变色进度条带指示 半圆开口大小可自由修改 首先我们来看下效果图 不同的开口大小只需要修改一个参数即可 半圆1: 半圆2: 半圆3: 如果是你想要的效果,就直接滑动 ...
- android 余额宝收益列表,Android 仿支付宝中的余额宝收益进度条
一. 看效果 二.上代码 package com.framework.widget; import android.app.Activity; import android.content.Conte ...
- android 余额宝,Android 仿支付宝中的余额宝收益进度条
一. 看效果 二.上代码 package com.framework.widget; import android.app.activity; import android.content.conte ...
- Android仿虾米音乐播放器之自定义进度条seekbar
先上图吧,仿照写的进度条 很明显不是系统的自带的进度条,所以我们需要自定义来实现这个效果,先看看官方给的例子 <layer-list xmlns:android="http://sch ...
最新文章
- 随机森林为何要有放回抽样
- spring应用实例
- 64 源码_【ClickHouse内核】源码阅读策略
- 计算机网络(十),HTTP的关键问题
- 用mysql制作一个登录_连接数据库制作一个简单的登入页面1
- 原生js--放大镜效果
- Http压力测试工具HttpTest4Net
- 模拟抖音推荐算法检测视频原创度
- c# 毕设计算机毕设
- 软件体系结构——面向对象风格
- C++语法学习笔记十四:派生类-调用顺序-访问等级-函数遮蔽
- icodelab 取走的弹珠(多组数据)
- Ubuntu 9.10 如何安装rais环境
- python学习之路遇到的问题以及解决方法
- 图像形成(5)球面透视投影和近似相机模型
- 原生JS仿写手机指南针(带水平仪)
- ACDREAM 05D 哗啦啦族的加法计算(DFS专场)
- 报错解决:expected START_TAG or END_TAG not TEXT (position: TEXT seen
- 天润云招股书“失效”:首次冲刺港股上市折戟,称全年业绩将下滑
- EtherCAT从设备输入输出实现