Android 自定义拼接图片,点击小图位置时,绘制在上层
2016-05-04 21:26
615 查看
这里将五张矩形图拼在同一图层,并使用paint.setXfermode,显示点击区域上的图层
备注:如果使用圆形图片素材(即圆形外是透明背景),那么需要用圆形的碰撞检测。
我的自定义View项目地址: https://github.com/aa86799/MyCustomView (欢迎start&fork)
本文地址:https://github.com/aa86799/MyCustomView/tree/master/guaguaka
备注:如果使用圆形图片素材(即圆形外是透明背景),那么需要用圆形的碰撞检测。
package com.stone.guaguaka.view; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Point; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import java.io.InputStream; import java.util.ArrayList; import java.util.List; /** * author : stone * email : aa86799@163.com * time : 16/5/3 20 27 */ public class OverlayImageView extends View { private List<Bitmap> mBitmaps; private List<Point> mPoints; private int mWidth; private int mHeight; private int mPosition; public OverlayImageView(Context context) { this(context, null); } public OverlayImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public OverlayImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.mBitmaps = new ArrayList<>(); this.mPoints = new ArrayList<>(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (mBitmaps.isEmpty()) { return; } setMeasuredDimension(mWidth, mHeight); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (mBitmaps.isEmpty()) { return; } Bitmap outBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.RGB_565); Canvas outCanvas = new Canvas(outBitmap); outCanvas.drawColor(Color.parseColor("#abc777")); Point point; for (int i = 0, len = mBitmaps.size(); i < len; ++i) { point = mPoints.get(i); if (mPosition != i) { outCanvas.drawBitmap(mBitmaps.get(i), point.x, point.y, null); } } /* 如果不使用paint,那么默认情况下,后绘制的在上层 这里有意将postion上的放在前面绘制,配合paint.setXfermode 绘制层次 这里要注意一点的就是: 如果paint 被new Canvas(bitmap)操作,这个canvas默认就是一个图层 如果paint 被外部的canvas操作,需要给它指定图层,指定后设置的xfermode才有需要的效果,否则效果达不到期望,让人难以琢磨 */ Paint paint = new Paint(); int saveLayerCount = canvas.saveLayer(0, 0, mWidth, mHeight, paint, Canvas.ALL_SAVE_FLAG);//存为新图层 canvas.drawBitmap(mBitmaps.get(mPosition), mPoints.get(mPosition).x, mPoints.get(mPosition).y, paint); //dst paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OVER)); canvas.drawBitmap(outBitmap, 0, 0, paint); //src paint.setXfermode(null); canvas.restoreToCount(saveLayerCount); //恢复保存的图层 } public void setImages(int... resId) { InputStream is; Bitmap bitmap; for (int i = 0; i < resId.length; i++) { is = getResources().openRawResource(resId[i]); bitmap = BitmapFactory.decodeStream(is); mBitmaps.add(bitmap); } mWidth = mBitmaps.get(0).getWidth() * 2; mHeight = mBitmaps.get(0).getHeight() * 2; for (int i = 0, len = mBitmaps.size(); i < len; ++i) { int x, y; if (i == 4) { x = mWidth / 4; y = mHeight / 4; } else { if (i % 2 == 0) { x = 0; } else { x = mWidth / 2; } if (i <= 1) { y = 0; } else { y = mHeight / 2; } } mPoints.add(new Point(x, y)); } invalidate(); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: int x = (int) event.getX(); int y = (int) event.getY(); if (mPosition != getTouchPosition(x, y)) { mPosition = getTouchPosition(x, y); } invalidate(); break; case MotionEvent.ACTION_MOVE: break; case MotionEvent.ACTION_UP: break; } return super.onTouchEvent(event); } private int getTouchPosition(int x, int y) { int position = 0; Point p; for (int i = 0, len = mPoints.size(); i < len; i++) { p = mPoints.get(i); if (isCollision(x, y, p.x, p.y, mWidth / 2, mHeight / 2)) { position = i; } } return position; } /** * @param x1 点 * @param y1 点 * @param x2 矩形view x * @param y2 矩形view y * @param w 矩形view 宽 * @param h 矩形view 高 * @return */ private boolean isCollision(int x1, int y1, int x2, int y2, int w, int h) { if (x1 >= x2 && x1 <= x2 + w && y1 >= y2 && y1 <= y2 + h) { return true; } return false; } }
我的自定义View项目地址: https://github.com/aa86799/MyCustomView (欢迎start&fork)
本文地址:https://github.com/aa86799/MyCustomView/tree/master/guaguaka
相关文章推荐
- Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)
- android 开源项目集合
- Android最佳实践之Notification、下拉刷新、内存及性能建议等
- 玩转Android之在线视频播放控件Vitamio的使用
- 玩转Android之在线视频播放控件Vitamio的使用
- 玩转Android之在线视频播放控件Vitamio的使用
- 玩转Android之在线视频播放控件Vitamio的使用
- Android图片适配问题分析
- Android自动化压力测试之Monkey Test Android常见的错误类型及黑白名单的使用方法(四)
- Android Handler详细使用方法实例
- Android 触摸事件机制(三) View中触摸事件详解
- Android中ListView内容超过一屏,上下滑动后数据紊乱的问题
- Android基础 | 控件基础 | RadioGroup用法
- android 多点触摸绘画demo
- [Android]Toast的工具类(- -!)可啪的重复显示Toast
- Android逆向之旅---Android中的sharedUserId属性详解
- 如何在android style文件中使用自定义属性
- 安卓实现QQ侧滑菜单效果
- android studio gradle下载失败解决方案
- Android基础 | 意图Intent讲解