Android实战简易教程-第六十九枪(自定义控件实现雪花飘落效果)

现在APP要求越来越高了,不只是要求实现功能,颜值的要求也越来越高,下面我们通过自定义控件来实现雪花飘落的效果,可以作为界面背景哦。

1.自定义控件:

package com.test.a;

import java.util.Random;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.view.View;

public class FlowerView extends View {

	Bitmap mFlowers = null;
	MyFlower flowers [] = new MyFlower[50];//50片雪花
	private Integer[] offsetX ;
	private Integer[] offsetY ;
	Random r = new Random();
	Matrix m = new Matrix();
	Paint p = new Paint();

	int mW = 480;
	int mH = 800;
	float de = 0f;

	public void setWH(int pW, int pH, float de){
		this.mW = pW;
		this.mH = pH;
		this.de = de;
		System.out.println("de ---->" + de);
		offsetX = new Integer[]{(int)(2*de), (int)(-2*de), (int)(-1*de), 0, (int)(1*de), (int)(2*de), (int)(1*de)};
		offsetY = new Integer[]{(int)(3*de), (int)(5*de), (int)(5*de), (int)(3*de), (int)(4*de)};
	}

	public FlowerView(Context context) {
		super(context);
	}

	public FlowerView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	public FlowerView(Context context, AttributeSet attrs) {
		super(context, attrs);

	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		for (int i = 0; i < flowers.length; i++) {
			MyFlower rect = flowers[i];
			int t = rect.t;
			t--;
			if (t <= 0) {
				rect.y += rect.g;
				canvas.save();
				m.reset();
				m.setScale(rect.s, rect.s);
				canvas.setMatrix(m);
				p.setAlpha(rect.a);
				canvas.drawBitmap(mFlowers, rect.x, rect.y, p);
				canvas.restore();
			}
			rect.t = t;
			if (rect.y >= mH) {
				rect.init();
			}
			if (rect.x >= mW || rect.x < - 20) {
				rect.init();
			}
			flowers[i] = rect;
		}
	}

	public void loadFlower(){
		Resources r = this.getContext().getResources();
		mFlowers = ((BitmapDrawable)r.getDrawable(R.drawable.snow)).getBitmap();
	}

	public void recly(){
		if (mFlowers != null && !mFlowers.isRecycled()) {
			mFlowers.recycle();
		}
	}

	public void addRect(){
		for (int i = 0; i < flowers.length; i++) {
			flowers[i] = new MyFlower();
		}
	}

	public void inva(){
		invalidate();
	}

	class MyFlower{
		int x;
		int y;
		float s;
		int a;
		int t;
		int g;

		public void init(){
			float aa = r.nextFloat();
			this.x = r.nextInt(mW - 80) + 80;
			this.y = 0;
			if (aa >= 1) {
				this.s = 1.1f;
			}else if (aa <= 0.2) {
				this.s = 0.4f;
			}else{
				this.s = aa;
			}
			this.a = r.nextInt(155) + 100;
			this.t = r.nextInt(105) + 1;
			this.g = offsetY[r.nextInt(4)];
		}

		public MyFlower(){
			super();
			init();
		}		

	}

}

2.布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <com.test.a.FlowerView
        android:id="@+id/flowerview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </com.test.a.FlowerView>

</LinearLayout>

3.java:

package com.test.a;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.DisplayMetrics;

public class MainActivity extends Activity {
	/** Called when the activity is first created. */
	private FlowerView mFlowerView;
	// 屏幕宽度
	public static int screenWidth;
	// 屏幕高度
	public static int screenHeight;
	Timer myTimer = null;
	TimerTask mTask = null;
	private static final int SNOW_BLOCK = 1;
	private Handler mHandler = new Handler() {
		public void dispatchMessage(Message msg) {
			mFlowerView.inva();
		};
	};

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		mFlowerView = (FlowerView) findViewById(R.id.flowerview);
		screenWidth = getWindow().getWindowManager().getDefaultDisplay()
				.getWidth();//获取屏幕宽度
		screenHeight = getWindow().getWindowManager().getDefaultDisplay()
				.getHeight();//获取屏幕高度

		DisplayMetrics dis = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(dis);
		float de = dis.density;
		mFlowerView.setWH(screenWidth, screenHeight, de);
		mFlowerView.loadFlower();
		mFlowerView.addRect();

		myTimer = new Timer();
		mTask = new TimerTask() {
			@Override
			public void run() {
				Message msg = new Message();
				msg.what = SNOW_BLOCK;
				mHandler.sendMessage(msg);
			}
		};
		myTimer.schedule(mTask, 3000, 10);
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		mFlowerView.recly();
	}
}

运行实例如下:

喜欢的朋友请关注我!

源码下载

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-12 00:39:59

Android实战简易教程-第六十九枪(自定义控件实现雪花飘落效果)的相关文章

Android实战简易教程-第三十九枪(第三方短信验证平台Mob和验证码自动填入功能结合实例)

用户注册或者找回密码时一般会用到短信验证功能,这里我们使用第三方的短信平台进行验证实例. 我们用到第三方短信验证平台是Mob,地址为:http://mob.com/ 一.注册用户.获取SDK 大家可以自行注册,得到APPKEY和APPSECRET,然后下载SDK,包的导入方式如截图: 二.主要代码 SMSSendForRegisterActivity.java:(获取验证码页) package com.qiandaobao.activity; import java.util.regex.Mat

Android实战简易教程-第四十九枪(两种方式实现网络图片异步加载)

加载图片属于比较耗时的工作,我们需要异步进行加载,异步加载有两种方式:1.通过AsyncTask类进行:2.通过Handler来实现,下面我们就来看一下如何通过这两种方式实现网络图片的异步加载. 一.AsyncTask方式 1.main.xml: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.co

Android实战简易教程-第五十九枪(EventBus小实例-传值、控制其他页控件显示)

页面之间的传值,有android基础的童鞋都会知道,可以通过Intent进行传值,但是动态控制另一个页面控件的显示恐怕这个就不好用了吧,下面我们介绍一个比较好用的框架-EventBus,通过实例介绍它的使用(要引入jar包才能使用EventBus,jar包在源码下载中). 一.介绍一下EventBus 使用EventBus的步骤: 1.新建一个类:作为消息类 /** * */ package com.example.eventbusdemo; /** * @author yayun * @sin

Android实战简易教程-第六十八枪(android小工具appwidget之时间显示)

Android AppWidget开发不同于普通的android应用,因为AppWidget是运行在别的进程中的程序.其使用RemoteViews更新UI.一旦系统发生变更,很容易引起AppWidget的更新.其支持的组件有限,事件类型也很少.所以一般用于更新周期较长,事件比较简单的用于桌面显示的组件.其开发流程相对来说还是比较简单的.大致分为: 1:编写布局文件 <?xml version="1.0" encoding="utf-8"?> <Te

Android实战简易教程-第四十八枪(App引导页面效果实现)

经常使用APP的童鞋会发现,第一次进入APP会有引导页面,里面可以放一些APP的使用介绍或其他信息等等,下面我们研究一下如何实现这个功能,增加APP的体验. 一.自定义控件继承ViewGroup: package com.genius.scroll; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.util

Android实战简易教程-第五十五枪(窃听风云之电话录音上传)

前一段时间我写过一篇关于短信监听的文章Android实战简易教程-第四十枪(窃听风云之短信监听),话说现在短信用的越来越少了啊,下面来个更猛的,电话录音监听上传,电话接通后开始录音,电话挂断后将录音上传.这里我们还是借助Bmob提供的上传服务,将录音文件上传到bomb的服务器,可以自行下载,播放录音. 一.配置bmob 配置bmob服务很是简单,注册账号,下载jar包,将jar包引入libs文件目录下: 然后配置权限: <uses-permission android:name="andr

Android实战简易教程-第六十六枪(结合SharedPreferenced实现自动登录功能)

我们使用的一般应用都有记住密码.自动登录功能,这样不用用户每次都要点击登录按钮,提升用户体验,下面我们通过一个实例研究一下如何通过android的sharedpreferenced实现自动登录功能.本实例有三个界面-登录界面,跳转界面,登录成功界面. 1.登录界面: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.andr

Android实战简易教程-第六十一枪(圆形显示的ImageView)

ImageView在我们的项目中经常使用,一般ImageView是正方形的,要使用圆形的ImageView可以通过自定义View来实现,下面我们介绍一下如何实现. 1.CircularImageView.java 继承自ImageView: package com.yayun.circularimageview; import com.mikhaellopez.circularimageview.R; import android.content.Context; import android.

Android实战简易教程-第六十四枪(Android APP 引导页实现-第一次应用进入时加载)

APP引导页是每个优质APP必备的元素,下面我们研究一下如何只在第一次进入应用时进行加载引导页的方法. 1.判断是否第一次进入应用的方法: package com.yayun.guide; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bun