Android自定义View实现雪花特效

本文实例为大家分享了Android自定义View实现雪花特效展示的具体代码,供大家参考,具体内容如下

效果图

1.SnowView 类

package com.ilz.rocketapplication.handaccount.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.widget.RelativeLayout;

import com.ilz.rocketapplication.handaccount.R;
import com.ilz.rocketapplication.handaccount.bean.SnowBean;
import com.ilz.rocketapplication.handaccount.utils.ColorUtils;
import com.ilz.rocketapplication.handaccount.utils.Tools;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

public class SnowView extends RelativeLayout {
// private final String SNOW = "❄";
// private final String SNOW = "☀❆★❉❈❀✿❃❁";
 private final String SNOW = "❄";
 private float vX = 2.5f;//风向 >0 右边飘 <0 左边飘
 private float vY = 5f;//下落速度 <0你的雪花要往上飘呀
 private int snowCount = 50;//雪花个数
 private List<SnowBean> snowBeanList = new ArrayList<>();

 private int XB = Tools.getWindowsWidth();
 private int YB = Tools.getWindowsHeight();

 private Paint paint = new Paint();
 private Timer timer;

 private boolean isStart = false;

 public SnowView(Context context) {
  this(context, null);
 }

 public SnowView(Context context, AttributeSet attrs) {
  this(context, attrs, 0);
 }

 public SnowView(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  initView();
 }

 private void initView() {
  paint.setAntiAlias(true);
  initSnowData();
 }

 public void start() {
  if (timer == null) {
   timer = new Timer();
  }
  isStart = true;
  timer.schedule(new TimerTask() {
   @Override
   public void run() {

    if (!isStart) return;
    for (int i = 0; i < snowBeanList.size(); i++) {

     snowBeanList.get(i).setX(snowBeanList.get(i).getX() + vX);
     snowBeanList.get(i).setY(snowBeanList.get(i).getY() + vY);

     if (snowBeanList.get(i).getX() < 0 || snowBeanList.get(i).getX() > XB) {
      snowBeanList.get(i).setX(getRandomX());
     }
     if (snowBeanList.get(i).getY() < 0 || snowBeanList.get(i).getY() > YB) {
      snowBeanList.get(i).setY(0f);
     }
    }

    postInvalidate();
   }
  }, 0, 15);
 }

 public void resume() {
  if (timer == null) {
   start();
  }
  isStart = true;
 }

 public void pause(){
  isStart = false;
 }

 public void destroy() {
  isStart = false;
  if (snowBeanList != null) {
   snowBeanList.clear();
  }
  invalidate();
  if (timer != null) {
   timer.cancel();
   timer = null;
  }
 }

 private void initSnowData() {
  for (int i = 0; i < snowCount; i++) {
   SnowBean bean = new SnowBean();
   bean.setX(getRandomX());
   bean.setY(getRandomY());
   bean.setSize((float) (Math.random() * 50) + 5);
   snowBeanList.add(bean);
  }
 }

 private float getRandomX() {
  return (float) (Math.random() * Tools.getWindowsWidth());
 }

 private float getRandomY() {
  return (float) (Math.random() * Tools.getWindowsHeight());
 }

 @Override
 protected void onLayout(boolean changed, int l, int t, int r, int b) {
  super.onLayout(changed, l, t, r, b);
 }

 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  for (int i = 0; i < snowBeanList.size(); i++) {
   SnowBean bean = snowBeanList.get(i);
   paint.setTextSize(bean.getSize());
   paint.setColor(bean.getColor());
   canvas.drawText(SNOW, bean.getX(), bean.getY(), paint);
  }
 }

 private GestureDetector detector = new GestureDetector(getContext(),new MyGestureDetector());
 private boolean isPoint = false;
 private long pointTime = 0;
 @Override
 public boolean onTouchEvent(MotionEvent event) {
//  switch (event.getAction()) {
//   case MotionEvent.ACTION_DOWN:
//    pointTime = 0;
//    int pCount = event.getPointerCount();
//    if (pCount >= 2) {
//     isPoint = true;
//     pointTime = System.currentTimeMillis();
//    }
//    break;
//   case MotionEvent.ACTION_MOVE:
//    break;
//   case MotionEvent.ACTION_UP:
//    isPoint = false;
//    pointTime = 0;
//    break;
//  }

//  return super.onTouchEvent(event);
  return detector.onTouchEvent(event);
 }

 private class MyGestureDetector implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener {

  @Override
  public boolean onDown(MotionEvent e) {
   return false;
  }

  @Override
  public void onShowPress(MotionEvent e) {

  }

  @Override
  public boolean onSingleTapUp(MotionEvent e) {
   return false;
  }

  @Override
  public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
   return false;
  }

  @Override
  public void onLongPress(MotionEvent e) {

  }

  @Override
  public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
   return false;
  }

  @Override
  public boolean onSingleTapConfirmed(MotionEvent e) {
   return false;
  }

  @Override
  public boolean onDoubleTap(MotionEvent e) {
   return false;
  }

  @Override
  public boolean onDoubleTapEvent(MotionEvent e) {
   return false;
  }
 }
}

2.SnowBean

package com.ilz.rocketapplication.handaccount.bean;

import android.graphics.Color;

import com.ilz.rocketapplication.handaccount.utils.ColorUtils;

public class SnowBean {
 float x;
 float y;
 float size;
 int color = Color.WHITE;

 public float getX() {
  return x;
 }

 public void setX(float x) {
  this.x = x;
 }

 public float getY() {
  return y;
 }

 public void setY(float y) {
  this.y = y;
 }

 public float getSize() {
  return size;
 }

 public void setSize(float size) {
  this.size = size;
 }

 public int getColor() {
  return color;
 }

 public void setColor(int color) {
  this.color = color;
 }
}

3.Tools

/**
  * 获取屏幕的宽度
*/
 public static int getWindowsWidth() {
  WindowManager wm = (WindowManager) (MyApplication.getInstance().getSystemService(Context.WINDOW_SERVICE));
  DisplayMetrics dm = new DisplayMetrics();
  wm.getDefaultDisplay().getMetrics(dm);
  int mScreenWidth = dm.widthPixels;
  return mScreenWidth;
 }

 /**
  * 获取屏幕的高度
  */
 public static int getWindowsHeight() {
  WindowManager wm = (WindowManager) (MyApplication.getInstance().getSystemService(Context.WINDOW_SERVICE));
  DisplayMetrics dm = new DisplayMetrics();
  wm.getDefaultDisplay().getMetrics(dm);
  int mScreenHeigh = dm.heightPixels;
  return mScreenHeigh;
 }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android 处理 View 重复点击的多种方法

    1.抽象类 //实现 View.OnClickListener 接口 public abstract class OnThrottleClickListener implements View.OnClickListener { private static final String TAG = "OnThrottleClickListener"; private static final int SKIP_DURATION = 300;//milliseconds private l

  • Android Filterable实现Recyclerview筛选功能的示例代码

    原先碰到筛选这种功能时,后端的接口都会让上传一个字段,根据字段来返回相应的数据.后来一次和别人对接时,接口直接返回全部数据,而且还要实现筛选功能.我...我说不就是一条sql语句的事,改接口多方便,我苦心劝导,然后被怼回来,切,不就是筛选嘛,求人不如自己搞. 1. 效果图 2. 思路 既然是筛选,那就少不了比较.也没有什么好的办法,无非就是循环对比,然后将适配器进行数据更新.页面刷新即可.但筛选的调用要方便,怎么比较才方便我们调用呢?偶然间看到了Filterable,使Adapter继承自该接口

  • Android自定义view仿QQ的Tab按钮动画效果(示例代码)

    话不多说 先上效果图 实现其实很简单,先用两张图 一张是背景的图,一张是笑脸的图片,笑脸的图片是白色,可能看不出来.实现思路:主要是再触摸view的时候同时移动这两个图片,但是移动的距离不一样,造成的错位感,代码很简单: import android.content.Context import android.graphics.* import android.util.AttributeSet import android.view.MotionEvent import android.vi

  • Android自定义view之围棋动画效果的实现

    前言 废话不多说直接开始 老规矩,文章最后有源码 完成效果图 棋子加渐变色 棋子不加渐变色 一.测量 1.获取宽高 @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mWidth = w; mHeight = h; useWidth = mWidth; if (mWidth > mHeight) { useWidth =

  • Android自定义View实现分段选择按钮的实现代码

    首先演示下效果,分段选择按钮,支持点击和滑动切换. 视图绘制过程中,要执行onMeasure.onLayout.onDraw等方法,这也是自定义控件最常用到的几个方法. onMeasure:测量视图的大小,可以根据MeasureSpec的Mode确定父视图和子视图的大小. onLayout:确定视图的位置 onDraw:绘制视图 这里就不做过多的介绍,主要介绍本控件涉及的到的部分. 1.1 获取item大小.起始位置 @Override protected void onMeasure(int

  • Android自定义View仿大众点评星星评分控件

    本文实例为大家分享了Android仿大众点评星星评分控件的具体代码,供大家参考,具体内容如下 话不多说,直接上代码,这里采用的是自定View public class RatingBar extends View { // 正常.半个和选中的星星 private Bitmap mStarNormal, mStarHalf, mStarSelected; //星星的总数 private int mStartTotalNumber = 5; //选中的星星个数 private float mSele

  • Android自定义view实现输入框效果

    本文实例为大家分享了Android自定义view实现输入框的具体代码,供大家参考,具体内容如下 自定义输入框的View package com.fenghongzhang.day017; import android.content.Context; import android.content.res.TypedArray; import android.text.InputType; import android.util.AttributeSet; import android.view.

  • Android开发教程之如何屏蔽View的重复点击

    前言 android 防止重复点击是一个非常常见的需求,每个人都有各自的点击事件的处理习惯,有的喜欢使用匿名内部类,有的activity.fragment.自定义View等继承点击事件然后在onClick()方法中根据id用switch实现各自View的点击事件. 在开发中我们经常需要这样的需求,比如一个验证码发送按钮,我们只想让它响应500毫秒中的第一次点击事件,该如何处理呢?你可能会说这个简单,在点击事件中获取当前时间与上次的比较下,如果小于500毫秒就return掉.是的,这样可以解决,但

  • Android实现的RecyclerView适配器

    这个适配器我珍藏已久(近两年), 不断看到别人发适配器相关的文章, 但我总觉得没我的好用, 所以今日拿出来分享(宣传)一下, 欢迎各位指正不足. 源码地址: GitHub 功能 无需继承 Adapter, 无需判断 item 类型. 支持页头和页脚. 支持自动展示空数据界面. 通过 Kotlin 的 lambda 大量缩减代码. 支持全局 Item 类型 支持 diff 刷新 使用 添加依赖 implementation "com.dengzii.adapter:$latestVersion&q

  • Android 滑动Scrollview标题栏渐变效果(仿京东toolbar)

    Scrollview标题栏滑动渐变 仿京东样式(上滑显示下滑渐变消失) /** * @ClassName MyScrollView * @Author Rex * @Date 2021/1/27 17:38 */ public class MyScrollView extends ScrollView { private TranslucentListener mTranslucentListener; public void setTranslucentListener(Translucent

  • Android自定义View实现圆弧进度的效果

    前言 Android开发中,常常自定义View实现自己想要的效果,当然自定义View也是Android开发中比较难的部分,涉及到的知识有Canvas(画布),Paint(画笔)等,自定义控件分为三种:一是直接继承自View,完全的自定义:二是在原有控件的基础上进行改造,达到自己想要的效果:还有一种就是自定义组合控件,将已有的控件根据自己的需要进行组合实现的效果.本人对自定义View也是一知半解,简单记录下自己学习自定义View(继承自View)的过程,方便日后翻阅. 使用技术 1.继承View

  • Android使用ScrollView实现滚动效果

    本文实例为大家分享了ScrollView实现滚动效果的具体代码,供大家参考,具体内容如下 如果长文本的内容超过一屏幕 则只能显示一屏幕的内容 设置ScrollView 通过滚动浏览下面的内容 若将标签更改为<HorizontalScrollView></HorizontalScrollView>则为水平滚动效果 xml文件: <?xml version="1.0" encoding="utf-8"?> <android.su

  • 详解Android WebView监听console错误信息

    根据需求,我们要拿到h5的错误信息,并将error信息进行上报.查询了下Android WebView的API发现了WebChromeClient这个方法可以满足要求: @Override public boolean onConsoleMessage(ConsoleMessage consoleMessage) { //获取log的级别 switch (consoleMessage.messageLevel()){ case ERROR://将error信息上报到服务端 LogUtil.log

随机推荐