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

Android粒子进度条

2015-12-10 22:37 260 查看
之前在哪里看见过一个H5迸溅粒子的进度条,觉得挺好玩的粗略研究了下它js的实现。今天试着用Android Canvas来实现看看效果,先上张图:




Demo的Git地址:https://github.com/qtstsq55/SparkPrograssBar.git
因为比较简单,大概写了下注释,不涉及触摸操作和其他组件。大体思路就是重载View的OnDraw方法而已,摘要下重点的部分。主Activity:


import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import com.example.sparkview.SparkController;
import com.example.sparkview.SparkPrograssBar;

public class MainActivity extends AppCompatActivity {

private SparkPrograssBar sparkPrograssbar;
private SparkController sparkController;
private Button btn_start,btn_end,btn_reset;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initEvents();
initSparkPrograssBar();
}

private void initView(){
btn_end = (Button) findViewById(R.id.btn_end);
btn_start = (Button) findViewById(R.id.btn_start);
btn_reset = (Button) findViewById(R.id.btn_reset);
sparkPrograssbar = (SparkPrograssBar) findViewById(R.id.sparkPrograssbar);
}

private void initEvents(){
btn_start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startPrograssBar(100);
}
});

btn_end.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stopPrograssBar();
}
});

btn_reset.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
resetPrograssBar();
}
});
}

private void initSparkPrograssBar(){
sparkController = new SparkController();
sparkController.setStartX(50);//组件左上角X坐标
sparkController.setStartY(45);//组件右上角坐标
sparkController.setStartColor(0f);//进度条初始颜色(红色),HSV颜色模式
sparkController.setEndColor(120f);//进度条结束颜色(绿色),HSV颜色模式
sparkController.setCurColor(sparkController.getStartColor());//进度条当前颜色,可有可无
sparkController.setWidth(620);//进度条宽度
sparkController.setHeight(10);//进度条高度
sparkController.setSpeed(1);//进度步长
sparkController.setDelay(30);//刷新频率
sparkController.setSparkCallBack(new SparkController.SparkCallBack() {
@Override
public void onStartPre() {
//开始前回调
}

@Override
public void onEnd() {
//结束后回调
}

@Override
public void onUpdate(float prograss) {
//更新回调
}
});
sparkPrograssbar.setSparkController(sparkController);
}

private void startPrograssBar(int prograss){
sparkPrograssbar.slidSprk(prograss);
}

private void stopPrograssBar(){
sparkPrograssbar.stopSlidSpak();
}

private void resetPrograssBar(){
sparkController.getSparks().clear();
sparkController.setCurPrograss(0);
startPrograssBar(100);
}

}


SparkPrograssBarView:

public class SparkPrograssBar extends View {

private SparkController sparkController;
private Paint paint;
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
if(msg.what == SparkController.INVALITE) {
sparkController.setCurPrograss(sparkController.getCurPrograss() + sparkController.getSpeed());
postInvalidate();
if (!sparkController.getSparks().isEmpty()) {
//30ms刷新一次
sendEmptyMessageDelayed(SparkController.INVALITE, sparkController.getDelay());
}
}
}
};

public SparkPrograssBar(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
paint.setAntiAlias(true);
paint.setDither(true);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if(sparkController == null) throw new IllegalStateException("SparkController can not null");
sparkController.setBorderWidth(getMeasuredWidth());
sparkController.setBorderHeight(getMeasuredHeight());
}

@Override
protected void onDraw(Canvas canvas) {
if(sparkController == null) throw new IllegalStateException("SparkController can not null");
paint.setStyle(Paint.Style.FILL);
float prograss = ((float) sparkController.getCurPrograss() / sparkController.getPrograss());
float currentX = sparkController.getStartX() + (prograss * sparkController.getWidth());
float currentY = sparkController.getStartY() + sparkController.getHeight();
paint.setColor(sparkController.createTopColor(prograss));
//进度条上半部分
canvas.drawRect(sparkController.getStartX(), sparkController.getStartY(), currentX, currentY - sparkController.getHeight() / 2, paint);
paint.setColor(sparkController.createBottomColor(prograss));
//进度条下半部分
canvas.drawRect(sparkController.getStartX(), currentY - sparkController.getHeight() / 2, currentX, currentY, paint);
if(sparkController.getCurPrograss() < sparkController.getPrograss()) {
//每次增加4个粒子
sparkController.createSparks(prograss);
}
//绘制所有粒子
for(int i = 0 ; i<sparkController.getSparks().size() ;i++){
Spark spark = sparkController.getSparks().get(i);
spark.setDepX(spark.getDepX() + (sparkController.rand(0f, 6f) - 3) / 100);
spark.setDepY(spark.getDepY() + 0.2f);
float sparkX = spark.getX() + spark.getDepX() / 2 + spark.getWeidth();
float sparkY = spark.getY() + 6 * spark.getDepY();
spark.setX(sparkX > currentX ? currentX - spark.getWeidth():sparkX);
spark.setY(sparkY);
if(spark.getY() > sparkController.getBorderHeight()){
sparkController.getSparks().remove(i);
}else{
paint.setColor(spark.createColor(sparkController));
canvas.drawRect(spark.getX(),spark.getY(),spark.getX() + spark.getWeidth(),spark.getY() + spark.getHeight(),paint);
}
}
if(sparkController.getSparks().isEmpty() && sparkController.getSparkCallBack() != null){
sparkController.getSparkCallBack().onEnd();
}
if(sparkController.getSparkCallBack() != null){
sparkController.getSparkCallBack().onUpdate(prograss);
}
}

public SparkController getSparkController() {
return sparkController;
}

public void setSparkController(SparkController sparkController) {
this.sparkController = sparkController;
}

public void slidSprk(int prograss) {
if(sparkController.getSparkCallBack() != null){
sparkController.getSparkCallBack().onStartPre();
}
sparkController.setPrograss(prograss);
invalidate();
mHandler.removeMessages(SparkController.INVALITE);
mHandler.sendEmptyMessage(SparkController.INVALITE);
}

public void stopSlidSpak(){
mHandler.removeMessages(SparkController.INVALITE);
if(sparkController.getSparkCallBack() != null){
sparkController.getSparkCallBack().onEnd();
}
}


控制一些重要参数的一个类:

public class SparkController {
public static final int INVALITE = 0x10;
private float startX,startY,width,height;
private int prograss,speed,delay = 50,maxPrograss = 100,curPrograss,borderWidth,borderHeight,createSparkNum = 8 ,sparkLift = 100;
private float startColor,endColor,curColor;
private List<Spark> sparks = new ArrayList<Spark>();
public interface SparkCallBack{
public void onStartPre();
public void onEnd();
public void onUpdate(float prograss);
}
private SparkCallBack sparkCallBack;

public int createTopColor(float prograss){
//进度条上部颜色
float hue = startColor + prograss * (endColor - startColor);
return  Color.HSVToColor(255,new float[]{hue,1f,1f});
}

public int createBottomColor(float prograss){
//进度条下部颜色,仅仅透明度区别
float hue = startColor + prograss * (endColor - startColor);
curColor = hue;
return  Color.HSVToColor(200, new float[]{hue, 1f, 1f});
}

public List<Spark> createSparks(float prograss){
//创建4个初始粒子
for(int i = 0; i<createSparkNum ; i++) {
sparks.add(createSpark(prograss));
}
return  sparks;
}

public Spark createSpark(float prograss){
//初始化粒子
Spark spark = new Spark();
spark.setX(getStartX() + prograss * getWidth() - rand(0f, 1f) * 10);
spark.setY(getStartY() + getHeight());
spark.setDepX((rand(0f, 4f) - 2) / 100);
spark.setDepY((rand(0f, getSparkLift()) - getSparkLift() * 2) / 100);
spark.setWeidth((int) (rand(1, 4) / 2));
spark.setHeight((int) (rand(1, 4) / 2));
spark.setHue(getCurColor());
return  spark;
}

public float rand(float a, float b){
double v = Math.random() * (b - a + 1) + a;
return Math.round(v);
}
}


最后是粒子的类Spark:

public class Spark {
private int weidth,height;//粒子的宽度与高度
private float hue,x,y,depX,depY;//粒子的HSV颜色和xy坐标与步长
}


代码都很简单,相信大家都能看懂。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息