先來無事研究了一下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;
? ? }
}
好了就是這些了,嘿嘿,還是挺好玩的,希望能夠幫到有需要的同學;