从今天开始每天会分享一些自定义控件编程相关内容。
自定义控件研发算是Android研发中的一颗明珠。每每Android推出漂亮功能的时候,都是某位代码工匠精心雕琢的硕果。研究他们的实现原理,相关技巧,有助于我们开发更好Android功能。常言道:熟读唐诗三百首,不会作诗也会吟。
好,今天我们先研究一个比较经典的,经常会碰到,但是又觉得实现起来有一定难度的“水波纹”效果。
核心类继承至View类
public class WaterBubbleView extends View { /** * 初始半径 */ private final int RADIUS = 40; /** * 初始透明度 */ private final int ALPHA = 255; private Canvas canvas; private Paint paint; /** * 颜色数组 */ private final int colors[] = new int[]{Color.RED, Color.BLUE, Color.GREEN, Color.YELLOW, Color.BLACK, Color.CYAN, Color.GRAY, Color.GRAY, Color.MAGENTA}; /** * 圆心X坐标 */ private int cx; /** * 圆心Y坐标 */ private int cy; /** * 圆的半径 */ private int radius = RADIUS; /** * 运行状态 */ private boolean isRunning = false; /** * 透明度 */ private int alpha = ALPHA; /** * 实现动画效果 */ private Handler handler = new Handler(new Callback() { @Override public boolean handleMessage(Message msg) { alpha -= 4; paint.setAlpha(alpha); radius += 15; if (alpha <= 10) { isRunning = false; radius = RADIUS; alpha = ALPHA; } invalidate(); return true; } }); public WaterBubbleView(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { canvas = new Canvas(); paint = new Paint(); paint.setAntiAlias(true); }
//这是第三步,在屏幕上画出视图,在此之前还有个第二步onLayout方法,用来决定视图绘制在屏幕的哪个部位,一般认为决定视图左上角和右下角的两个位置。 @Override protected void onDraw(Canvas canvas) { if (isRunning) { System.out.println("isRun, draw"); canvas.drawCircle(cx, cy, radius, paint); handler.sendEmptyMessageDelayed(0, 20); } else { System.out.println("noRun, change"); paint.setColor(colors[(int) (Math.random() * colors.length)]); } }
//用来测量视图绘制在屏幕上的大小尺度,这是继承View的第一步 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: //保证每次按下时绘图颜色重置 radius=40; alpha=255; if (!isRunning) { isRunning = true; } cx = (int) event.getX(); cy = (int) event.getY(); handler.sendEmptyMessage(0); break; case MotionEvent.ACTION_HOVER_MOVE: isRunning = true; break; case MotionEvent.ACTION_UP: isRunning = true; break; } return super.onTouchEvent(event); } }
引用方式:
<com.voyage.waterbubble.WaterBubbleView android:layout_width="fill_parent" android:layout_height="fill_parent" />
layout_height可以指定为固定高度,波纹会在视图中绘画。
特别说明:当alpha 的值为0时将停止循环绘制。
实现原理:init() 中初始化画布和画笔,
在onDraw()中首次画默认圆,发送handler消息,更新半径和透明图参数,启动 invalidate() 方法,再次绘画,如此循环。直到alpha值为o,停止绘画。
效果图: