Android自定义控件仿QQ编辑和选取圆形头像

这篇文章主要为大家详细介绍了Android自定义控件编辑和选取圆形头像,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

android大家都有很多需要用户上传头像的需求,有的是选方形,有的是圆角矩形,有的是圆形。
首先我们要做一个处理图片的自定义控件,把传入的图片,经过用户选择区域,处理成一定的形状。

有的app是通过在图片上画一个矩形区域表示选中的内容,有的则是通过双指放大缩小,拖动图片来选取图片。圆形头像,还是改变图片比较好

圆形区域可调节大小。

这个自定义View的图像部分分为三个,背景图片,半透明蒙层,和亮色区域……还是直接贴代码得了

 package com.example.jjj.widget; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; public class RoundEditImageView extends View { private Bitmap bitmap; RectF clipBounds, dst, src; Paint clearPaint; // 控件宽高 private int w, h; // 选区半径 private float radius = 150f; // 圆形选区的边界 private RectF circleBounds; // 最大放大倍数 private float max_scale = 2.0f; // 双指的距离 private float distance; private float x0, y0; private boolean doublePoint; public RoundEditImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } public RoundEditImageView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public RoundEditImageView(Context context) { super(context); init(); } private void init() { clearPaint = new Paint(Paint.ANTI_ALIAS_FLAG); clearPaint.setColor(Color.GRAY); clearPaint.setXfermode(new PorterDuffXfermode(Mode.CLEAR)); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (bitmap != null) { canvas.drawBitmap(bitmap, null, dst, null);//每次invalidate通过改变dst达到缩放平移的目的 } // 保存图层,以免清除时清除了bitmap int count = canvas.saveLayer(clipBounds, null, Canvas.ALL_SAVE_FLAG); canvas.drawColor(0x80000000); canvas.drawCircle(w / 2, h / 2, radius, clearPaint);// 清除半透明黑色,留下一个透明圆 canvas.restoreToCount(count); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); this.w = w; this.h = h; // 记录view所占的矩形 clipBounds = new RectF(0, 0, w, h); float l, r, t, b; if (bitmap != null) { // 判断长宽比,当长宽比太长会太宽是,以fitCenter的方式初始化图片 if (w / (float) h > bitmap.getWidth() / (float) bitmap.getHeight()) { // 图片太高 float w_ = h * bitmap.getWidth() / (float) bitmap.getHeight(); l = w / 2f - w_ / 2f; r = w / 2f + w_ / 2f; t = 0; b = h; } else { // 图片太长,或跟view一样长 float h_ = w * bitmap.getHeight() / (float) bitmap.getWidth(); l = 0; r = w; t = h / 2f - h_ / 2f; b = h / 2f + h_ / 2f; } dst = new RectF(l, t, r, b);// 这个矩形用来变换 src = new RectF(l, t, r, b);// 这个矩形仅为保存第一次的状态 max_scale = Math.max(max_scale, bitmap.getWidth() / src.width()); } circleBounds = new RectF(w / 2 - radius, h / 2 - radius, w / 2 + radius, h / 2 + radius); } public void setImageBitmap(Bitmap bitmap) { this.bitmap = bitmap; invalidate(); } @Override public boolean dispatchTouchEvent(MotionEvent e) { if (e.getPointerCount() > 2) {// 不接受多于两指的事件 return false; } else if (e.getPointerCount() == 2) { doublePoint = true;// 标志位,记录两指事件处理后,抬起一只手也不处理拖动 handleDoubleMove(e); } else { // 处理单指的拖动 switch (e.getAction()) { case MotionEvent.ACTION_DOWN: x0 = e.getX(); y0 = e.getY(); break; case MotionEvent.ACTION_MOVE: if (doublePoint) { break; } float x = e.getX(); float y = e.getY(); float w = dst.width(); float h = dst.height(); // 不允许拖过圆形区域,不能使圆形区域内空白 dst.left += x - x0; if (dst.left > circleBounds.left) { dst.left = circleBounds.left; } else if (dst.left  circleBounds.top) { dst.top = circleBounds.top; } else if (dst.top  src.width() * max_scale) { // 无法缩小到比选区还小,或到达最大倍数 return; } // 把dst区域放大scale倍 dst.left = (dst.left - pX) * scale + pX; dst.right = (dst.right - pX) * scale + pX; dst.top = (dst.top - pY) * scale + pY; dst.bottom = (dst.bottom - pY) * scale + pY; // 缩放同样不允许使圆形区域空白 if (dst.left > circleBounds.left) { dst.left = circleBounds.left; dst.right = dst.left + w * scale; } else if (dst.right  circleBounds.top) { dst.top = circleBounds.top; dst.bottom = dst.top + h * scale; } else if (dst.bottom 

Activity中用法

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_select_header); RoundEditImageView imageView = (RoundEditImageView) findViewById(R.id.roundEditImageView1); bitmap = BitmapFactory.decodeFile(imagePath); imageView.setImageBitmap(bitmap); } @Override public void onClick(View v) { //生成一个300*300的当前亮圆形中的图片 Bitmap result = imageView.extractBitmap(300); //压缩成png FileOutputStream out = new FileOutputStream(new File(filePath)); result.compress(Bitmap.CompressFormat.PNG, 100, out); //上传与显示 ... } 

需求是模仿QQ的,本人不太会讲解,做着玩玩。

以上就是Android自定义控件仿QQ编辑和选取圆形头像的详细内容,更多请关注0133技术站其它相关文章!

赞(0) 打赏
未经允许不得转载:0133技术站首页 » 移动