Android-给照片底部添加波浪效果
2015-07-29 13:46
633 查看
实现的效果是酱紫的:
![](http://img.blog.csdn.net/20150729134504279?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
使用方式跟普通的ImageView是一样的,代码:
一开始做的时候,没有重写onMeasure,导致波浪效果怎么也出不来,妈蛋的!
转载请标明出处:/article/1908029.html
很可惜这种方式的效率太低了,ListView根本就滑不动啊,于是有了下面这种实现方式!
竟然也实现了,而且ListView还能滑的动,amazing!
使用方式跟普通的ImageView是一样的,代码:
/** * 参考:http://blog.csdn.net/lee576/article/details/7900228 * */ public class WaveBottomImageView extends ImageView{ private Bitmap mBitmap; private boolean inited; // 定义两个常量,这两个常量指定该图片横向,纵向上都被划分为100格 private final int WIDTH = 100; private final int HEIGHT = 100; // 记录该图片上包含10201个顶点 private final int COUNT = (WIDTH + 1) * (HEIGHT + 1); // 定义一个数组,记录Bitmap上的101*101个点的坐标 private final float[] orig = new float[COUNT * 2]; // 定义一个数组,记录Bitmap上的101*101个点经过扭曲后的坐标 // 对图片扭曲的关键就是修改该数组里元素的值 private final float[] verts = new float[COUNT * 2]; private int bitmapWidth; private int bitmapHeight; private float boxHeigtht; public WaveBottomImageView(Context context) { this(context, null); } public WaveBottomImageView(Context context, AttributeSet attrs) { super(context, attrs); mBitmap = ((BitmapDrawable)this.getDrawable()).getBitmap(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); // 获取图片宽度和高度 bitmapWidth = getMeasuredWidth(); bitmapHeight = getMeasuredHeight(); boxHeigtht = bitmapHeight / HEIGHT; setMeasuredDimension(bitmapWidth, (int)(bitmapHeight + boxHeigtht)); if(!inited){ init(); inited = true; } } protected void onDraw(Canvas canvas) { canvas.drawBitmapMesh(mBitmap, WIDTH, HEIGHT, verts, 0, null, 0, null); } private void init(){ //初始化 int index = 0; for (int y = 0; y <= HEIGHT; y++) { float fy = bitmapHeight * y / HEIGHT; for (int x = 0; x <= WIDTH; x++) { float fx = bitmapWidth * x / WIDTH; // 初始化orig,verts数组 // 初始化,orig,verts两个数组均匀地保存了101*101个点的x,y坐标 orig[index * 2 + 0] = verts[index * 2 + 0] = fx; orig[index * 2 + 1] = verts[index * 2 + 1] = fy; if(y == HEIGHT){ // 修改最后一行的y坐标 float oldY = orig[index * 2 + 1]; float newY = (float) (oldY + boxHeigtht * Math.sin(Math.PI / 4 * (x % 5))); verts[index * 2 + 1] = newY; } index += 1; } } } // private void wave() { // int index = (WIDTH + 1) * HEIGHT; // for (int x = 0; x <= WIDTH; x++) { // float oldY = orig[index * 2 + 1]; // float newY = (float) (oldY + boxHeigtht * Math.sin(Math.PI / 4 * (x % 5))); // verts[index * 2 + 1] = newY; // index += 1; // } // } }
一开始做的时候,没有重写onMeasure,导致波浪效果怎么也出不来,妈蛋的!
转载请标明出处:/article/1908029.html
很可惜这种方式的效率太低了,ListView根本就滑不动啊,于是有了下面这种实现方式!
/** * 参考:http://blog.csdn.net/lmj623565791/article/details/42094215 * */ public class WaveImageView extends ImageView { private Paint mPaint; private Paint mPathPaint; private Path mPath; private Bitmap mMaskBitmap; private static final Xfermode mXfermode = new PorterDuffXfermode(Mode.DST_IN); private float mRectFWidth; private int mWidth; private int mHeight; public WaveImageView(Context context) { this(context, null); } public WaveImageView(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); } private void init(final Context context, final AttributeSet attrs) { mPaint = new Paint(); mPath = new Path(); mPathPaint = new Paint(); mPathPaint.setAntiAlias(true); mPathPaint.setColor(0xff000000); mPathPaint.setStyle(Paint.Style.FILL); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); // 获取图片宽度和高度 mWidth = getMeasuredWidth(); mHeight = getMeasuredHeight(); mRectFWidth = mWidth / 20.0f; mRectFWidth = mRectFWidth - mRectFWidth%1;//去掉小数部分 } @SuppressLint("DrawAllocation") @Override protected void onDraw(Canvas canvas) { // 拿到Drawable Drawable drawable = getDrawable(); // 获取drawable的宽和高 int dWidth = drawable.getIntrinsicWidth(); int dHeight = drawable.getIntrinsicHeight(); if (drawable != null) { // 创建bitmap Bitmap bitmap = Bitmap.createBitmap(mWidth, mHeight, Config.ARGB_8888); float scale = 1.0f; // 创建画布 Canvas drawCanvas = new Canvas(bitmap); // 按照bitmap的宽高,以及view的宽高,计算缩放比例;因为设置的src宽高比例可能和imageview的宽高比例不同,这里我们不希望图片失真; scale = getWidth() * 1.0F / Math.min(dWidth, dHeight); // 根据缩放比例,设置bounds,相当于缩放图片了 drawable.setBounds(0, 0, (int) (scale * dWidth), (int) (scale * dHeight)); // 1. 先把原图(dst)绘制上 drawable.draw(drawCanvas); // 2. 设置Xfermode mPaint.setXfermode(mXfermode); // 3. 把mask(src)绘制上 if (mMaskBitmap == null || mMaskBitmap.isRecycled()) { mMaskBitmap = getMaskBitmap(); } drawCanvas.drawBitmap(mMaskBitmap, 0, 0, mPaint); // 将准备好的bitmap绘制出来 canvas.drawBitmap(bitmap, 0, 0, null); } } /** * 绘制形状 * * @return */ public Bitmap getMaskBitmap() { Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); RectF oval = new RectF(0, 0, mRectFWidth, mRectFWidth); mPath.addArc(oval, 0, 180); mPath.lineTo(0, -(mHeight-mRectFWidth)); mPath.lineTo(mRectFWidth, -(mHeight-mRectFWidth)); mPath.lineTo(mRectFWidth, 0); canvas.translate(0, mHeight-mRectFWidth); canvas.drawPath(mPath, mPathPaint); float sum = mRectFWidth; while(sum < mWidth){ canvas.translate(mRectFWidth, 0); canvas.drawPath(mPath, mPathPaint); sum += mRectFWidth; } return bitmap; } }
竟然也实现了,而且ListView还能滑的动,amazing!
相关文章推荐
- Android 动画之RotateAnimation应用详解
- android Smali注入
- 【笔记】Android线程概括
- Google Android市场apk下载
- Android使用Activity用作弹出式对话框
- Android强制切换横屏竖屏不起作用的解决办法
- ADT后windows菜单未找到Android SDK Manager和Android Virtual Device Manager该解决方案的选择
- Ubuntu 14.04 x64 安装 Android SDK(转载)
- android打开联系人的代码
- Android中Paint字体属性的设置
- Android 中parcelable 和 parcel
- Android Studio第一次启动的Fetching android sdk component information的问题
- openwrt 使用 android 手机usb tether联网
- 玩转Android---组件篇---Handler的使用(1)
- 玩转Android---事件监听篇---第1篇
- 玩转Android---事件监听篇---第2篇
- 玩转Android---组件篇---数据存储之SQLite
- 玩转Android---组件篇---数据存储之File
- 玩转Android---组件篇---Service(服务)
- 玩转Android---组件篇---Broadcast Receiver(广播接收器)