600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > 自定义ImageView完成圆形头像自定义

自定义ImageView完成圆形头像自定义

时间:2019-10-14 04:01:25

相关推荐

自定义ImageView完成圆形头像自定义

前言

我们可以看到现在的好多app的头像都是圆形的,记得应该是一年之前吧,具体的时间也不记得了,那个时候更新飞信,那次改版挺大,头像是圆形的,感觉挺不错的。那么今天也来实现以下吧。

我们来分析一下,怎么去实现

第一步:我们应该知道显示的头像是一个imageview,那么我们就继承ImageView第二步:它有自己的自定义属性(外部有一个大小可以变的圆,颜色也可以变化)

接下来我们来实现吧

首先要来看看他有的自定义属性

attrs.xml:

<?xml version="1.0" encoding="utf-8"?><resources><declare-styleable name="CircleImageView"><attr name="outCircleColor" format="color"/><attr name="outCircleWidth" format="dimension"/></declare-styleable></resources>

来实现自定义的ImageView:

这里面也没有多少的代码,在这里用到的测量宽高,绘制圆,代码里面都有了注释。

package com.example.headimage;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.PorterDuff;import android.graphics.PorterDuffXfermode;import android.graphics.drawable.BitmapDrawable;import android.util.AttributeSet;import android.widget.ImageView;/*** Created by 若兰 on /2/13.* 一个懂得了编程乐趣的小白,希望自己* 能够在这个道路上走的很远,也希望自己学习到的* 知识可以帮助更多的人,分享就是学习的一种乐趣* QQ:1069584784* csdn:/wuyinlei*/public class CircleImageView extends ImageView {//外圆的宽度private int outCircleWidth;//外圆的颜色private int outCircleColor = Color.WHITE;//画笔private Paint paint;//view的宽度和高度private int viewWidth;private int viewHeigth;private Bitmap image;public CircleImageView(Context context) {this(context, null);}public CircleImageView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initAttrs(context, attrs, defStyleAttr);}/*** 初始化资源文件** @param context* @param attrs* @param defStyleAttr*/private void initAttrs(Context context, AttributeSet attrs, int defStyleAttr) {TypedArray array = null;if (attrs != null) {array = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView);int len = array.length();for (int i = 0; i < len; i++) {int attr = array.getIndex(i);switch (attr) {//获取到外圆的颜色case R.styleable.CircleImageView_outCircleColor:this.outCircleColor = array.getColor(attr, Color.WHITE);break;//获取到外圆的半径case R.styleable.CircleImageView_outCircleWidth:this.outCircleWidth = (int) array.getDimension(attr, 5);break;}}}paint = new Paint();paint.setColor(outCircleColor);//颜色paint.setAntiAlias(true);//设置抗锯齿array.recycle(); //回收}/*** view的测量* @param widthMeasureSpec* @param heightMeasureSpec*/@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int width = measureWith(widthMeasureSpec);int height = measureWith(heightMeasureSpec);viewWidth = width - outCircleWidth * 2;viewHeigth = height - outCircleWidth * 2;//调用该方法将测量后的宽和高设置进去,完成测量工作,setMeasuredDimension(width, height);}/*** 测量宽和高,这一块可以是一个模板代码(Android群英传)* @param widthMeasureSpec* @return*/private int measureWith(int widthMeasureSpec) {int result = 0;//从MeasureSpec对象中提取出来具体的测量模式和大小int mode = MeasureSpec.getMode(widthMeasureSpec);int size = MeasureSpec.getSize(widthMeasureSpec);if (mode == MeasureSpec.EXACTLY) {//测量的模式,精确result = size;} else {result = viewWidth;}return result;}/*** 绘制* @param canvas*/@Overrideprotected void onDraw(Canvas canvas) {//加载图片loadImage();if (image != null) {//拿到最小的值(这里我们要去到最小的)int min = Math.min(viewWidth, viewHeigth);int circleCenter = min / 2;image = Bitmap.createScaledBitmap(image, min, min, false);//画圆canvas.drawCircle(circleCenter + outCircleWidth, circleCenter + outCircleWidth, circleCenter + outCircleColor, paint);//画图像canvas.drawBitmap(createCircleBitmap(image, min), outCircleWidth, outCircleWidth, null);}}/*** 创建一个圆形的bitmap** @param image 传入的image* @param min* @return*/private Bitmap createCircleBitmap(Bitmap image, int min) {Bitmap bitmap = null;Paint paint = new Paint();paint.setAntiAlias(true);bitmap = Bitmap.createBitmap(min, min, Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(bitmap);//画一个和图片大小相等的画布canvas.drawCircle(min / 2, min / 2, min / 2, paint);paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));canvas.drawBitmap(image, 0, 0, paint);return bitmap;}/*** 加载Image*/private void loadImage() {BitmapDrawable bitmapDrawable = (BitmapDrawable) this.getDrawable();if (bitmapDrawable != null) {image = bitmapDrawable.getBitmap();}}/*** 对外提供的可以设置外圆的颜色的方法* @param outCircleColor*/public void setOutCircleColor(int outCircleColor) {if (null != paint) {paint.setColor(outCircleColor);}this.invalidate();}/*** 对外提供给的设置外圆的宽度大小的方法* @param outCircleWidth*/public void setOutCircleWidth(int outCircleWidth) {this.outCircleWidth = outCircleWidth;this.invalidate();}}

我们来看下效果图:

好了,这里我在添加一些功能吧,就是可以选择相册图片,可以调用系统相机,在使用图片的时候可以裁剪。我们点击的时候用到了PopupWindow。这些代码都很简单(我以为还有点知识点,结果被鄙视了。。。)

package com.example.headimage;import android.content.Intent;import android.graphics.Bitmap;import android.graphics.drawable.BitmapDrawable;import .Uri;import android.os.Environment;import android.provider.MediaStore;import android.provider.Settings;import android.support.v7.app.AlertDialog;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.DisplayMetrics;import android.view.Gravity;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.WindowManager;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.PopupWindow;import android.widget.RelativeLayout;import android.widget.Toast;import java.io.File;import java.text.SimpleDateFormat;import java.util.Date;public class MainActivity extends AppCompatActivity implements View.OnClickListener {private CircleImageView ivHead;private RelativeLayout layout_choose;private RelativeLayout layout_photo;private RelativeLayout layout_close;private LinearLayout layout_all;protected int mScreenWidth;/*** 定义三种状态*/private static final int REQUESTCODE_PIC = 1;//相册private static final int REQUESTCODE_CAM = 2;//相机private static final int REQUESTCODE_CUT = 3;//图片裁剪private Bitmap mBitmap;private File mFile;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ivHead = (CircleImageView) findViewById(R.id.iv_head);layout_all = (LinearLayout) findViewById(R.id.layout_all);ivHead.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()){case R.id.iv_head:showMyDialog();break;}}PopupWindow avatorPop;private void showMyDialog() {View view = LayoutInflater.from(this).inflate(R.layout.pop_show_dialog,null);layout_choose = (RelativeLayout) view.findViewById(R.id.layout_choose);layout_photo = (RelativeLayout) view.findViewById(R.id.layout_photo);layout_close = (RelativeLayout) view.findViewById(R.id.layout_close);layout_choose.setBackgroundColor(getResources().getColor(R.color.base_color_text_white));layout_photo.setBackgroundDrawable(getResources().getDrawable(R.drawable.pop_bg_press));layout_close.setBackgroundColor(getResources().getColor(R.color.base_color_text_white));layout_photo.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View arg0) {// TODO Auto-generated method stublayout_choose.setBackgroundColor(getResources().getColor(R.color.base_color_text_white));layout_photo.setBackgroundDrawable(getResources().getDrawable(R.drawable.pop_bg_press));layout_close.setBackgroundColor(getResources().getColor(R.color.base_color_text_white));openCamera();// Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);//intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);//startActivityForResult(intent,);}});layout_choose.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View arg0) {// TODO Auto-generated method stublayout_photo.setBackgroundColor(getResources().getColor(R.color.base_color_text_white));layout_choose.setBackgroundDrawable(getResources().getDrawable(R.drawable.pop_bg_press));layout_close.setBackgroundColor(getResources().getColor(R.color.base_color_text_white));openPic();}});layout_close.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {layout_photo.setBackgroundColor(getResources().getColor(R.color.base_color_text_white));layout_close.setBackgroundDrawable(getResources().getDrawable(R.drawable.pop_bg_press));layout_choose.setBackgroundColor(getResources().getColor(R.color.base_color_text_white));avatorPop.dismiss();}});DisplayMetrics metric = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(metric);mScreenWidth = metric.widthPixels;avatorPop = new PopupWindow(view, mScreenWidth, 200);avatorPop.setTouchInterceptor(new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {avatorPop.dismiss();return true;}return false;}});//设置宽度avatorPop.setWidth(WindowManager.LayoutParams.MATCH_PARENT);//设置高度avatorPop.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);//可以点击avatorPop.setTouchable(true);avatorPop.setFocusable(true);avatorPop.setOutsideTouchable(true);avatorPop.setBackgroundDrawable(new BitmapDrawable());// 动画效果 从底部弹起avatorPop.setAnimationStyle(R.style.Animations_GrowFromBottom);avatorPop.showAtLocation(layout_all, Gravity.BOTTOM, 0, 0);}/*** 打开相册*/private void openPic() {Intent picIntent = new Intent(Intent.ACTION_PICK,null);picIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*");startActivityForResult(picIntent,REQUESTCODE_PIC);}/*** 调用相机*/private void openCamera() {String state = Environment.getExternalStorageState();if (state.equals(Environment.MEDIA_MOUNTED)){Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);if (!file.exists()){file.mkdirs();}mFile = new File(file, System.currentTimeMillis() + ".jpg");intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mFile));intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY,1);startActivityForResult(intent,REQUESTCODE_CAM);} else {Toast.makeText(this, "请确认已经插入SD卡", Toast.LENGTH_SHORT).show();}}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {if (resultCode == RESULT_OK) {switch (requestCode) {case REQUESTCODE_CAM:startPhotoZoom(Uri.fromFile(mFile));break;case REQUESTCODE_PIC:if (data == null || data.getData() == null){return;}startPhotoZoom(data.getData());break;case REQUESTCODE_CUT:if (data!= null){setPicToView(data);}break;}}super.onActivityResult(requestCode, resultCode, data);}private void setPicToView(Intent data) {Bundle bundle = data.getExtras();if (bundle != null){//这里也可以做文件上传mBitmap = bundle.getParcelable("data");ivHead.setImageBitmap(mBitmap);}}/*** 打开系统图片裁剪功能* @param uri*/private void startPhotoZoom(Uri uri) {Intent intent = new Intent("com.android.camera.action.CROP");intent.setDataAndType(uri,"image/*");intent.putExtra("crop",true);intent.putExtra("aspectX",1);intent.putExtra("aspectY",1);intent.putExtra("outputX",300);intent.putExtra("outputY",300);intent.putExtra("scale",true); //黑边intent.putExtra("scaleUpIfNeeded",true); //黑边intent.putExtra("return-data",true);intent.putExtra("noFaceDetection",true);startActivityForResult(intent,REQUESTCODE_CUT);}}

我们来看下效果

裁剪功能:

裁剪后确定:

这里我们对于动画,还有资源属性用到了一些style样式,还有一些动画资源文件,这里我就不上传了,直接给git地址,方便下载,查看更多资源

/wuyinlei/CircleImgae

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。