自定义控件---继承View类方式(五彩绚烂的水波纹案例)

---------------------------------------看效果(还有动画效果哦)----------------------------------------------------

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.atguigu.myware.MyWave
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

MainActivity.java

package com.atguigu.myware;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}
}

MyWave.java

package com.atguigu.myware;

import java.util.ArrayList;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

/**
 * 水波纹效果
 */
public class MyWave extends View {
	/**
	 * 定义一个水波浪类(一个圆环包括圆心、半径、画笔(需要绘制))
	 */
	private class Wave {
		// 圆心
		int pointX;
		int pointY;
		// 半径
		int radius;
		// 画笔
		Paint paint;
	}

	// 二个相临波浪中心点的最小距离
	private static final int DIS_SOLP = 13;
	// 是否有水波浪
	protected boolean isRunning = false;

	/**
	 * 第一步构造器
	 */
	// 定义水波纹的集合
	private ArrayList<Wave> wList;

	public MyWave(Context context, AttributeSet attrs) {
		super(context, attrs);
		// 初始化创建水波纹集合
		wList = new ArrayList<MyWave.Wave>();
	}

	/**
	 * touch事件
	 */
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		super.onTouchEvent(event);

		switch (event.getAction()) {
		//按下屏幕、滑动都可以产生水波
		case MotionEvent.ACTION_DOWN:
		case MotionEvent.ACTION_MOVE:
			// 得到down、move的圆心
			int x = (int) event.getX();
			int y = (int) event.getY();
			// 如果水波纹集合为空,就绘制一个水波纹
			if (wList.size() == 0) {
				//绘制水波纹
				addPoint2List(x, y);
				// 修改状态,说明水波生成
				isRunning = true;
				//此刻发送一个消息,说明绘制了一个水波
				handler.sendEmptyMessage(0);
			} else {
				// 如果水波集合不为空,就去最后一个绘制的环形水波
				Wave w = wList.get(wList.size() - 1);

				if (Math.abs(w.pointX - x) > DIS_SOLP
						|| Math.abs(w.pointY - y) > DIS_SOLP) {
					addPoint2List(x, y);
				}
			};
			break;

		default:
			break;
		}
		return true;
	}

	/*
	 * 定义4种色彩的水波
	 */
	private int[] colors = new int[] { Color.BLUE, Color.RED, Color.YELLOW,
			Color.GREEN };

	/**
	 * 添加波浪
	 */
	private void addPoint2List(int x, int y) {
		//创建一个水波类
		Wave w = new Wave();
		//将滑动或者按下时候的坐标赋值给水波类
		w.pointX = x;
		w.pointY = y;
		//创建画笔
		Paint pa = new Paint();
		//画出水波(环形)设置颜色,抗锯齿,形状
		pa.setColor(colors[(int) (Math.random() * 4)]);
		pa.setAntiAlias(true);
		pa.setStyle(Style.STROKE);
		//赋值
		w.paint = pa;
		//往集合中添加一个环形水波
		wList.add(w);
	}

	/**
	 * 绘制水波纹
	 */
	@Override
	protected void onDraw(Canvas canvas) {
		for (int i = 0; i < wList.size(); i++) {
			Wave wave = wList.get(i);
			canvas.drawCircle(wave.pointX, wave.pointY, wave.radius, wave.paint);
		}
	}

	/*
	 * 运用消息机制
	 */
	private Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			//接受到发送过来的消息进行相应的操作
			// 刷新数据
			flushData();
			// 刷新页面
			invalidate();
			// 循环动画
			if (isRunning) {
				handler.sendEmptyMessageDelayed(0, 50);
			}

		};
	};

	/**
	 * 刷新数据(操作环形水波的透明度以及半径变化)
	 */
	private void flushData() {

		for (int i = 0; i < wList.size(); i++) {

			Wave w = wList.get(i);

			// 如果透明度为 0 从集合中删除
			int alpha = w.paint.getAlpha();
			if (alpha == 0) {
				wList.remove(i);
				continue;
			}
			//每次透明度值减5
			alpha -= 5;
			if (alpha < 5) {
				alpha = 0;
			}
			// 降低透明度
			w.paint.setAlpha(alpha);

			// 扩大半径
			w.radius = w.radius + 3;
			// 设置半径厚度
			w.paint.setStrokeWidth(w.radius / 3);
		}

		/*
		 * 如果集合被清空,就停止刷新动画
		 */
		if (wList.size() == 0) {
			isRunning = false;
		}
	}
}

---------------------------看一个简单的版本----------------------效果是逐渐变大,直到消失--------------------------------

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.atguigu.myware.MyWave
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

MainActivity.java

package com.atguigu.myware;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}
}

MyWave.java

package com.atguigu.myware;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

/**
 * 水波纹的效果的视图
 *
 */
public class MyWave extends View {

	private Paint paint;

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		super.onTouchEvent(event);
		switch (event.getAction()) {
		/*
		 * 当按下的时候开始绘制圆环水波纹
		 */
		case MotionEvent.ACTION_DOWN:
			// 1. 设置圆心
			startX = event.getX();
			startY = event.getY();

			// 2.根据圆心创建新的圆
			initView();

			// 3.绘制
			invalidate();

			break;

		default:
			break;
		}
		return true;
	}

	private Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			// 1.透明度改变-小
			int alpha = paint.getAlpha();
			alpha -= 5;
			if (alpha < 0) {
				alpha = 0;
			}
			// 透明度:0~255之间
			paint.setAlpha(alpha);

			// 2.半径变大
			radius += 5;
			paint.setStrokeWidth(radius / 3);

			// 3.再次绘制一个,执行onDraw方法
			invalidate();
		};
	};

	/*
	 * 第一步、构造器
	 */
	public MyWave(Context context, AttributeSet attrs) {
		super(context, attrs);
		initView();
	}

	/**
	 * 初始化View
	 */
	private int radius;// 半径

	private void initView() {
		paint = new Paint();
		// 设置颜色
		paint.setColor(Color.RED);
		// 设置抗锯齿
		paint.setAntiAlias(true);
		// 设置圆环样式
		paint.setStyle(Style.STROKE);
		// 半径为5
		radius = 5;
		paint.setStrokeWidth(radius / 3);

	}

	// 圆形坐标
	private float startX;
	private float startY;

	/**
	 * 绘制环形水波纹
	 */
	@Override
	protected void onDraw(Canvas canvas) {
		if (paint.getAlpha() > 0) {
			if (startX > 0 && startY > 0) {
				// 绘制一个圆环
				canvas.drawCircle(startX, startY, radius, paint);
				// 绘制的同时,发送一个延迟消息
				handler.sendEmptyMessageDelayed(0, 50);
			}
		}
	}
}
时间: 2024-08-28 11:11:23

自定义控件---继承View类方式(五彩绚烂的水波纹案例)的相关文章

自定义控件---继承View类方式(自定义开关效果案例)

----------------------------------------------------简单的效果图-------------------------------------------------------------------------- activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools=&quo

Android自定义控件:Android L控件点击水波纹的实现(源码 + Demo)

实现思路来自singwhatiwanna http://blog.csdn.net/singwhatiwanna/article/details/42614953 Demo: 一.控件的流程: 大致上如下,实际是有些偏差的大家可以自己画画 RevealLayout()--->init()--->onMeasure()--->onLayout()--->onDraw()--->dispatchTouchEvent()--->getTargetView()--->is

自定义控件之直接继承View创建全新视图(二)

自定义控件我们上一节探讨了一种最简单的自定义是直接继承View的子类,实现控件的不同UI视图展示及功能的拓展,在学习新知识前可以温习下之前所学知识-自定义控件之对现有控件拓展(一). ok,在回顾了之前所学的知识之后,现在我们来学习稍微复杂点的自定义控件:今天我们实现一个直接继承于View的全新控件.大家都知道音乐播放器吧,在点击一首歌进行播放时,通常会有一块区域用于显示音频条,我们今天就来学习下,播放器音频条的实现. 首先我们还是先定义一个类,直接继承于View,并重写它的构造方法,并初始化一

Django 类方式view进行进行用户验证

问题: Django中,view的书写方式有两种,一种是def函数方式,一种是class方式,函数方式通过@login_required装饰器标记函数,就必须通过用户验证,而类,则没办法通过此方法进行标记 那,如何解决这个问题? 利用类的继承方式,写一个基类,需要验证的class view类,首先继承这个基类,后面所有通过此类的url都需要进行用户验证登录,因为可能有许多的view需要使用该类,需要独立出来,建立在utils目录下,起名mixin_is_login.py,然后在各种需要的view

android自定义控件(二) 入门,继承View

转载请注明地址:http://blog.csdn.net/ethan_xue/article/details/7313788 ps: 可根据apidemo里LableView,list4,list6学习 文档在dev guide/Framework Topics/User Interface/Building Custom Components 自定义控件的步骤: 1 View的工作原理  2 编写View类  3 为View类增加属性  4 绘制屏幕  5 响应用户消息  6 自定义回调函数

JAVA学习第二十二课(多线程(二))- (多线程的创建方式一 :继承Thread类)

线程是程序中的执行线程.Java 虚拟机允许应用程序并发地运行多个执行线程. 创建新执行线程有两种方法. 一种方法是将类声明为 Thread 的子类.该子类应重写Thread 类的run 方法.另一种方法是声明实现 Runnable 接口的类.该类然后实现run 方法. 创建线程方式一:继承Thread类 一.创建线程的步骤: 1.定义一个类继承Thread类 2.覆盖Thread中的run()方法 3.直接创建Thread类子类的对象 4.调用start方法开启线程,并调用线程的任务run方法

Java多线程的两种实现方式:继承Thread类 &amp; 实现Runable接口

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! 创建和启动线程的两种传统方式: Java提供了线程类Thread来创建多线程的程序.其实,创建线程与创建普通的类的对象的操作是一样的,而线程就是Thread类或其子类的实例对象.每个Thread对象描述了一个单独的线程.要产生一个线程,有两种方法: ◆需要从Java.lang.Thread类派生一个新的线程类,重载它的run()方法: ◆实现Runnalbe接口,重载Runnalbe接口中的run()方法.

JS面向对象组件 -- 继承的其他方式(类式继承、原型继承)

继承的其他形式: •类式继承:利用构造函数(类)继承的方式 •原型继承:借助原型来实现对象继承对象 类 : JS是没有类的概念的 , 把JS中的构造函数看做的类 要做属性和方法继承的时候,要分开继承. function Aaa(){ //父类 this.name = "小明"; } Aaa.prototype.showName = function(){ alert( this.name ); }; function Bbb(){ //子类 } Bbb.prototype = new

子类继承基类的三种继承方式

在C++中,子类继承父类有三种继承方式,分别是:public, protected和private.子类继承的方式不同,那么子类对象访问父类中的参数访问权限也不同. public 方式继承:基类的private成员派生类不可见,基类中的protected和public成员在派生类中可以直接使用,并且变成了派生类中相应                        的protected成员和public成员,但是只有public成员可以在派生类外使用. protected 方式继承:基类的priv