我们常用的语音输入法会根据我们说话的大小产生一些波动动画,那么这个动画是怎么实现的呢?其实很简单。原理:一张空的麦克风图像,一张满的麦克风图像,先绘制一张空的,然后再绘制一些满的,但是满的绘制之前,有一个圆形的clip区域,这个区域就是用来显示满的显示多少。另外有点注意,有些手机要打开软件加速,不然clip区域显示的是方形的而不是圆形的,看起来的效果就悲剧了。
图片资源我用的是讯飞的图片,
看源码:
以上是控件的源码,图片加载方法:
以上加载图片方法可以自动加载.9格式的。
工程下载:bdvoice
图片资源我用的是讯飞的图片,
看源码:
package com.voice.bdv; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PaintFlagsDrawFilter; import android.graphics.Path; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.View; public class ClipCircleView extends View { private Drawable empty; private Drawable full; Path path; PaintFlagsDrawFilter filter; public ClipCircleView(Context paramContext, AttributeSet attrs) { super(paramContext, attrs); setLayerType(View.LAYER_TYPE_SOFTWARE, null);// 软件加速 } public void init() { try { empty = MainActivity.getDrawable(getContext(), "voice_empty.png"); full = MainActivity.getDrawable(getContext(), "voice_full.png"); this.empty.setBounds(new Rect(-this.empty.getIntrinsicWidth() / 2, -this.empty.getIntrinsicHeight() / 2, this.empty .getIntrinsicWidth() / 2, this.empty .getIntrinsicHeight() / 2)); this.full.setBounds(new Rect(-this.full.getIntrinsicWidth() / 2, -this.full.getIntrinsicHeight() / 2, this.full .getIntrinsicWidth() / 2, this.full .getIntrinsicHeight() / 2)); filter = new PaintFlagsDrawFilter(Paint.ANTI_ALIAS_FLAG, Paint.FILTER_BITMAP_FLAG); path = new Path(); initPath(0); } catch (Exception localException) { localException.printStackTrace(); } } public void initPath(int paramInt) { this.path.reset(); this.path.addCircle(0.0F, 0.0F, this.empty.getIntrinsicWidth() * paramInt / 12, Path.Direction.CCW); } public void onDraw(Canvas paramCanvas) { paramCanvas.save(); paramCanvas.setDrawFilter(filter); paramCanvas.translate(getWidth() / 2, getHeight() / 2); if (empty != null) empty.draw(paramCanvas); if (path != null) paramCanvas.clipPath(path); if (full != null) full.draw(paramCanvas); paramCanvas.restore(); } public void finalize() throws Throwable { this.empty = null; this.full = null; super.finalize(); } protected void onMeasure(int paramInt1, int paramInt2) { super.onMeasure(paramInt1, paramInt2); int i = View.MeasureSpec.getSize(paramInt1); int j = View.MeasureSpec.getSize(paramInt2); Drawable localDrawable = getBackground(); if (localDrawable != null) { i = localDrawable.getMinimumWidth(); j = localDrawable.getMinimumHeight(); } setMeasuredDimension(resolveSize(i, paramInt1), resolveSize(j, paramInt2)); } }
以上是控件的源码,图片加载方法:
public static Bitmap getDrawable(Resources res, TypedValue value, InputStream stream, Rect rect, BitmapFactory.Options options) { if (options == null) options = new BitmapFactory.Options(); if ((options.inDensity == 0) && (value != null)) { int i = value.density; if (i == 0) options.inDensity = 160; else if (i != 65535) options.inDensity = i; } if ((options.inTargetDensity == 0) && (res != null)) options.inTargetDensity = res.getDisplayMetrics().densityDpi; return BitmapFactory.decodeStream(stream, rect, options); } private static Drawable getDrawable(Resources res, Bitmap bitmap, byte[] paramArrayOfByte, Rect rect, String path) { if (paramArrayOfByte != null) return new NinePatchDrawable(res, bitmap, paramArrayOfByte, rect, path); return new BitmapDrawable(res, bitmap); } public static Drawable getDrawable(Resources res, TypedValue value, InputStream stream, String path, BitmapFactory.Options options) { if (stream == null) return null; Rect rect = new Rect(); if (options == null) options = new BitmapFactory.Options(); Bitmap bitmap = getDrawable(res, value, stream, rect, options); if (bitmap != null) { byte[] arrayOfByte = bitmap.getNinePatchChunk(); if ((arrayOfByte == null) || (!NinePatch.isNinePatchChunk(arrayOfByte))) { arrayOfByte = null; rect = null; } return getDrawable(res, bitmap, arrayOfByte, rect, path); } return null; } public static Drawable getDrawable(Context context, String path) { try { Resources res = context.getResources(); InputStream stream = context.getAssets().open(path); TypedValue value = new TypedValue(); value.density = 240; if (Build.VERSION.SDK_INT > 3) { return getDrawable(res, value, stream, path, null); } return Drawable.createFromResourceStream(res, value, stream, path); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; }
以上加载图片方法可以自动加载.9格式的。
工程下载:bdvoice
收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (0)
站点信息
- 文章2305
- 用户1336
- 访客11455720
每日一句
Talent without working hard is nothing.
没有努力,天份不代表什么。
没有努力,天份不代表什么。
MySQL 数据库优化
This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its de
免ROOT实现模拟点击任意位置
Mobaxterm终端神器
CreateProcessW要注意的细节问题
Autonomous NAT Traversal
【教程】win10 彻底卸载edge浏览器
eclipse工程基于Xposed的一个简单Hook
排名前5的开源在线机器学习
Mac OS最简单及(Karabiner)快捷键设置
发一款C++编写的麻将
VMware NAT端口映射外网访问虚拟机linux
独家发布最新可用My-AutoPost——wordpress 采集器
新会员