我是靠谱客的博主 默默小虾米,这篇文章主要介绍基于eclipse的android项目实战—博学谷(二十一)安卓更换头像功能(实测Android9及以下版本可用),现在分享给大家,希望可以做个参考。

本项目是用eclipse软件编写,经过我的亲自实践,其真实有效,希望能给您有所帮助????????

项目版本:android5.1.1
ADT版本:23.0.6
SDK版本:24.4.1
运行模拟器:夜神模拟器

若有不足之处或不对的地方,欢迎大佬们指点


本项目源码下载链接:
https://download.csdn.net/download/hyh17808770899/20285938
在下载源码之前请先下载apk安装查看运行效果:https://yuyunyaohui.lanzoui.com/ipirYrf1byd

请添加图片描述


开头必读:本文介绍Android更换头像功能,本项目源码实测安卓9.0及以下可用,Android 10由于文件权限的关系,显示手机储存卡里的图片不能直接使用图片路径,需要使用图片uri加载,但如果在AndroidManifest.xml里将android:targetSdkVersion改成29以下,安卓10也是可以用滴。targetSdkVersion低于29时,在android 10也是可以直接使用图片路径读取bitmap的。

从此文开始,后面的内容将不再准确将所有代码给出,但主要功能实现代码必有,如果有必要,请下载源码查看。

通过点击个人资料界面的头像来更换头像,更换头像时手机会提示打开摄像机权限。点击头像后会出现一个弹窗,可选择更换头像的方式(拍照和相册选择),拍照完成或选择好图片后,进入图片裁剪界面,将图片裁剪,然后点击完成,图片就保存到了SD卡,命名"head.jpg",再用一个语句将头像的显示控件更改为显示该SD卡保存的图片,如此即可更换头像。
“我”的界面的头像,加一个判断语句,如果SD卡不存在该图片,就将默认的图片显示成头像;如果存在,头像就会显示这个 "head.jpg"图片。
将App卸载重新安装,这个头像都不会变,除非将SD卡中的"head.jpg"图片删除。修改头像即是将该图片覆盖。(有需要的话自己优化)


1、圆形头像

先将头像弄成圆形头像,这样看起来美观一些,相关方法在基于eclipse的android项目实战—博学谷(新功能一)圆形头像中

既然是头像修改,那就要实现点击头像弹出选择框,而“我”的界面的头像,无论是登录或者未登录,点击的时候都是有功能需要实现的,所以在个人资料界面实现修改头像功能。

2、个人资料界面逻辑代码修改

个人资料界面添加更换头像的点击事件和头像显示代码
china.ynyx.heyunhui.activity包中的UserInfoActivity.java文件中添加代码

(1)定义私有变量

复制代码
1
2
3
4
5
6
7
private ImageView iv_head_icon; private static String path = "/sdcard/DemoHead/";//sd路径 private Bitmap head;//头像Bitmap private Context context = this; Bitmap bt = BitmapFactory.decodeFile(path + "head.jpg");//从Sd中找头像,转换成Bitmap

(2)头像显示方法实现:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private void imagehead() { // TODO Auto-generated method stub if(bt!=null){ iv_head_icon.setImageBitmap(bt); }else{ /** * 如果SD里面没有则需要从服务器取头像,取回来的头像再保存在SD中 */ iv_head_icon.setImageResource(R.drawable.default_icon); } rl_head.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { ActionSheetDialog(); } }); }

(3)在onCreate(Bundle savedInstanceState)方法中添加头像显示方法:

复制代码
1
2
3
4
/*完成头像修改功能的代码---创新功能一*/ imagehead(); /*完成头像修改功能的代码---创新功能一*/

(4)在init()方法中初始化头像图片控件

复制代码
1
2
iv_head_icon =(ImageView) findViewById(R.id.iv_head_icon);

(5)拍照和相册选择的点击事件:

onActivityResult(int requestCode, int resultCode, Intent data)方法中添加代码:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//相机拍照后的返回结果 case 3: if (resultCode == RESULT_OK) { File temp = new File(Environment.getExternalStorageDirectory() + "/head.jpg"); cropPhoto(Uri.fromFile(temp));//裁剪图片 } break; //从相册里面取相片的返回结果 case 4: if (resultCode == RESULT_OK) { cropPhoto(data.getData());//裁剪图片 } break; //调用系统裁剪图片后 case 5: if (data != null) { Bundle extras = data.getExtras(); head = extras.getParcelable("data"); if (head != null) { /** * 上传服务器代码 */ setPicToView(head);//保存在SD卡中 iv_head_icon.setImageBitmap(head);//用ImageView显示出来 } }
复制代码
1
2
super.onActivityResult(requestCode, resultCode, data);

(6)拍照、相册、系统裁剪的具体实现代码:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
private void ActionSheetDialog() { final String[] stringItems = {"拍照", "从相册中选择"}; final ActionSheetDialog dialog = new ActionSheetDialog(context, stringItems, null); dialog.title("请选择头像更换方式")// .titleTextSize_SP(14.5f)// .show(); dialog.setOnOperItemClickL(new OnOperItemClickL() { @Override public void onOperItemClick(AdapterView<?> parent, View view, int position, long id) { if (position == 0) {//调用相机拍照 T.showShort(context, stringItems[position]); //6.0动态申请权限,摄像头权限,SD卡读取权限 if (ContextCompat.checkSelfPermission(UserInfoActivity.this, Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(UserInfoActivity.this,Manifest.permission.WRITE_EXTERNAL_STORAGE)!=PackageManager.PERMISSION_GRANTED){ ActivityCompat.requestPermissions(UserInfoActivity.this, new String[] {Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE},MY_ADD_CASE_CALL_PHONE ); }else { //最好用try/catch包裹一下,防止因为用户未给应用程序开启相机权限,而使程序崩溃 try{ Intent intent1 = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);//开启相机应用程序获取并返回图片(capture:俘获) if (Build.VERSION.SDK_INT < 24) { intent1.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "head.jpg")));//指明存储图片或视频的地址URI startActivityForResult(intent1, 3);//采用ForResult打开 } else { Uri imageUri = FileProvider.getUriForFile(UserInfoActivity.this, "com.camera_photos.fileprovider", new File(Environment.getExternalStorageDirectory(), "head.jpg")); intent1.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent1.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); startActivityForResult(intent1, 3);//采用ForResult打开 } }catch (Exception e){ Toast.makeText(UserInfoActivity.this, "相机无法启动,请先开启相机权限", Toast.LENGTH_LONG).show(); } } dialog.dismiss(); }else if (position == 1) {//从相册里面取照片 //6.0动态申请权限,摄像头权限,SD卡写入取权限 if (ContextCompat.checkSelfPermission(UserInfoActivity.this, Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(UserInfoActivity.this,Manifest.permission.WRITE_EXTERNAL_STORAGE)!=PackageManager.PERMISSION_GRANTED){ ActivityCompat.requestPermissions(UserInfoActivity.this, new String[] {Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE},MY_ADD_CASE_CALL_PHONE ); }else { T.showShort(context, stringItems[position]); Intent intent2 = new Intent(Intent.ACTION_PICK, null);//返回被选中项的URI intent2.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");//得到所有图片的URI startActivityForResult(intent2, 4); } dialog.dismiss(); } } }); } /** * 调用系统的裁剪 * * @param uri */ public void cropPhoto(Uri uri) { Intent intent = new Intent("com.android.camera.action.CROP"); //找到指定URI对应的资源图片 intent.setDataAndType(uri, "image/*"); intent.putExtra("crop", "true"); // aspectX aspectY 是裁剪框宽高的比例 intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); // outputX outputY 是裁剪图片宽高 intent.putExtra("outputX", 150);// 输出图片大小 intent.putExtra("outputY", 150); intent.putExtra("return-data", true); //进入系统裁剪图片的界面 startActivityForResult(intent, 5); } private void setPicToView(Bitmap mBitmap) { String sdStatus = Environment.getExternalStorageState(); if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) { // 检测sd卡是否可用 return; } FileOutputStream b = null; File file = new File(path); file.mkdirs();// 创建以此File对象为名(path)的文件夹 String fileName = path + "head.jpg";//图片名字 try { b = new FileOutputStream(fileName); mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, b);// 把数据写入文件(compress:压缩) } catch (FileNotFoundException e) { e.printStackTrace(); } finally { try { //关闭流 b.flush(); b.close(); } catch (IOException e) { e.printStackTrace(); } } }

3、“我”的界面逻辑代码修改

头像在个人资料界面修改后应该将其他地方的头像也一并修改,所以需要在“我”的界面添加上头像图片路径,如果有则显示该路径图片,如果没有即显示默认头像。

china.ynyx.heyunhui.view包中的MyInfoView.java文件中

复制代码
1
2
3
4
public ImageView iv_head_icon = null; private LinearLayout ll_head; private static String path = "/sdcard/DemoHead/";//sd路径(头像路径)

设置“我”的界面头像显示,initView()方法中添加:

复制代码
1
2
3
ll_head = (LinearLayout) mCurrentView.findViewById(R.id.ll_head); iv_head_icon = (ImageView)mCurrentView.findViewById(R.id.iv_head_icon);

将下面的代码放到setLoginParams(boolean isLogin)方法的if (isLogin) {里面

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
Bitmap bt = BitmapFactory.decodeFile(path + "head.jpg");//从Sd中找头像,转换成Bitmap if(bt!=null){ //显示修改后的头像 iv_head_icon.setImageBitmap(bt); }else{ /** * 如果SD里面没有则需要从服务器取头像,取回来的头像再保存在SD中 */ //没有则显示默认头像 iv_head_icon.setImageResource(R.drawable.default_icon); }

这样在进入“我”的界面,就会显示修改后的头像

注:未登录显示默认头像方法:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public void setLoginParams(boolean isLogin) { if (isLogin) { tv_user_name.setText(AnalysisUtils.readLoginUserName(mContext)); /*完成头像修改功能的代码---创新功能一*/ Bitmap bt = BitmapFactory.decodeFile(path + "head.jpg");//从Sd中找头像,转换成Bitmap if(bt!=null){ iv_head_icon.setImageBitmap(bt); }else{ /** * 如果SD里面没有则需要从服务器取头像,取回来的头像再保存在SD中 */ iv_head_icon.setImageResource(R.drawable.default_icon); } /*完成头像修改功能的代码---创新功能一*/ } else { tv_user_name.setText("点击登录"); iv_head_icon.setImageResource(R.drawable.default_icon); } }

4、完善

由于在个人资料界面修改头像后返回“我”的界面,返回按钮没有添加将图片数据传回的代码,所以需要刷新页面才能改变“我”的界面的头像(点击其他页面再点击“我”)
请添加图片描述

所以我直接将个人资料界面的返回按钮逻辑实现修改了,使其被点击后直接返回主页,然后再点击“我”,实现“我”的界面头像修改。
china.ynyx.heyunhui.activity包中的UserInfoActivity.java文件中的返回按钮代码中添加:

复制代码
1
2
3
Intent intent=new Intent(UserInfoActivity.this,MainActivity.class); startActivity(intent);

实现效果如下:
请添加图片描述

5、修改AndroidManifest.xml文件

添加:

复制代码
1
2
3
4
5
6
7
<uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera"/> <uses-feature android:name="android.hardware.camera.autofocus"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

<application>中添加安卓7.0以上相机权限:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
<!-- 完成头像修改功能的代码 安卓7.0以上摄像机权限调用 --> <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.camera_photos.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> <!-- 完成头像修改功能的代码 安卓7.0以上摄像机权限调用 -->

6、弹窗实现

在src目录下新建china.ynyx.heyunhui.dialog包,再在该包中新建更换头像时弹窗需要用到的java文件:
在这里插入图片描述
由于代码太多,这里就不一一展示了,需者自取:
https://yuyunyaohui.lanzoui.com/ilhz6qpnyve

添加库文件:更换头像弹窗所需要的库文件
https://yuyunyaohui.lanzoui.com/iKe6Xqpnole
在这里插入图片描述

5、弹窗样式

res目录下新建anim文件夹,在该文件夹中新建两个xml文件
dialog_enter.xml具体代码如下:

复制代码
1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" > <!-- %p指相对于父容器 --> <translate android:duration="500" android:fromYDelta="-100%p" /> </set>

dialog_exit.xml具体代码如下:

复制代码
1
2
3
4
5
6
7
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" > <translate android:duration="500" android:toYDelta="-100%p" /> </set>

res目录下的layout文件夹中新建ac_dialog_home.xml文件

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="utf-8"?> <ExpandableListView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/elv" android:background="#ffffff" android:layout_width="fill_parent" android:layout_height="fill_parent" android:cacheColorHint="#00000000" android:divider="@null" android:fadingEdge="none" android:groupIndicator="@null" android:listSelector="#00000000" android:scrollbars="none" />

res目录下的values文件夹中的styles.xml中20行添加代码:

复制代码
1
2
3
4
5
6
7
<style name="myDialogAnim" parent="android:Animation"> <!-- 进入时的动画 --> <item name="@android:windowEnterAnimation">@anim/dialog_enter</item> <!-- 退出时的动画 --> <item name="@android:windowExitAnimation">@anim/dialog_exit</item> </style>

基于eclipse的android项目实战—博学谷(零)创建和运行Android项目
基于eclipse的android项目实战—博学谷(一)欢迎界面
基于eclipse的android项目实战—博学谷(二)注册界面
基于eclipse的android项目实战—博学谷(三)登录界面
基于eclipse的android项目实战—博学谷(四)底部导航栏
基于eclipse的android项目实战—博学谷(五)“我”的模块
基于eclipse的android项目实战—博学谷(六)设置界面
基于eclipse的android项目实战—博学谷(七)修改密码
基于eclipse的android项目实战—博学谷(八)设置密保和找回密码
基于eclipse的android项目实战—博学谷(九)个人资料界面
基于eclipse的android项目实战—博学谷(十)个人资料修改
基于eclipse的android项目实战—博学谷(十一)习题界面
基于eclipse的android项目实战—博学谷(十二)习题详情界面
基于eclipse的android项目实战—博学谷(十三)水平滑动广告栏界面
基于eclipse的android项目实战—博学谷(十四)课程界面
基于eclipse的android项目实战—博学谷(十五)课程详情界面
基于eclipse的android项目实战—博学谷(十六)视频播放界面
基于eclipse的android项目实战—博学谷(十七)播放记录界面
基于eclipse的android项目实战—博学谷(十八)播放不同视频(网络视频)
基于eclipse的android项目实战—博学谷(十九)播放不同视频(本地视频)
基于eclipse的android项目实战—博学谷(二十)HCIA-Kunpeng

最后

以上就是默默小虾米最近收集整理的关于基于eclipse的android项目实战—博学谷(二十一)安卓更换头像功能(实测Android9及以下版本可用)的全部内容,更多相关基于eclipse内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(70)

评论列表共有 0 条评论

立即
投稿
返回
顶部