效果图
代码是这个人写的,致敬大佬
BaseType类
import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.PorterDuff; import java.util.Random; /** * Author: Melodyxxx * Email: [email protected] * Created at: 17/03/06. * Description: */ public abstract class BaseType implements DynamicWeatherView.WeatherType { private Context mContext; private int mWidth; private int mHeight; public Context getContext() { return mContext; } public int getWidth() { return mWidth; } public int getHeight() { return mHeight; } /** * 生成元素 */ public abstract void generate(); public BaseType(Context context, DynamicWeatherView dynamicWeatherView) { mContext = context; mWidth = dynamicWeatherView.getViewWidth(); mHeight = dynamicWeatherView.getViewHeight(); } @Override public void onSizeChanged(Context context, int w, int h) { mWidth = w; mHeight = h; // SurfaceView 的大小改变时需要根据宽高重新生成元素(例如雨滴) generate(); } /** * 清空画布 * * @param canvas */ protected void clearCanvas(Canvas canvas) { canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); } /** * 获取给定两数之间的一个随机数 * * @param min 最小值 * @param max 最大值 * @return 介于最大值和最小值之间的一个随机数 */ protected int getRandom(int min, int max) { if (max < min) { return 1; } return min + new Random().nextInt(max - min); } public int dp2px(float dpValue) { final float scale = mContext.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } }
DynamicWeatherView
import android.content.Context; import android.graphics.Canvas; import android.graphics.PixelFormat; import android.os.SystemClock; import android.util.AttributeSet; import android.view.SurfaceHolder; import android.view.SurfaceView; /** * Author: Melodyxxx * Email: [email protected] * Created at: 17/03/06. * Description: */ public class DynamicWeatherView extends SurfaceView implements SurfaceHolder.Callback { public interface WeatherType { void onDraw(Canvas canvas); void onSizeChanged(Context context, int w, int h); } private Context mContext; private DrawThread mDrawThread; private SurfaceHolder mHolder; private WeatherType mType; private int mViewWidth; private int mViewHeight; public void setType(WeatherType type) { mType = type; } public int getViewWidth() { return mViewWidth; } public int getViewHeight() { return mViewHeight; } public DynamicWeatherView(Context context) { this(context, null); } public DynamicWeatherView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public DynamicWeatherView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mContext = context; mHolder = getHolder(); mHolder.addCallback(this); mHolder.setFormat(PixelFormat.TRANSPARENT); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mViewWidth = w; mViewHeight = h; if (mType != null) { mType.onSizeChanged(mContext, w, h); } } @Override public void surfaceCreated(SurfaceHolder holder) { mDrawThread = new DrawThread(); mDrawThread.setRunning(true); mDrawThread.start(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { mDrawThread.setRunning(false); } /** * 绘制线程 */ private class DrawThread extends Thread { // 用来停止线程的标记 private boolean isRunning = false; public void setRunning(boolean running) { isRunning = running; } @Override public void run() { Canvas canvas; // 无限循环绘制 while (isRunning) { if (mType != null && mViewWidth != 0 && mViewHeight != 0) { canvas = mHolder.lockCanvas(); if (canvas != null) { mType.onDraw(canvas); if (isRunning) { mHolder.unlockCanvasAndPost(canvas); } else { // 停止线程 break; } // sleep SystemClock.sleep(1); } } } } } }
RainTypeImpl
import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.drawable.Drawable; import java.util.ArrayList; /** * Author: Melodyxxx * Email: [email protected] * Created at: 17/03/06. * Description: */ public class RainTypeImpl extends BaseType { // 背景 private Drawable mBackground; // 雨滴集合 private ArrayList<RainHolder> mRains; // 画笔 private Paint mPaint; public RainTypeImpl(Context context, DynamicWeatherView dynamicWeatherView) { super(context, dynamicWeatherView); init(); } private void init() { mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setColor(Color.WHITE); // 这里雨滴的宽度统一为3 mPaint.setStrokeWidth(3); mRains = new ArrayList<>(); } @Override public void generate() { mBackground = getContext().getResources().getDrawable(R.drawable.rain_sky_day); mBackground.setBounds(0, 0, getWidth(), getHeight()); for (int i = 0; i < 60; i++) { RainHolder rain = new RainHolder( getRandom(1, getWidth()), getRandom(1, getHeight()), getRandom(dp2px(9), dp2px(15)), getRandom(dp2px(5), dp2px(9)), getRandom(20, 100) ); mRains.add(rain); } } private RainHolder r; @Override public void onDraw(Canvas canvas) { clearCanvas(canvas); // 画背景 mBackground.draw(canvas); // 画出集合中的雨点 for (int i = 0; i < mRains.size(); i++) { r = mRains.get(i); mPaint.setAlpha(r.a); canvas.drawLine(r.x, r.y, r.x, r.y + r.l, mPaint); } // 将集合中的点按自己的速度偏移 for (int i = 0; i < mRains.size(); i++) { r = mRains.get(i); r.y += r.s; if (r.y > getHeight()) { r.y = -r.l; } } } private class RainHolder { /** * 雨点 x 轴坐标 */ int x; /** * 雨点 y 轴坐标 */ int y; /** * 雨点长度 */ int l; /** * 雨点移动速度 */ int s; /** * 雨点透明度 */ int a; public RainHolder(int x, int y, int l, int s, int a) { this.x = x; this.y = y; this.l = l; this.s = s; this.a = a; } } }
还有xml文件
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <gradient android:angle="270" android:endColor="@color/rain_sky_day_end" android:startColor="@color/rain_sky_day_start" /> </shape>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:angle="270"
android:endColor="@color/rain_sky_night_end"
android:startColor="@color/rain_sky_night_start" />
</shape>
用的话这样用
<cn.xrick.rain.DynamicWeatherView android:id="@+id/dynamic_weather_view" android:layout_width="match_parent" android:layout_height="match_parent"/>
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); DynamicWeatherView mDynamicWeatherView = (DynamicWeatherView) findViewById(R.id.dynamic_weather_view); mDynamicWeatherView.setType(new RainTypeImpl(this, mDynamicWeatherView)); } }
GitHub地址 下载前给star
标签:int,void,下雨,天气,private,public,import,Android,android From: https://www.cnblogs.com/Frank-dev-blog/p/16828324.html