Android 自定義view之雪花飄飄

先來無事研究了一下Android 自定義view的開發,簡單寫了一個雪花飄飄的效果:

效果如圖:


雪花飄飄場景

廢話不多說直接上代碼:

public class SnowViewextends View {

private PaintmyPaint;

? ? private int snowNum=100;

? ? private ListsnowBeans;

? ? private boolean isPlaying;

? ? public SnowView(Context context) {

super(context);

? ? ? ? init();

? ? }

public SnowView(Context context, @Nullable AttributeSet attrs) {

super(context, attrs);

? ? ? ? init();

? ? }

public SnowView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

? ? ? ? init();

? ? }

private void init() {

myPaint=new Paint(Paint.ANTI_ALIAS_FLAG);

? ? ? ? snowBeans=new ArrayList<>();

? ? ? ? isPlaying=true;

? ? }

@Override

? ? protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

? ? ? ? snowBeans.clear();

? ? ? ? for (int i=0;i

snowBeans.add(SnowBean.getBuildSnowBean(w,h));

? ? ? ? }

}

@Override

? ? protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

? ? ? ? for (int i=0;i

snowBeans.get(i).onDraw(canvas,myPaint);

? ? ? ? ? ? snowBeans.get(i).step();

? ? ? ? }

if(isPlaying){

postInvalidateDelayed(10);

? ? ? ? }

}

public void start(){

invalidate();

? ? ? ? isPlaying=true;

? ? }

public void stop(){

isPlaying=false;

? ? }

/**

? ? * 雪花對象

? ? */

? static? class SnowBean {

private int x;

? ? ? ? private int y;

? ? ? ? private int color;

? ? ? ? private int radius;

? ? ? ? private int rotation;

? ? ? ? private int speed;

? ? ? ? private int viewWdith;

? ? ? ? private int viewheight;

? ? ? ? private int stokeWidth;

? ? ? ? private PointstartPoint;

? ? ? ? private PointmiddlePoint;

? ? ? ? private PointendPoint;

? ? ? ? public int getStokeWidth() {

return stokeWidth;

? ? ? ? }

public void setStokeWidth(int stokeWidth) {

this.stokeWidth = stokeWidth;

? ? ? ? }

public PointgetStartPoint() {

return startPoint;

? ? ? ? }

public void setStartPoint(Point startPoint) {

this.startPoint = startPoint;

? ? ? ? }

public PointgetMiddlePoint() {

return middlePoint;

? ? ? ? }

public void setMiddlePoint(Point middlePoint) {

this.middlePoint = middlePoint;

? ? ? ? }

public PointgetEndPoint() {

return endPoint;

? ? ? ? }

public void setEndPoint(Point endPoint) {

this.endPoint = endPoint;

? ? ? ? }

public int getViewWdith() {

return viewWdith;

? ? ? ? }

public void setViewWdith(int viewWdith) {

this.viewWdith = viewWdith;

? ? ? ? }

public int getViewheight() {

return viewheight;

? ? ? ? }

public void setViewheight(int viewheight) {

this.viewheight = viewheight;

? ? ? ? }

public int getX() {

float t = getY() *1.0f / (getEndPoint().y - getStartPoint().y);

? ? ? ? ? ? return BezierUtil.calutePoint(t, getStartPoint(), getMiddlePoint(), getEndPoint()).x;

? ? ? ? }

public void setX(int x) {

this.x = x;

? ? ? ? }

public int getY() {

return y;

? ? ? ? }

public void setY(int y) {

this.y = y;

? ? ? ? }

public int getColor() {

return color;

? ? ? ? }

public void setColor(int color) {

this.color = color;

? ? ? ? }

public int getRadius() {

return radius;

? ? ? ? }

public void setRadius(int radius) {

this.radius = radius;

? ? ? ? }

public int getRotation() {

return rotation;

? ? ? ? }

public void setRotation(int rotation) {

this.rotation = rotation;

? ? ? ? }

public int getSpeed() {

return speed;

? ? ? ? }

public void setSpeed(int speed) {

this.speed = speed;

? ? ? ? }

public static SnowBeangetBuildSnowBean(int width, int height) {

SnowBean snowBean =new SnowBean();

? ? ? ? ? ? Random random =new Random();

? ? ? ? ? ? snowBean.setY(-random.nextInt(height));

? ? ? ? ? ? snowBean.setX(random.nextInt(width));

? ? ? ? ? ? snowBean.setColor(Color.WHITE);

? ? ? ? ? ? snowBean.setRadius(2+random.nextInt(20));

? ? ? ? ? ? snowBean.setRotation(random.nextInt(60));

? ? ? ? ? ? snowBean.setSpeed(2 +Math.abs(snowBean.getRadius()-20));

? ? ? ? ? ? snowBean.setViewheight(height);

? ? ? ? ? ? snowBean.setViewWdith(width);

? ? ? ? ? ? snowBean.setStartPoint(new Point(random.nextInt(width), -random.nextInt(height)));

? ? ? ? ? ? snowBean.setMiddlePoint(new Point(random.nextInt(width), random.nextInt(height)));

? ? ? ? ? ? snowBean.setEndPoint(new Point(random.nextInt(width), height + random.nextInt(height)));

? ? ? ? ? ? snowBean.setStokeWidth((int)(snowBean.getRadius()*0.2));

? ? ? ? ? ? snowBean.setRotation(random.nextInt(60));

? ? ? ? ? ? return snowBean;

? ? ? ? }

public void step() {

y +=speed;

? ? ? ? ? ? if (y >viewheight) {

y = -50;

? ? ? ? ? ? }

setRotation(getRotation()+1);

? ? ? ? }

public void onDraw(Canvas canvas, Paint paint) {

canvas.save();

? ? ? ? ? ? paint.setColor(getColor());

//? ? ? ? canvas.drawRect(getX() - getRadius(), getY() - getRadius(), getX() + getRadius(), getY() + getRadius(), paint);

? ? ? ? ? ? paint.setStyle(Paint.Style.STROKE);

? ? ? ? ? ? paint.setStrokeWidth(getStokeWidth());

? ? ? ? ? ? canvas.rotate(getRotation(),getX(),getY());

? ? ? ? ? ? for(int i=0;i<6;i++){

int lineStartX=getX();

? ? ? ? ? ? ? ? int lineEndX=getX()+radius;

? ? ? ? ? ? ? ? canvas.drawLine(lineStartX,getY(),lineEndX,getY(),paint);

? ? ? ? ? ? ? ? int line1Startx=(int)(getX()+getRadius()*0.5);

? ? ? ? ? ? ? ? int lint1Starty=getY();

? ? ? ? ? ? ? ? double degree60=Math.toRadians(60);

? ? ? ? ? ? ? ? int lint1Endx=(int)(line1Startx+radius*0.5*Math.cos(degree60));

? ? ? ? ? ? ? ? int lint1Endy=(int)(lint1Starty-radius*0.5*Math.cos(degree60));

? ? ? ? ? ? ? ? canvas.drawLine(line1Startx,lint1Starty,lint1Endx,lint1Endy,paint);

? ? ? ? ? ? ? ? int line2Startx = (int) (getX() + getRadius() *0.5);

? ? ? ? ? ? ? ? int lint2Starty = getY();

? ? ? ? ? ? ? ? int lint2Endx = (int) (line1Startx +radius *0.5 * Math.cos(degree60));

? ? ? ? ? ? ? ? int lint2Endy = (int) (lint1Starty +radius *0.5 * Math.cos(degree60));

? ? ? ? ? ? ? ? canvas.drawLine(line2Startx, lint2Starty, lint2Endx, lint2Endy, paint);

? ? ? ? ? ? ? ? canvas.rotate(60,getX(),getY());

? ? ? ? ? ? }

canvas.restore();

? ? ? ? }

}

}

其中用到了貝塞爾曲線算法,工具類公式:

public class BezierUtil {

public static PointcalutePoint(float t,Point p0,Point p1,Point p2){

Point point=new Point();

? ? ? ? float temp=1-t;

? ? ? ? point.x=(int)(temp*temp*p0.x+2*t*temp*p1.x+t*t*p2.x);

? ? ? ? point.y=(int)(temp*temp*p0.y+2*t*temp*p1.y+t*t*p2.y);

? ? ? ? return point;

? ? }

}

好了就是這些了,嘿嘿,還是挺好玩的,希望能夠幫到有需要的同學;

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容