国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android自定義控件仿QQ編輯和選取圓形頭像

2019-12-12 05:07:59
字體:
來源:轉載
供稿:網友

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.right - w) {     dst.left = circleBounds.right - w;    }    dst.right = dst.left + w;    // 不允許拖過圓形區域,不能使圓形區域內空白    dst.top += y - y0;    if (dst.top > circleBounds.top) {     dst.top = circleBounds.top;    } else if (dst.top < circleBounds.bottom - h) {     dst.top = circleBounds.bottom - h;    }    dst.bottom = dst.top + h;    x0 = x;    y0 = y;    invalidate();    break;   case MotionEvent.ACTION_UP:    doublePoint = false;// 恢復標志位    break;   }  }  return true; } // 處理雙指事件 private void handleDoubleMove(MotionEvent e) {  switch (e.getAction() & MotionEvent.ACTION_MASK) {  case MotionEvent.ACTION_POINTER_DOWN:   distance = sqrt(e);   Log.d("px", "down:distance=" + distance);   break;  case MotionEvent.ACTION_MOVE:   scale(e);   break;  case MotionEvent.ACTION_UP:   break;  default:   break;  } } private void scale(MotionEvent e) {  float dis = sqrt(e);  // 以雙指中心作為圖片縮放的支點  float pX = e.getX(0) / 2f + e.getX(1) / 2f;  float pY = e.getY(0) / 2f + e.getY(1) / 2f;  float scale = dis / distance;  Log.d("px", "move:distance=" + dis + ",scale to" + scale);  float w = dst.width();  float h = dst.height();  if (w * scale < radius * 2 || h * scale < radius * 2 || w * scale > 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.right) {   dst.right = circleBounds.right;   dst.left = dst.right - w * scale;  }  if (dst.top > circleBounds.top) {   dst.top = circleBounds.top;   dst.bottom = dst.top + h * scale;  } else if (dst.bottom < circleBounds.bottom) {   dst.bottom = circleBounds.bottom;   dst.top = dst.bottom - h * scale;  }  invalidate();  distance = dis; } private float sqrt(MotionEvent e) {  return (float) Math.sqrt((e.getX(0) - e.getX(1)) * (e.getX(0) - e.getX(1)) + (e.getY(0) - e.getY(1)) * (e.getY(0) - e.getY(1))); } // 生成目前選區指定大小的圓形bitmap public Bitmap extractBitmap(int width) {  Bitmap outBitmap = Bitmap.createBitmap(width, width, Bitmap.Config.ARGB_8888);  Canvas canvas = new Canvas(outBitmap);  Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);  p.setColor(Color.GRAY);  canvas.drawCircle(width / 2, width / 2, width / 2, p);  float scale = dst.width() / bitmap.getWidth();  int w = (int) (circleBounds.width() / scale);  int l = (int) ((circleBounds.left - dst.left) / scale);  int r = l + w;  int t = (int) ((circleBounds.top - dst.top) / scale);  int b = t + w;  Rect resRect = new Rect(l, t, r, b);  Paint paint = new Paint();  paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));  canvas.drawBitmap(bitmap, resRect, canvas.getClipBounds(), paint);  return outBitmap; }}

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的,本人不太會講解,做著玩玩。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 灵宝市| 南京市| 赤峰市| 通山县| 黔江区| 望江县| 平泉县| 宁城县| 商城县| 马关县| 融水| 法库县| 稷山县| 柘城县| 新民市| 白水县| 当雄县| 中阳县| 大竹县| 淮北市| 吴忠市| 东方市| 鄂尔多斯市| 水富县| 聂拉木县| 长宁区| 宁乡县| 新巴尔虎右旗| 革吉县| 黔南| 长治市| 佳木斯市| 磐石市| 巴青县| 灵川县| 康马县| 水城县| 龙井市| 慈溪市| 磐安县| 鹿泉市|