自定义View——类似微信裁剪控件
2016-04-28 13:47
585 查看
用微信的时候发现设置头像的时候总是有些莫名其妙的问题,就模仿着做了个自定义View。
效果:
直接上代码。。。有些注释
没有太大难度,图片是用canvas画上去的,图片的处理是利用matrix实现的,截图利用的是getDrawingCathe,其实也可以通过自己确定范围createBitmap,但是我因为项目需要背后的颜色,所以采用这种方式更为简便
效果:
直接上代码。。。有些注释
public class CutView extends View implements ScaleGestureDetector.OnScaleGestureListener{ private Rect mBmpRect; private Paint mShadowPaint,mRectPaint; private Bitmap mSourceBmp; private Matrix mMatrix; private boolean isInited; private float cutRadio = 1f; private ScaleGestureDetector scaleGestureDetector; public CutView(Context context) { this(context,null); } public CutView(Context context, AttributeSet attrs) { super(context, attrs); init(context); mSourceBmp = BitmapFactory.decodeResource(getResources(), R.mipmap.bg); } private void init(Context context){ setBackgroundColor(Color.BLACK); mBmpRect = new Rect(); mRectPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mRectPaint.setColor(Color.WHITE); mRectPaint.setStyle(Paint.Style.STROKE); mShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mShadowPaint.setColor(0xa0000000); scaleGestureDetector = new ScaleGestureDetector(context,this); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int w = MeasureSpec.getSize(widthMeasureSpec); int h = MeasureSpec.getSize(heightMeasureSpec); //左右两边的padding设置 int padding = (int) (w * 0.065f); //裁剪比例 int rectW = w - 2 * padding; int rectH = (int) (rectW / cutRadio); mBmpRect.set(padding,(h - rectH)/2,padding + rectW,(h - rectH)/2 + rectH); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); if (!isInited) { mMatrix = new Matrix(); int dw = mSourceBmp.getWidth(); int dh = mSourceBmp.getHeight(); float scale = 0; if (dw > dh) { scale = mBmpRect.width() /(float) dw; }else { scale = mBmpRect.height() /(float) dh; } mMatrix.postTranslate(getWidth() / 2 - dw / 2, getHeight() / 2 - dh/2); mMatrix.postScale(scale,scale,mBmpRect.left+mBmpRect.width()/2,mBmpRect.top+mBmpRect.height()/2); isInited = true; } } private float startX,startY; private boolean isMultiPoint = false; @Override public boolean onTouchEvent(MotionEvent event) { if (event.getPointerCount()>1) { scaleGestureDetector.onTouchEvent(event); isMultiPoint = true; } switch (event.getAction()) { case MotionEvent.ACTION_DOWN: if (checkIsInRect(event)) { startX = event.getX(); startY = event.getY(); } else { return false; } break; case MotionEvent.ACTION_MOVE: float offX = event.getX() - startX; float offY = event.getY() - startY; if (!isMultiPoint) { mMatrix.postTranslate(offX, offY); invalidate(); } startX = event.getX(); startY = event.getY(); break; case MotionEvent.ACTION_UP: isMultiPoint = false; break; } return true; } /* 检查触摸点是否在裁剪范围框内 */ private boolean checkIsInRect(MotionEvent event){ int x = (int) event.getX(); int y = (int) event.getY(); return mBmpRect.contains(x,y); } /* 裁剪 */ public Bitmap cut(){ setDrawingCacheEnabled(true); Bitmap bmp = getDrawingCache(); return Bitmap.createBitmap(bmp, mBmpRect.left, mBmpRect.top, mBmpRect.width(), mBmpRect.height()); } /* 旋转 */ public void rotate(){ Point point = getCenterPoint(); mMatrix.postRotate(-90,point.x,point.y); invalidate(); } /* 水平翻转 */ public void flip(){ Point point = getCenterPoint(); mMatrix.postScale(-1, 1,point.x,point.y); invalidate(); } private Point getCenterPoint(){ Point point = new Point(); RectF rectF = getBmpRect(); point.x = (int) (rectF.left + rectF.width()/2); point.y = (int) (rectF.top + rectF.height()/2); return point; } public void setCutRadio(float cutRadio) { this.cutRadio = cutRadio; } public void setSourceBmp(Bitmap mSourceBmp) { this.mSourceBmp = mSourceBmp; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //画出源图片 canvas.drawBitmap(mSourceBmp,mMatrix,null); //画出阴影遮盖部分 canvas.drawRect(0, 0, getWidth(), mBmpRect.top, mShadowPaint); canvas.drawRect(0, mBmpRect.top, mBmpRect.left, mBmpRect.bottom, mShadowPaint); canvas.drawRect(mBmpRect.right, mBmpRect.top, getWidth(), mBmpRect.bottom, mShadowPaint); canvas.drawRect(0,mBmpRect.bottom,getWidth(),getHeight(),mShadowPaint); //画出中间裁剪部分的矩形,边缘留出1的距离为了截图的时候不被截取到 canvas.drawRect(mBmpRect.left-1,mBmpRect.top-1,mBmpRect.right+1,mBmpRect.bottom+1,mRectPaint); } @Override public boolean onScale(ScaleGestureDetector detector) { float scale = detector.getScaleFactor(); RectF rectF = getBmpRect(); if (rectF.contains(detector.getFocusX(),detector.getFocusY())) { mMatrix.postScale(scale, scale, detector.getFocusX(), detector.getFocusY()); }else { mMatrix.postScale(scale, scale,rectF.left+rectF.width()/2,rectF.top+rectF.height()/2); } invalidate(); return true; } @Override public boolean onScaleBegin(ScaleGestureDetector detector) { return true; } @Override public void onScaleEnd(ScaleGestureDetector detector) { } private RectF getBmpRect(){ Matrix matrix = mMatrix; RectF rectF = new RectF(); rectF.set(0, 0, mSourceBmp.getWidth(), mSourceBmp.getHeight()); matrix.mapRect(rectF); return rectF; } }
没有太大难度,图片是用canvas画上去的,图片的处理是利用matrix实现的,截图利用的是getDrawingCathe,其实也可以通过自己确定范围createBitmap,但是我因为项目需要背后的颜色,所以采用这种方式更为简便
相关文章推荐
- 微信 支付支付授权目录 修改
- 微信支付(20140923更新)商户支付密钥key的生成与设置
- Java中的微信公众号开发(一)
- PHP处理微信昵称emoji方法
- 微信支付 php 公众平台及移动端服务器
- 微信公众平台——获取用户信息
- 高大上的微信公众号养成记
- 填平友盟社会化分享之---微信分享的坑
- 微信公众号线上和线下增粉秘籍:
- 微信看呆!阿里钉钉宣布推出多人视频会议:免费高清
- 微商城分销系统软件首选—好分销微信三级分销系统源码定制
- 微信公众平台开发之申请微信开发测试号及花生壳内网映射
- js 小程序 计算器
- Android 自定义本地图片加载库,仿微信相册
- 解决微信安卓SDK获取用户昵称时中文乱码的问题
- 微信订阅号
- 微信企业红包开发签名一样一直提示签名错误的解决办法
- nrf51822 --- 微信移植 (官方例子移植到SDK10.0)
- 微信网页动画---swiper.animate.css
- 模拟UA实现访问只能在微信上打开的网页