开发中经常会有这样的要求:用户可以点击头像更换成自己想要的头像。
思路是这样的:点击头像可以选择从相册中选择或者通过拍照完成设置。
这里也就需要两步来实现:一是从相册,而是拍照。
这里用到了一个开源的工具类:RoundImageView
,该类实现了绘制圆形图片。以及用到了开源的文件创建类:FileUitlity
,在文章得最后我将把两个类中的代码分享下。
为了实现主要功能,布局就一个RoundImageView
组件,该组件需要导入上面提到的RoundImageView
。
<com.inext.test.datatest.util.RoundImageView
android:id="@+id/roundImageView"
android:src="@mipmap/ic_launcher"
android:layout_width="60dp"
android:layout_height="60dp" />
Activity.class
中的核心代码:
//获取组件
RoundImageView roundImageView = (RoundImageView)findViewById(R.id.roundImageView);
//绑定监听
roundImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//PopupWindow----START-----这里开始到下面标记的地方是实现点击头像弹出PopupWindow,实现用户从PopupWindow中选择更换头像的方式
backgroundAlpha(0.3f);
View view = LayoutInflater.from(getBaseContext()).inflate(R.layout.popu_window,null);
final PopupWindow popupWindow = new PopupWindow(view, ActionBar.LayoutParams.WRAP_CONTENT,ActionBar.LayoutParams.WRAP_CONTENT, true);
popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
popupWindow.setOutsideTouchable(true);
popupWindow.setFocusable(true);
//获取屏幕宽度
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
popupWindow.setWidth(dm.widthPixels);
popupWindow.setAnimationStyle(R.style.popuwindow);
//显示位置
popupWindow.showAtLocation(view, Gravity.BOTTOM, 0, 0);
popupWindow.setOnDismissListener(new poponDismissListener());
//PopupWindow-----END
//PopupWindow中对应的选择按钮
Button button = (Button)view.findViewById(R.id.take_photo);//通过拍照的方式
Button button1 = (Button)view.findViewById(R.id.all_photo);//通过相册的方式
Button button2 = (Button)view.findViewById(R.id.out);//取消按钮
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
backgroundAlpha(1f);
popupWindow.dismiss();
}
});
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
backgroundAlpha(1f);
popupWindow.dismiss();
//调用手机相册的方法,该方法在下面有具体实现
allPhoto();
}
});
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
backgroundAlpha(1f);
popupWindow.dismiss();
//调用手机照相机的方法,通过Intent调用系统相机完成拍照,并调用系统裁剪器裁剪照片
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//创建文件路径,头像保存的路径
File file =FileUitlity.getInstance(getApplicationContext()).makeDir("head_image");
//定义图片路径和名称
path = file.getParent() + File.separatorChar + System.currentTimeMillis() + ".jpg";
//保存图片到Intent中,并通过Intent将照片传给系统裁剪器
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(path)));
//图片质量
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
//启动有返回的Intent,即返回裁剪好的图片到RoundImageView组件中显示
startActivityForResult(intent, REQUEST_CODE);
}
});
}
});
//该方法实现通过何种方式跟换图片
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//如果返回码不为-1,则表示不成功
if (resultCode != Activity.RESULT_OK){
return;
}
if (requestCode == ALL_PHOTO){
//调用相册
Cursor cursor = this.getContentResolver().query(data.getData(),
new String[]{MediaStore.Images.Media.DATA},null,null,null);
//游标移到第一位,即从第一位开始读取
cursor.moveToFirst();
String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
cursor.close();
//调用系统裁剪
startPhoneZoom(Uri.fromFile(new File(path)));
}else if (requestCode == REQUEST_CODE){
//相机返回结果,调用系统裁剪
startPhoneZoom(Uri.fromFile(new File(path)));
}else if(requestCode == RESULT_PHOTO) {
//设置裁剪返回的位图
Bundle bundle = data.getExtras();
if (bundle!=null){
Bitmap bitmap = bundle.getParcelable("data");
//将裁剪后得到的位图在组件中显示
roundImageView.setImageBitmap(bitmap);
}
}
}
//调用系统裁剪的方法
private void startPhoneZoom(Uri uri){
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
//是否可裁剪
intent.putExtra("corp", "true");
//裁剪器高宽比
intent.putExtra("aspectY",1);
intent.putExtra("aspectX",1);
//设置裁剪框高宽
intent.putExtra("outputX",150);
intent.putExtra("outputY", 150);
//返回数据
intent.putExtra("return-data",true);
startActivityForResult(intent,RESULT_PHOTO);
}
//调用手机相册
private void allPhoto(){
Intent intent = new Intent(Intent.ACTION_PICK,MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent,ALL_PHOTO);
}
/** * 添加PopupWindow关闭的事件,主要是为了将背景透明度改回来 * */
class poponDismissListener implements PopupWindow.OnDismissListener{
@Override
public void onDismiss() {
// TODO Auto-generated method stub
//Log.v("List_noteTypeActivity:", "我是关闭事件");
backgroundAlpha(1f);
}
}
/** * 设置添加屏幕的背景透明度 * @param bgAlpha */
public void backgroundAlpha(float bgAlpha)
{
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.alpha = bgAlpha; //0.0-1.0
getWindow().setAttributes(lp);
}
权限设置:
<!-- 读取 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- 写入权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 创建与删除权限 -->
<uses-permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS" />
两个开源的工具类,这两个类可直接复制使用:
FileUitlity.java
:
import android.content.Context;
import android.os.Environment;
import java.io.File;
public class FileUitlity {
private static String ROOT_CACHE;
public static String ROOT_DIR="yt_xyt";
private static FileUitlity instance = null;
private FileUitlity() {
}
public static FileUitlity getInstance(Context context) {
if (instance == null) {
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
ROOT_CACHE = (Environment.getExternalStorageDirectory() + "/"
+ ROOT_DIR + "/");
} else {
ROOT_CACHE = (context.getFilesDir().getAbsolutePath() + "/"+ROOT_DIR+"/");
}
File dir = new File(ROOT_CACHE);
if (!dir.exists()) {
dir.mkdirs();
}
instance = new FileUitlity();
}
return instance;
}
public File makeDir(String dir) {
File fileDir = new File(ROOT_CACHE + dir);
if (fileDir.exists()) {
return fileDir;
} else {
fileDir.mkdirs();
return fileDir;
}
}
}
RoundImageView.java
:
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;
public class RoundImageView extends ImageView {
public RoundImageView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public RoundImageView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public RoundImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
@Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
Bitmap b = null;
if(drawable instanceof BitmapDrawable){
b = ((BitmapDrawable) drawable).getBitmap();
}else if(drawable instanceof Drawable){
b = Bitmap.createBitmap(
getWidth(),
getHeight(),
drawable.getOpacity() != PixelFormat.OPAQUE ? Config.ARGB_8888
: Config.RGB_565);
Canvas canvas1 = new Canvas(b);
// canvas.setBitmap(bitmap);
drawable.setBounds(0, 0, getWidth(),
getHeight());
drawable.draw(canvas1);
}
if (null == b) {
return;
}
Bitmap bitmap = b.copy(Config.ARGB_8888, true);
int w = getWidth(), h = getHeight();
Bitmap roundBitmap = getCroppedBitmap(bitmap, w);
canvas.drawBitmap(roundBitmap, 0, 0, null);
}
public static Bitmap getCroppedBitmap(Bitmap bmp, int radius) {
Bitmap sbmp;
if (bmp.getWidth() != radius || bmp.getHeight() != radius)
sbmp = Bitmap.createScaledBitmap(bmp, radius, radius, false);
else
sbmp = bmp;
Bitmap output = Bitmap.createBitmap(sbmp.getWidth(), sbmp.getHeight(),
Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xffa19774;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, sbmp.getWidth(), sbmp.getHeight());
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.parseColor("#BAB399"));
canvas.drawCircle(sbmp.getWidth() / 2 + 0.7f,
sbmp.getHeight() / 2 + 0.7f, sbmp.getWidth() / 2 + 0.1f, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(sbmp, rect, rect, paint);
return output;
}
}